Skip to content

Commit e11e5a3

Browse files
committed
Reorganize the package
1 parent 9f1296d commit e11e5a3

7 files changed

Lines changed: 175 additions & 123 deletions

File tree

adapters/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3-
from adapters import * # noqa
3+
from __future__ import absolute_import
4+
5+
from .adapters import * # noqa
6+
from .fields import * # noqa

adapters/adapters.py

Lines changed: 6 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,19 @@
11
# -*- coding: utf-8 -*-
22

33
from __future__ import unicode_literals
4+
from __future__ import absolute_import
45

56
import collections
67
import copy
78
import six
89

10+
from .base import BaseField
11+
from .meta import AdapterMetaClass
12+
from .utils import BindingDict
13+
from .utils import undefined
914

10-
__all__ = ['Adapter', 'Field']
1115

12-
13-
class undefined:
14-
pass
15-
16-
17-
class BindingDict(collections.MutableMapping):
18-
def __init__(self, adapter):
19-
self.adapter = adapter
20-
self.fields = collections.OrderedDict()
21-
22-
def __setitem__(self, key, field):
23-
self.fields[key] = field
24-
field.bind(key, self.adapter)
25-
26-
def __getitem__(self, key):
27-
return self.fields[key]
28-
29-
def __delitem__(self, key):
30-
del self.fields[key]
31-
32-
def __iter__(self):
33-
return iter(self.fields)
34-
35-
def __len__(self):
36-
return len(self.fields)
37-
38-
def __repr__(self):
39-
return dict.__repr__(self.fields)
40-
41-
42-
def get_attribute(obj, attrs):
43-
for attr in attrs:
44-
if obj is None:
45-
return undefined
46-
47-
try:
48-
if isinstance(obj, collections.Mapping):
49-
obj = obj[attr]
50-
elif isinstance(obj, collections.Iterable):
51-
obj = obj[int(attr)]
52-
else:
53-
obj = getattr(obj, attr)
54-
except Exception:
55-
return undefined
56-
57-
if callable(obj):
58-
obj = obj()
59-
60-
return obj
61-
62-
63-
class BaseField(object):
64-
def __init__(self, source=None, default=undefined, required=True):
65-
self.source = source
66-
self.default = default
67-
self.required = required
68-
69-
def bind(self, field_name, adapter):
70-
if field_name == self.source:
71-
raise ValueError((
72-
"The `source='{field_name}'` kwarg is redundant on "
73-
"field `{adapter_name}.{field_name}`. "
74-
"Remove the `source` kwarg."
75-
).format(
76-
field_name=field_name,
77-
adapter_name=adapter.__class__.__name__,
78-
))
79-
80-
self.field_name = field_name
81-
self.adapter = adapter
82-
83-
if self.source is None:
84-
self.source = self.field_name
85-
86-
if self.source == '*':
87-
self.lookup_attrs = []
88-
else:
89-
self.lookup_attrs = self.source.split('.')
90-
91-
def get_attribute(self, obj):
92-
value = get_attribute(obj, self.lookup_attrs)
93-
if value is undefined:
94-
if self.default is not undefined:
95-
return self.default
96-
elif self.required:
97-
raise ValueError((
98-
"Required value not found for field "
99-
"`{adapter_name}.{field_name}`. Provide a default value."
100-
).format(
101-
adapter_name=self.adapter.__class__.__name__,
102-
field_name=self.field_name,
103-
))
104-
else:
105-
return undefined
106-
else:
107-
return value
108-
109-
def adapt(self, data):
110-
return data
111-
112-
113-
class AdapterMetaClass(type):
114-
def __new__(meta, name, bases, attrs):
115-
fields = [
116-
(key, attrs.pop(key))
117-
for key in attrs.keys() if isinstance(attrs[key], BaseField)
118-
]
119-
120-
for base in reversed(bases):
121-
if hasattr(base, 'declared_fields'):
122-
fields = list(base.declared_fields.items()) + fields
123-
124-
attrs['declared_fields'] = collections.OrderedDict(fields)
125-
126-
cls = super(AdapterMetaClass, meta).__new__(meta, name, bases, attrs)
127-
128-
return cls
129-
130-
131-
class Field(BaseField):
132-
pass
16+
__all__ = ['Adapter']
13317

13418

13519
@six.add_metaclass(AdapterMetaClass)

adapters/base.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from __future__ import unicode_literals
4+
from __future__ import absolute_import
5+
6+
from .helpers import get_attribute
7+
from .utils import undefined
8+
9+
10+
class BaseField(object):
11+
def __init__(self, source=None, default=undefined, required=True):
12+
self.source = source
13+
self.default = default
14+
self.required = required
15+
16+
def bind(self, field_name, adapter):
17+
if field_name == self.source:
18+
raise ValueError((
19+
"The `source='{field_name}'` kwarg is redundant on "
20+
"field `{adapter_name}.{field_name}`. "
21+
"Remove the `source` kwarg."
22+
).format(
23+
field_name=field_name,
24+
adapter_name=adapter.__class__.__name__,
25+
))
26+
27+
self.field_name = field_name
28+
self.adapter = adapter
29+
30+
if self.source is None:
31+
self.source = self.field_name
32+
33+
if self.source == '*':
34+
self.lookup_attrs = []
35+
else:
36+
self.lookup_attrs = self.source.split('.')
37+
38+
def get_attribute(self, obj):
39+
value = get_attribute(obj, self.lookup_attrs)
40+
if value is undefined:
41+
if self.default is not undefined:
42+
return self.default
43+
elif self.required:
44+
raise ValueError((
45+
"Required value not found for field "
46+
"`{adapter_name}.{field_name}`. Provide a default value."
47+
).format(
48+
adapter_name=self.adapter.__class__.__name__,
49+
field_name=self.field_name,
50+
))
51+
else:
52+
return undefined
53+
else:
54+
return value
55+
56+
def adapt(self, data):
57+
return data

adapters/fields.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from __future__ import unicode_literals
4+
5+
from .base import BaseField
6+
7+
8+
__all__ = ['Field']
9+
10+
11+
class Field(BaseField):
12+
pass

adapters/helpers.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from __future__ import unicode_literals
4+
from __future__ import absolute_import
5+
6+
import collections
7+
8+
from .utils import undefined
9+
10+
11+
__all__ = ['get_attribute']
12+
13+
14+
def get_attribute(obj, attrs):
15+
for attr in attrs:
16+
if obj is None:
17+
return undefined
18+
19+
try:
20+
if isinstance(obj, collections.Mapping):
21+
obj = obj[attr]
22+
elif isinstance(obj, collections.Iterable):
23+
obj = obj[int(attr)]
24+
else:
25+
obj = getattr(obj, attr)
26+
except Exception:
27+
return undefined
28+
29+
if callable(obj):
30+
obj = obj()
31+
32+
return obj

adapters/meta.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from __future__ import unicode_literals
4+
from __future__ import absolute_import
5+
6+
import collections
7+
8+
from .base import BaseField
9+
10+
11+
__all__ = ['AdapterMetaClass']
12+
13+
14+
class AdapterMetaClass(type):
15+
def __new__(meta, name, bases, attrs):
16+
fields = [
17+
(key, attrs.pop(key))
18+
for key in attrs.keys() if isinstance(attrs[key], BaseField)
19+
]
20+
21+
for base in reversed(bases):
22+
if hasattr(base, 'declared_fields'):
23+
fields = list(base.declared_fields.items()) + fields
24+
25+
attrs['declared_fields'] = collections.OrderedDict(fields)
26+
27+
cls = super(AdapterMetaClass, meta).__new__(meta, name, bases, attrs)
28+
29+
return cls

adapters/utils.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import collections
4+
5+
6+
__all__ = ['BindingDict', 'undefined']
7+
8+
9+
class BindingDict(collections.MutableMapping):
10+
def __init__(self, adapter):
11+
self.adapter = adapter
12+
self.fields = collections.OrderedDict()
13+
14+
def __setitem__(self, key, field):
15+
self.fields[key] = field
16+
field.bind(key, self.adapter)
17+
18+
def __getitem__(self, key):
19+
return self.fields[key]
20+
21+
def __delitem__(self, key):
22+
del self.fields[key]
23+
24+
def __iter__(self):
25+
return iter(self.fields)
26+
27+
def __len__(self):
28+
return len(self.fields)
29+
30+
def __repr__(self):
31+
return dict.__repr__(self.fields)
32+
33+
34+
class undefined:
35+
pass

0 commit comments

Comments
 (0)