Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Uninitialized:
- pass
- class FieldDescriptor(object):
- def __init__(self, value_type, json_key, initial_value=Uninitialized):
- self._value_type = value_type
- self._storage_key = json_key
- self._initial_value = initial_value
- self._parent_attr_name = None
- def _check_py_value(self, new_value):
- if new_value is not None and not isinstance(new_value, self._value_type):
- raise TypeError("Bad type %s" % type(new_value).__name__)
- def _form_json_value(self, parent_instance):
- return self.__get__(parent_instance)
- def __get__(self, parent_instance, _=None):
- value = getattr(parent_instance, self._parent_attr_name).val
- return None if value is Uninitialized else value
- def __set__(self, parent_instance, value):
- getattr(parent_instance, self._parent_attr_name).val = value
- class StrField(FieldDescriptor):
- def __init__(self, json_key, initial_value=Uninitialized):
- super(StrField, self).__init__(str, json_key, initial_value)
- class ListField(FieldDescriptor):
- def __init__(self, json_key, initial_value=Uninitialized):
- super(ListField, self).__init__(list, json_key, initial_value)
- class Wrap(object):
- def __init__(self, val):
- self.val = val
- class ObjectField(FieldDescriptor):
- def __init__(self, json_key):
- for name_, descriptor in self.iterate_descriptors():
- attr_name = "_value_of_{}".format(name_) # kind of proxy
- descriptor._parent_attr_name = attr_name
- new_field = Wrap(descriptor._initial_value)
- setattr(self, attr_name, new_field)
- FieldDescriptor.__init__(self, value_type=self.__class__, json_key=json_key, initial_value=self)
- @classmethod
- def iterate_descriptors(cls):
- for attr_name, descriptor in cls.__dict__.iteritems():
- if isinstance(descriptor, FieldDescriptor):
- yield attr_name, descriptor
- def _form_json_value(self, _=None):
- return {dsc._storage_key: dsc._form_json_value(self) for _, dsc in self.iterate_descriptors()}
- def test_it_with_pytest():
- class ObjF(ObjectField):
- txt = StrField("OBJF.StrDO")
- list = ListField("OBJF.C")
- class Nest(ObjectField):
- b1 = ObjF("NEST.B1")
- b2 = ObjF("NEST.B2")
- class Outer(ObjectField):
- oo1 = Nest('oo1')
- oo2 = Nest('oo2')
- root = Outer(None)
- # assign some values
- root.oo1.b1.txt = "DIFFERENT"
- root.oo2.b2.list = [12, 3, 5]
- assert root.oo1._value_of_b1 != root.oo2._value_of_b1 # that pass
- a = root.oo1.b1.txt
- b = root.oo1.b2.txt
- c = root.oo2.b1.txt
- assert a != b # that pass
- assert a != c # that fails, 'DIFFERENT' == 'DIFFERENT'
- assert root._form_json_value() == {
- 'oo1': {
- 'NEST.B1': {
- 'OBJF.C': None,
- 'OBJF.StrDO': 'DIFFERENT' # ok
- },
- 'NEST.B2': {
- 'OBJF.C': None, # that fails, is [12, 3, 5]
- 'OBJF.StrDO': None
- }
- },
- 'oo2': {
- 'NEST.B1': {
- 'OBJF.C': None,
- 'OBJF.StrDO': None # that fails is "DIFFERENT"
- },
- 'NEST.B2': {
- 'OBJF.C': [12, 3, 5], # ok
- 'OBJF.StrDO': None
- }
- }
- }
Add Comment
Please, Sign In to add comment