From ee193d95cac8c5c3b8c7d0fd61e63be7d96475e7 Mon Sep 17 00:00:00 2001 From: Robert Niederreiter Date: Sat, 3 Dec 2011 11:02:44 +0100 Subject: [PATCH] split up code to some modules --- src/node/ext/zodb/__init__.py | 240 ++++---------------------------- src/node/ext/zodb/interfaces.py | 6 + src/node/ext/zodb/parts.py | 107 ++++++++++++++ src/node/ext/zodb/utils.py | 75 ++++++++++ 4 files changed, 212 insertions(+), 216 deletions(-) create mode 100644 src/node/ext/zodb/interfaces.py create mode 100644 src/node/ext/zodb/parts.py create mode 100644 src/node/ext/zodb/utils.py diff --git a/src/node/ext/zodb/__init__.py b/src/node/ext/zodb/__init__.py index fc66f88..0b71dc8 100644 --- a/src/node/ext/zodb/__init__.py +++ b/src/node/ext/zodb/__init__.py @@ -1,247 +1,55 @@ -import copy -from plumber import ( - plumber, - Part, - default, - extend, - finalize, - plumb, -) -from odict.pyodict import ( - _odict, - _nil, -) +from plumber import plumber from persistent import Persistent -from persistent.dict import PersistentDict -from BTrees.OOBTree import OOBTree -from zope.interface import implements -from node.interfaces import ( - INode, - IAttributes, -) from node.parts import ( Adopt, - Nodespaces, - Attributes, Order, AsAttrAccess, DefaultInit, Nodify, NodeChildValidate, - Storage, ) -from node.utils import ( - AttributeAccess, - instance_property, +from node.ext.zodb.interfaces import IZODBNode +from node.ext.zodb.parts import ( + ZODBPart, + PodictStorage, + OOBTodictStorage, + ZODBAttributes, +) +from node.ext.zodb.utils import ( + Podict, + OOBTodict, + volatile_property, ) -class Podict(_odict, PersistentDict): - - def _dict_impl(self): - return PersistentDict - - -class OOBTodict(_odict, OOBTree): - - def _dict_impl(self): - return OOBTree - - def _get_lh(self): - try: - return self['____lh'] - except KeyError: - self['____lh'] = _nil - return self['____lh'] - - def _set_lh(self, val): - self['____lh'] = val - - lh = property(_get_lh, _set_lh) - - def _get_lt(self): - try: - return self['____lt'] - except KeyError: - self['____lt'] = _nil - return self['____lt'] - - def _set_lt(self, val): - self['____lt'] = val - - lt = property(_get_lt, _set_lt) - - def __getitem__(self, key): - if key.startswith('____'): - return self._dict_impl().__getitem__(self, key) - return _odict.__getitem__(self, key) - - def __setitem__(self, key, val): - if key.startswith('____'): - # private attributes, no way to set persistent attributes on - # OOBTree deriving class. - self._dict_impl().__setitem__(self, key, val) - else: - _odict.__setitem__(self, key, val) - - def __repr__(self): - if self: - pairs = ("(%r, %r)" % (k, v) for k, v in self.iteritems()) - return "OOBTodict([%s])" % ", ".join(pairs) - else: - return "OOBTodict()" - - -class IZODBNode(INode): - """Marker for ZODB nodes. - """ - - -class ZODBPart(Part): - """This part requires plumbed class to inherit from Persistent. - """ - implements(IZODBNode) - - @extend - @property - def __parent__(self): - """Always expect _v_parent to be set, see __setattr__ and - __getitem__. - """ - return self._v_parent - - @extend - def __getitem__(self, key): - v = self.storage[key] - if INode.providedBy(v): - v._v_parent = self - return v - - @extend - def __setattr__(self, name, value): - """If name is __parent__, write value to _v_parent. This avoids - _p_changed to be set set by Persitent.__setattr__. Using a read/write - property for __name__ won't work. - """ - if name == '__parent__': - name = '_v_parent' - Persistent.__setattr__(self, name, value) - - @default - def __call__(self): - """Meant to be plumbed if something should happen in a particular - subclass on __call__. Persisting is left to the ZODB transaction - mechanism. - """ - pass - - @plumb - def __setitem__(_next, self, key, value): - _next(self, key, value) - self.storage._p_changed = 1 - - @finalize - def copy(self): - return copy.deepcopy(self) - - -class PodictStorage(ZODBPart, Storage): - - @default - @instance_property - def storage(self): - return Podict() - - -class OOBTodictStorage(ZODBPart, Storage): - - @default - @instance_property - def storage(self): - return OOBTodict() - - -class ZODBAttributes(Part): - implements(IAttributes) - - attribute_access_for_attrs = default(False) - attributes_factory = default(None) - - @finalize - @property - def attrs(self): - try: - attrs = self._attrs - except AttributeError: - self._attrs = attrs = self.attributes_factory(name='_attrs', - parent=self) - if self.attribute_access_for_attrs: - return AttributeAccess(attrs) - return attrs +attribute_parts = ( + NodeChildValidate, Adopt, DefaultInit, Nodify +) +node_parts = ( + NodeChildValidate, Adopt, Order, AsAttrAccess, + DefaultInit, Nodify, ZODBAttributes +) class ZODBNodeAttributes(Persistent): __metaclass__ = plumber - __plumbing__ = ( - NodeChildValidate, - Adopt, - DefaultInit, - Nodify, - PodictStorage, - ) + __plumbing__ = attribute_parts + (PodictStorage,) allow_non_node_childs = True class ZODBNode(Persistent): __metaclass__ = plumber - __plumbing__ = ( - NodeChildValidate, - Adopt, - Order, - AsAttrAccess, - DefaultInit, - Nodify, - ZODBAttributes, - PodictStorage, - ) + __plumbing__ = node_parts + (PodictStorage,) attributes_factory = ZODBNodeAttributes class OOBTNodeAttributes(Persistent): __metaclass__ = plumber - __plumbing__ = ( - NodeChildValidate, - Adopt, - DefaultInit, - Nodify, - OOBTodictStorage, - ) + __plumbing__ = attribute_parts + (OOBTodictStorage,) allow_non_node_childs = True class OOBTNode(Persistent): __metaclass__ = plumber - __plumbing__ = ( - NodeChildValidate, - Adopt, - Order, - AsAttrAccess, - DefaultInit, - Nodify, - ZODBAttributes, - OOBTodictStorage, - ) - attributes_factory = OOBTNodeAttributes - - -def volatile_property(func): - """Like ``node.utils.instance_property``, but sets instance attribute - with '_v_' prefix. - """ - def wrapper(self): - attribute_name = '_v_%s' % func.__name__ - if not hasattr(self, attribute_name): - setattr(self, attribute_name, func(self)) - return getattr(self, attribute_name) - wrapper.__doc__ = func.__doc__ - return property(wrapper) \ No newline at end of file + __plumbing__ = node_parts + (OOBTodictStorage,) + attributes_factory = OOBTNodeAttributes \ No newline at end of file diff --git a/src/node/ext/zodb/interfaces.py b/src/node/ext/zodb/interfaces.py new file mode 100644 index 0000000..867b4a3 --- /dev/null +++ b/src/node/ext/zodb/interfaces.py @@ -0,0 +1,6 @@ +from node.interfaces import INode + + +class IZODBNode(INode): + """Marker for ZODB nodes. + """ \ No newline at end of file diff --git a/src/node/ext/zodb/parts.py b/src/node/ext/zodb/parts.py new file mode 100644 index 0000000..cd814e2 --- /dev/null +++ b/src/node/ext/zodb/parts.py @@ -0,0 +1,107 @@ +import copy +from plumber import ( + Part, + default, + extend, + finalize, + plumb, +) +from persistent import Persistent +from zope.interface import implements +from node.interfaces import ( + INode, + IAttributes, +) +from node.parts import Storage +from node.utils import ( + AttributeAccess, + instance_property, +) +from node.ext.zodb.interfaces import IZODBNode +from node.ext.zodb.utils import ( + Podict, + OOBTodict, +) + + +class ZODBPart(Part): + """This part requires plumbed class to inherit from Persistent. + """ + implements(IZODBNode) + + @extend + @property + def __parent__(self): + """Always expect _v_parent to be set, see __setattr__ and + __getitem__. + """ + return self._v_parent + + @extend + def __getitem__(self, key): + v = self.storage[key] + if INode.providedBy(v): + v._v_parent = self + return v + + @extend + def __setattr__(self, name, value): + """If name is __parent__, write value to _v_parent. This avoids + _p_changed to be set set by Persitent.__setattr__. Using a read/write + property for __name__ won't work. + """ + if name == '__parent__': + name = '_v_parent' + Persistent.__setattr__(self, name, value) + + @default + def __call__(self): + """Meant to be plumbed if something should happen in a particular + subclass on __call__. Persisting is left to the ZODB transaction + mechanism. + """ + pass + + @plumb + def __setitem__(_next, self, key, value): + _next(self, key, value) + self.storage._p_changed = 1 + + @finalize + def copy(self): + return copy.deepcopy(self) + + +class PodictStorage(ZODBPart, Storage): + + @default + @instance_property + def storage(self): + return Podict() + + +class OOBTodictStorage(ZODBPart, Storage): + + @default + @instance_property + def storage(self): + return OOBTodict() + + +class ZODBAttributes(Part): + implements(IAttributes) + + attribute_access_for_attrs = default(False) + attributes_factory = default(None) + + @finalize + @property + def attrs(self): + try: + attrs = self._attrs + except AttributeError: + self._attrs = attrs = self.attributes_factory(name='_attrs', + parent=self) + if self.attribute_access_for_attrs: + return AttributeAccess(attrs) + return attrs \ No newline at end of file diff --git a/src/node/ext/zodb/utils.py b/src/node/ext/zodb/utils.py new file mode 100644 index 0000000..4c747dc --- /dev/null +++ b/src/node/ext/zodb/utils.py @@ -0,0 +1,75 @@ +from odict.pyodict import ( + _odict, + _nil, +) +from persistent.dict import PersistentDict +from BTrees.OOBTree import OOBTree + + +class Podict(_odict, PersistentDict): + + def _dict_impl(self): + return PersistentDict + + +class OOBTodict(_odict, OOBTree): + + def _dict_impl(self): + return OOBTree + + def _get_lh(self): + try: + return self['____lh'] + except KeyError: + self['____lh'] = _nil + return self['____lh'] + + def _set_lh(self, val): + self['____lh'] = val + + lh = property(_get_lh, _set_lh) + + def _get_lt(self): + try: + return self['____lt'] + except KeyError: + self['____lt'] = _nil + return self['____lt'] + + def _set_lt(self, val): + self['____lt'] = val + + lt = property(_get_lt, _set_lt) + + def __getitem__(self, key): + if key.startswith('____'): + return self._dict_impl().__getitem__(self, key) + return _odict.__getitem__(self, key) + + def __setitem__(self, key, val): + if key.startswith('____'): + # private attributes, no way to set persistent attributes on + # OOBTree deriving class. + self._dict_impl().__setitem__(self, key, val) + else: + _odict.__setitem__(self, key, val) + + def __repr__(self): + if self: + pairs = ("(%r, %r)" % (k, v) for k, v in self.iteritems()) + return "OOBTodict([%s])" % ", ".join(pairs) + else: + return "OOBTodict()" + + +def volatile_property(func): + """Like ``node.utils.instance_property``, but sets instance attribute + with '_v_' prefix. + """ + def wrapper(self): + attribute_name = '_v_%s' % func.__name__ + if not hasattr(self, attribute_name): + setattr(self, attribute_name, func(self)) + return getattr(self, attribute_name) + wrapper.__doc__ = func.__doc__ + return property(wrapper) \ No newline at end of file