Guest User

Untitled

a guest
Oct 20th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.30 KB | None | 0 0
  1. class Uninitialized:
  2. pass
  3.  
  4.  
  5. class FieldDescriptor(object):
  6.  
  7. def __init__(self, value_type, json_key, initial_value=Uninitialized):
  8. self._value_type = value_type
  9. self._storage_key = json_key
  10. self._initial_value = initial_value
  11. self._parent_attr_name = None
  12.  
  13. def _check_py_value(self, new_value):
  14. if new_value is not None and not isinstance(new_value, self._value_type):
  15. raise TypeError("Bad type %s" % type(new_value).__name__)
  16.  
  17. def _form_json_value(self, parent_instance):
  18. return self.__get__(parent_instance)
  19.  
  20. def __get__(self, parent_instance, _=None):
  21. value = getattr(parent_instance, self._parent_attr_name).val
  22. return None if value is Uninitialized else value
  23.  
  24. def __set__(self, parent_instance, value):
  25. getattr(parent_instance, self._parent_attr_name).val = value
  26.  
  27.  
  28. class StrField(FieldDescriptor):
  29. def __init__(self, json_key, initial_value=Uninitialized):
  30. super(StrField, self).__init__(str, json_key, initial_value)
  31.  
  32.  
  33. class ListField(FieldDescriptor):
  34. def __init__(self, json_key, initial_value=Uninitialized):
  35. super(ListField, self).__init__(list, json_key, initial_value)
  36.  
  37.  
  38. class Wrap(object):
  39. def __init__(self, val):
  40. self.val = val
  41.  
  42.  
  43. class ObjectField(FieldDescriptor):
  44. def __init__(self, json_key):
  45. for name_, descriptor in self.iterate_descriptors():
  46. attr_name = "_value_of_{}".format(name_) # kind of proxy
  47. descriptor._parent_attr_name = attr_name
  48. new_field = Wrap(descriptor._initial_value)
  49. setattr(self, attr_name, new_field)
  50.  
  51. FieldDescriptor.__init__(self, value_type=self.__class__, json_key=json_key, initial_value=self)
  52.  
  53. @classmethod
  54. def iterate_descriptors(cls):
  55. for attr_name, descriptor in cls.__dict__.iteritems():
  56. if isinstance(descriptor, FieldDescriptor):
  57. yield attr_name, descriptor
  58.  
  59. def _form_json_value(self, _=None):
  60. return {dsc._storage_key: dsc._form_json_value(self) for _, dsc in self.iterate_descriptors()}
  61.  
  62.  
  63. def test_it_with_pytest():
  64.  
  65. class ObjF(ObjectField):
  66. txt = StrField("OBJF.StrDO")
  67. list = ListField("OBJF.C")
  68.  
  69. class Nest(ObjectField):
  70. b1 = ObjF("NEST.B1")
  71. b2 = ObjF("NEST.B2")
  72.  
  73. class Outer(ObjectField):
  74. oo1 = Nest('oo1')
  75. oo2 = Nest('oo2')
  76.  
  77. root = Outer(None)
  78. # assign some values
  79. root.oo1.b1.txt = "DIFFERENT"
  80. root.oo2.b2.list = [12, 3, 5]
  81.  
  82. assert root.oo1._value_of_b1 != root.oo2._value_of_b1 # that pass
  83.  
  84. a = root.oo1.b1.txt
  85. b = root.oo1.b2.txt
  86. c = root.oo2.b1.txt
  87. assert a != b # that pass
  88. assert a != c # that fails, 'DIFFERENT' == 'DIFFERENT'
  89.  
  90. assert root._form_json_value() == {
  91. 'oo1': {
  92. 'NEST.B1': {
  93. 'OBJF.C': None,
  94. 'OBJF.StrDO': 'DIFFERENT' # ok
  95. },
  96. 'NEST.B2': {
  97. 'OBJF.C': None, # that fails, is [12, 3, 5]
  98. 'OBJF.StrDO': None
  99. }
  100. },
  101. 'oo2': {
  102. 'NEST.B1': {
  103. 'OBJF.C': None,
  104. 'OBJF.StrDO': None # that fails is "DIFFERENT"
  105. },
  106. 'NEST.B2': {
  107. 'OBJF.C': [12, 3, 5], # ok
  108. 'OBJF.StrDO': None
  109. }
  110. }
  111. }
Add Comment
Please, Sign In to add comment