aboutsummaryrefslogtreecommitdiff
path: root/pandora/models/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'pandora/models/__init__.py')
-rw-r--r--pandora/models/__init__.py23
1 files changed, 22 insertions, 1 deletions
diff --git a/pandora/models/__init__.py b/pandora/models/__init__.py
index d4e3b87..6a14f45 100644
--- a/pandora/models/__init__.py
+++ b/pandora/models/__init__.py
@@ -12,6 +12,22 @@ class Field(namedtuple("Field", ["field", "default", "formatter"])):
12 return super(Field, cls).__new__(cls, field, default, formatter) 12 return super(Field, cls).__new__(cls, field, default, formatter)
13 13
14 14
15class SyntheticField(namedtuple("SyntheticField", ["field"])):
16 """Field That Requires Synthesis
17
18 Synthetic fields may exist in the data but generally do not and require
19 additional synthesis to arrive ate a sane value. Subclasses must define
20 a formatter method that receives an API client, field name, and full data
21 payload.
22 """
23
24 default = None
25
26 @staticmethod
27 def formatter(api_client, field, data): # pragma: no cover
28 raise NotImplementedError
29
30
15class ModelMetaClass(type): 31class ModelMetaClass(type):
16 32
17 def __new__(cls, name, parents, dct): 33 def __new__(cls, name, parents, dct):
@@ -22,7 +38,7 @@ class ModelMetaClass(type):
22 if key.startswith("__"): 38 if key.startswith("__"):
23 continue 39 continue
24 40
25 if isinstance(val, Field): 41 if isinstance(val, Field) or isinstance(val, SyntheticField):
26 fields[key] = val 42 fields[key] = val
27 del new_dct[key] 43 del new_dct[key]
28 44
@@ -57,6 +73,11 @@ class PandoraModel(with_metaclass(ModelMetaClass, object)):
57 for key, value in instance.__class__._fields.items(): 73 for key, value in instance.__class__._fields.items():
58 newval = data.get(value.field, value.default) 74 newval = data.get(value.field, value.default)
59 75
76 if isinstance(value, SyntheticField):
77 newval = value.formatter(api_client, value.field, data, newval)
78 setattr(instance, key, newval)
79 continue
80
60 if newval and value.formatter: 81 if newval and value.formatter:
61 newval = value.formatter(api_client, newval) 82 newval = value.formatter(api_client, newval)
62 83