goblin.properties.Property.setgetdb_name()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 2
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
"""Classes to handle properties and data type definitions"""
2
3
import logging
4
from typing import Any
5
6
from gremlin_python.statics import long # type: ignore
7
8
from goblin import abc, exception
9
10
logger = logging.getLogger(__name__)
11
12
13
def noop_factory(x, y):
14
    return None
15
16
17
class PropertyDescriptor:
18
    """
19
    Descriptor that validates user property input and gets/sets properties
20
    as instance attributes. Not instantiated by user.
21
    """
22
23
    def __init__(self, name, prop):
24
        self._prop_name = name
25
        self._name = '_' + name
26
        self._data_type = prop.data_type
27
        self._default = prop.default
28
29
    def __get__(self, obj, objtype):
30
        if obj is None:
31
            return getattr(objtype.__mapping__, self._prop_name)
32
        return getattr(obj, self._name, self._default)
33
34
    def __set__(self, obj, val):
35
        val = self._data_type.validate(val)
36
        setattr(obj, self._name, val)
37
38
    def __delete__(self, obj):
39
        # hmmm what is the best approach here
40
        attr = getattr(obj, self._name, None)
41
        if attr:
42
            del attr
43
44
45
class Property(abc.BaseProperty):
46
    """
47
    API class used to define properties. Replaced with
48
    :py:class:`PropertyDescriptor` by :py:class:`goblin.element.ElementMeta`.
49
50
    :param goblin.abc.DataType data_type: Str or class of data type
51
    :param str db_name: User defined custom name for property in db
52
    :param default: Default value for this property.
53
    """
54
55
    __descriptor__ = PropertyDescriptor
56
57
    def __init__(self,
58
                 data_type,
59
                 *,
60
                 db_name=None,
61
                 default=None,
62
                 db_name_factory=None):
63
        if not db_name_factory:
64
            db_name_factory = noop_factory  # noop
65
        if isinstance(data_type, type):
66
            data_type = data_type()
67
        self._db_name_factory = db_name_factory
68
        self._data_type = data_type
69
        self._db_name = db_name
70
        self._default = default
71
72
    @property
73
    def data_type(self):
74
        return self._data_type
75
76
    def getdb_name(self):
77
        return self._db_name
78
79
    def setgetdb_name(self, val):
80
        self._db_name = val
81
82
    db_name = property(getdb_name, setgetdb_name)
83
84
    @property
85
    def db_name_factory(self):
86
        return self._db_name_factory
87
88
    @property
89
    def default(self):
90
        return self._default
91
92
93
class IdPropertyDescriptor:
94
    def __init__(self, name, prop):
95
        assert name == 'id', 'ID properties must be named "id"'
96
        self._data_type = prop.data_type
97
        self._name = '_' + name
98
        self._serializer = prop.serializer
99
100
    def __get__(self, obj, objtype=None):
101
        if obj is None:
102
            raise exception.ElementError(
103
                "Only instantiated elements have ID property")
104
        return obj._id
105
106
    def __set__(self, obj, val):
107
        if self._serializer:
108
            val = self._serializer(val)
109
        val = self._data_type.validate(val)
110
        setattr(obj, self._name, val)
111
112
113
def default_id_serializer(val):
114
    if isinstance(val, int):
115
        val = long(val)
116
    return val
117
118
119
class IdProperty(abc.BaseProperty):
120
121
    __descriptor__ = IdPropertyDescriptor
122
123
    def __init__(self, data_type, *, serializer=None):
124
        if not serializer:
125
            serializer = default_id_serializer
126
        if isinstance(data_type, type):
127
            data_type = data_type()
128
        self._data_type = data_type
129
        self._serializer = serializer
130
131
    @property
132
    def data_type(self):
133
        return self._data_type
134
135
    @property
136
    def serializer(self):
137
        return self._serializer
138
139
140
# Data types
141
class Generic(abc.DataType):
142
    def validate(self, val):
143
        return super().validate(val)
144
145
    def to_db(self, val=None):
146
        return super().to_db(val=val)
147
148
    def to_ogm(self, val):
149
        return super().to_ogm(val)
150
151
152 View Code Duplication
class String(abc.DataType):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
153
    """Simple string datatype"""
154
155
    def validate(self, val):
156
        if val is not None:
157
            try:
158
                return str(val)
159
            except ValueError as e:
160
                raise exception.ValidationError(
161
                    'Not a valid string: {}'.format(val)) from e
162
163
    def to_db(self, val=None):
164
        return super().to_db(val=val)
165
166
    def to_ogm(self, val):
167
        return super().to_ogm(val)
168
169
170
class Integer(abc.DataType):
171
    """Simple integer datatype"""
172
173
    def validate(self, val):
174
        if val is not None:
175
            try:
176
                if isinstance(val, long):
177
                    return long(val)
178
                return int(val)
179
            except (ValueError, TypeError) as e:
180
                raise exception.ValidationError(
181
                    'Not a valid integer: {}'.format(val)) from e
182
183
    def to_db(self, val=None):
184
        return super().to_db(val=val)
185
186
    def to_ogm(self, val):
187
        return super().to_ogm(val)
188
189
190
class Float(abc.DataType):
191
    """Simple float datatype"""
192
193
    def validate(self, val):
194
        try:
195
            val = float(val)
196
        except ValueError:
197
            raise exception.ValidationError(
198
                "Not a valid float: {}".format(val)) from e
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable e does not seem to be defined.
Loading history...
199
        return val
200
201
    def to_db(self, val=None):
202
        return super().to_db(val=val)
203
204
    def to_ogm(self, val):
205
        return super().to_ogm(val)
206
207
208 View Code Duplication
class Boolean(abc.DataType):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
209
    """Simple boolean datatype"""
210
211
    def validate(self, val: Any):
212
        try:
213
            val = bool(val)
214
        except ValueError:
215
            raise exception.ValidationError(
216
                "Not a valid boolean: {val}".format(val)) from e # type: ignore
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable e does not seem to be defined.
Loading history...
217
        return val
218
219
    def to_db(self, val=None):
220
        return super().to_db(val=val)
221
222
    def to_ogm(self, val):
223
        return super().to_ogm(val)
224