159 lines
4.9 KiB
Python
159 lines
4.9 KiB
Python
import weakref
|
|
from mongoengine.common import _import_class
|
|
|
|
__all__ = ("BaseDict", "BaseList")
|
|
|
|
|
|
class BaseDict(dict):
|
|
"""A special dict so we can watch any changes
|
|
"""
|
|
|
|
_dereferenced = False
|
|
_instance = None
|
|
_name = None
|
|
|
|
def __init__(self, dict_items, instance, name):
|
|
Document = _import_class('Document')
|
|
EmbeddedDocument = _import_class('EmbeddedDocument')
|
|
|
|
if isinstance(instance, (Document, EmbeddedDocument)):
|
|
self._instance = weakref.proxy(instance)
|
|
self._name = name
|
|
return super(BaseDict, self).__init__(dict_items)
|
|
|
|
def __getitem__(self, *args, **kwargs):
|
|
value = super(BaseDict, self).__getitem__(*args, **kwargs)
|
|
|
|
EmbeddedDocument = _import_class('EmbeddedDocument')
|
|
if isinstance(value, EmbeddedDocument) and value._instance is None:
|
|
value._instance = self._instance
|
|
return value
|
|
|
|
def __setitem__(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseDict, self).__setitem__(*args, **kwargs)
|
|
|
|
def __delete__(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseDict, self).__delete__(*args, **kwargs)
|
|
|
|
def __delitem__(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseDict, self).__delitem__(*args, **kwargs)
|
|
|
|
def __delattr__(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseDict, self).__delattr__(*args, **kwargs)
|
|
|
|
def __getstate__(self):
|
|
self.instance = None
|
|
self._dereferenced = False
|
|
return self
|
|
|
|
def __setstate__(self, state):
|
|
self = state
|
|
return self
|
|
|
|
def clear(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseDict, self).clear(*args, **kwargs)
|
|
|
|
def pop(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseDict, self).pop(*args, **kwargs)
|
|
|
|
def popitem(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseDict, self).popitem(*args, **kwargs)
|
|
|
|
def update(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseDict, self).update(*args, **kwargs)
|
|
|
|
def _mark_as_changed(self):
|
|
if hasattr(self._instance, '_mark_as_changed'):
|
|
self._instance._mark_as_changed(self._name)
|
|
|
|
|
|
class BaseList(list):
|
|
"""A special list so we can watch any changes
|
|
"""
|
|
|
|
_dereferenced = False
|
|
_instance = None
|
|
_name = None
|
|
|
|
def __init__(self, list_items, instance, name):
|
|
Document = _import_class('Document')
|
|
EmbeddedDocument = _import_class('EmbeddedDocument')
|
|
|
|
if isinstance(instance, (Document, EmbeddedDocument)):
|
|
self._instance = weakref.proxy(instance)
|
|
self._name = name
|
|
return super(BaseList, self).__init__(list_items)
|
|
|
|
def __getitem__(self, *args, **kwargs):
|
|
value = super(BaseList, self).__getitem__(*args, **kwargs)
|
|
|
|
EmbeddedDocument = _import_class('EmbeddedDocument')
|
|
if isinstance(value, EmbeddedDocument) and value._instance is None:
|
|
value._instance = self._instance
|
|
return value
|
|
|
|
def __setitem__(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).__setitem__(*args, **kwargs)
|
|
|
|
def __delitem__(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).__delitem__(*args, **kwargs)
|
|
|
|
def __setslice__(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).__setslice__(*args, **kwargs)
|
|
|
|
def __delslice__(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).__delslice__(*args, **kwargs)
|
|
|
|
def __getstate__(self):
|
|
self.instance = None
|
|
self._dereferenced = False
|
|
return self
|
|
|
|
def __setstate__(self, state):
|
|
self = state
|
|
return self
|
|
|
|
def append(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).append(*args, **kwargs)
|
|
|
|
def extend(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).extend(*args, **kwargs)
|
|
|
|
def insert(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).insert(*args, **kwargs)
|
|
|
|
def pop(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).pop(*args, **kwargs)
|
|
|
|
def remove(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).remove(*args, **kwargs)
|
|
|
|
def reverse(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).reverse(*args, **kwargs)
|
|
|
|
def sort(self, *args, **kwargs):
|
|
self._mark_as_changed()
|
|
return super(BaseList, self).sort(*args, **kwargs)
|
|
|
|
def _mark_as_changed(self):
|
|
if hasattr(self._instance, '_mark_as_changed'):
|
|
self._instance._mark_as_changed(self._name)
|