def _get_basedict(dict_items): """Get a BaseList bound to a fake document instance""" fake_doc = DocumentStub() base_list = BaseDict(dict_items, instance=None, name="my_name") base_list._instance = ( fake_doc # hack to inject the mock, it does not work in the constructor ) return base_list
def __expand_dynamic_values(self, name, value): """Expand any dynamic values to their correct types / values.""" if not isinstance(value, (dict, list, tuple)): return value # If the value is a dict with '_cls' in it, turn it into a document is_dict = isinstance(value, dict) if is_dict and '_cls' in value: cls = get_document(value['_cls']) return cls(**value) if is_dict: value = { k: self.__expand_dynamic_values(k, v) for k, v in value.items() } else: value = [self.__expand_dynamic_values(name, v) for v in value] # Convert lists / values so we can watch for any changes on them EmbeddedDocumentListField = _import_class('EmbeddedDocumentListField') if (isinstance(value, (list, tuple)) and not isinstance(value, BaseList)): if issubclass(type(self), EmbeddedDocumentListField): value = EmbeddedDocumentList(value, self, name) else: value = BaseList(value, self, name) elif isinstance(value, dict) and not isinstance(value, BaseDict): value = BaseDict(value, self, name) return value
def __expand_dynamic_values(self, name, value): """expand any dynamic values to their correct types / values""" if not isinstance(value, (dict, list, tuple)): return value is_list = False if not hasattr(value, 'items'): is_list = True value = dict([(k, v) for k, v in enumerate(value)]) if not is_list and '_cls' in value: cls = get_document(value['_cls']) return cls(**value) data = {} for k, v in value.items(): key = name if is_list else k data[k] = self.__expand_dynamic_values(key, v) if is_list: # Convert back to a list data_items = sorted(data.items(), key=operator.itemgetter(0)) value = [v for k, v in data_items] else: value = data # Convert lists / values so we can watch for any changes on them if (isinstance(value, (list, tuple)) and not isinstance(value, BaseList)): value = BaseList(value, self, name) elif isinstance(value, dict) and not isinstance(value, BaseDict): value = BaseDict(value, self, name) return value
def __get__(self, instance, owner): """Descriptor to automatically dereference references.""" if instance is None: # Document class being used rather than a document object return self ReferenceField = _import_class("ReferenceField") GenericReferenceField = _import_class("GenericReferenceField") EmbeddedDocumentListField = _import_class("EmbeddedDocumentListField") auto_dereference = instance._fields[self.name]._auto_dereference dereference = auto_dereference and ( self.field is None or isinstance(self.field, (GenericReferenceField, ReferenceField)) ) if ( instance._initialised and dereference and instance._data.get(self.name) and not getattr(instance._data[self.name], "_dereferenced", False) ): ref_values = instance._data.get(self.name) instance._data[self.name] = self._lazy_load_refs( ref_values=ref_values, instance=instance, name=self.name, max_depth=1 ) if hasattr(instance._data[self.name], "_dereferenced"): instance._data[self.name]._dereferenced = True value = super().__get__(instance, owner) # Convert lists / values so we can watch for any changes on them if isinstance(value, (list, tuple)): if issubclass(type(self), EmbeddedDocumentListField) and not isinstance( value, EmbeddedDocumentList ): value = EmbeddedDocumentList(value, instance, self.name) elif not isinstance(value, BaseList): value = BaseList(value, instance, self.name) instance._data[self.name] = value elif isinstance(value, dict) and not isinstance(value, BaseDict): value = BaseDict(value, instance, self.name) instance._data[self.name] = value if ( auto_dereference and instance._initialised and isinstance(value, (BaseList, BaseDict)) and not value._dereferenced ): value = self._lazy_load_refs( ref_values=value, instance=instance, name=self.name, max_depth=1 ) value._dereferenced = True instance._data[self.name] = value return value
def test___init___(self): class MyDoc(Document): pass dict_items = {'k': 'v'} doc = MyDoc() base_dict = BaseDict(dict_items, instance=doc, name='my_name') self.assertIsInstance(base_dict._instance, Document) self.assertEqual(base_dict._name, 'my_name') self.assertEqual(base_dict, dict_items)
def test___init___(self): class MyDoc(Document): pass dict_items = {"k": "v"} doc = MyDoc() base_dict = BaseDict(dict_items, instance=doc, name="my_name") assert isinstance(base_dict._instance, Document) assert base_dict._name == "my_name" assert base_dict == dict_items
def test___init___(self): class MyDoc(Document): pass dict_items = {"k": "v"} doc = MyDoc() base_dict = BaseDict(dict_items, instance=doc, name="my_name") self.assertIsInstance(base_dict._instance, Document) self.assertEqual(base_dict._name, "my_name") self.assertEqual(base_dict, dict_items)
def _convert_value(self, instance, value): if isinstance(value, (list, tuple)): if (issubclass(type(self), fields.EmbeddedDocumentListField) and not isinstance(value, fields.EmbeddedDocumentList)): value = EmbeddedDocumentList(value, instance, self.name) elif not isinstance(value, BaseList): value = BaseList(value, instance, self.name) instance._data[self.name] = value elif isinstance(value, dict) and not isinstance(value, BaseDict): value = BaseDict(value, instance, self.name) instance._data[self.name] = value return value
def __get__(self, instance, owner): """Descriptor to automatically dereference references. """ if instance is None: # Document class being used rather than a document object return self ReferenceField = _import_class('ReferenceField') GenericReferenceField = _import_class('GenericReferenceField') EmbeddedDocumentListField = _import_class('EmbeddedDocumentListField') dereference = (self._auto_dereference and (self.field is None or isinstance( self.field, (GenericReferenceField, ReferenceField)))) _dereference = _import_class("DeReference")() self._auto_dereference = instance._fields[self.name]._auto_dereference if instance._initialised and dereference and instance._data.get( self.name): instance._data[self.name] = _dereference(instance._data.get( self.name), max_depth=1, instance=instance, name=self.name) value = super(ComplexBaseField, self).__get__(instance, owner) # Convert lists / values so we can watch for any changes on them if isinstance(value, (list, tuple)): if (issubclass(type(self), EmbeddedDocumentListField) and not isinstance(value, EmbeddedDocumentList)): value = EmbeddedDocumentList(value, instance, self.name) elif not isinstance(value, BaseList): value = BaseList(value, instance, self.name) instance._data[self.name] = value elif isinstance(value, dict) and not isinstance(value, BaseDict): value = BaseDict(value, instance, self.name) instance._data[self.name] = value if (self._auto_dereference and instance._initialised and isinstance(value, (BaseList, BaseDict)) and not value._dereferenced): value = _dereference(value, max_depth=1, instance=instance, name=self.name) value._dereferenced = True instance._data[self.name] = value return value
def _get_basedict(dict_items): """Get a BaseList bound to a fake document instance""" fake_doc = DocumentStub() base_list = BaseDict(dict_items, instance=None, name='my_name') base_list._instance = fake_doc # hack to inject the mock, it does not work in the constructor return base_list