Beispiel #1
0
    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
Beispiel #2
0
    def __get__(self, instance, owner):
        def convert(value):
            if isinstance(value, ObjectId):
                # Dereference
                if hasattr(self.document_type, "get_by_id"):
                    return self.document_type.get_by_id(ObjectId(value))
                else:
                    v = self.document_type.objects(id=value).first()
                if v is None:
                    raise ValidationError("Unable to dereference %s:%s" %
                                          (self.document_type, v))
                return v
            else:
                return value

        if instance is None:
            # Document class being used rather than a document object
            return self
        # Get value from document instance if available
        value = instance._data.get(self.name)
        # Dereference DBRefs value = BaseList(value, instance, self.name)
        if value is not None:
            instance._data[self.name] = BaseList([convert(v) for v in value],
                                                 instance, self.name)
        return super().__get__(instance, owner)
Beispiel #3
0
    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
Beispiel #4
0
    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')
        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))
                and 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
Beispiel #5
0
    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
Beispiel #6
0
    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')
        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)) and
           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 test___init___(self):
        class MyDoc(Document):
            pass

        list_items = [True]
        doc = MyDoc()
        base_list = BaseList(list_items, instance=doc, name='my_name')
        self.assertIsInstance(base_list._instance, Document)
        self.assertEqual(base_list._name, 'my_name')
        self.assertEqual(base_list, list_items)
    def test___init___(self):
        class MyDoc(Document):
            pass

        list_items = [True]
        doc = MyDoc()
        base_list = BaseList(list_items, instance=doc, name="my_name")
        assert isinstance(base_list._instance, Document)
        assert base_list._name == "my_name"
        assert base_list == list_items
Beispiel #9
0
    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 test___iter__(self):
     values = [True, False, True, False]
     base_list = BaseList(values, instance=None, name='my_name')
     self.assertEqual(values, list(base_list))
 def _get_baselist(list_items):
     """Get a BaseList bound to a fake document instance"""
     fake_doc = DocumentStub()
     base_list = BaseList(list_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 test___iter__(self):
     values = [True, False, True, False]
     base_list = BaseList(values, instance=None, name="my_name")
     assert values == list(base_list)
 def test___iter___allow_modification_while_iterating_withou_error(self):
     # regular list allows for this, thus this subclass must comply to that
     base_list = BaseList([True, False, True, False], instance=None, name='my_name')
     for idx, val in enumerate(base_list):
         if val:
             base_list.pop(idx)
 def _get_baselist(list_items):
     """Get a BaseList bound to a fake document instance"""
     fake_doc = DocumentStub()
     base_list = BaseList(list_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
Beispiel #15
0
 def test___iter___allow_modification_while_iterating_withou_error(self):
     # regular list allows for this, thus this subclass must comply to that
     base_list = BaseList([True, False, True, False], instance=None, name='my_name')
     for idx, val in enumerate(base_list):
         if val:
             base_list.pop(idx)