[Zope-Checkins] SVN: Zope/trunk/lib/python/ZClasses/_pmc.py Import
what we can from ZODB.persistentclass to avoid duplication.
Jim Fulton
jim at zope.com
Sun Apr 10 09:42:01 EDT 2005
Log message for revision 29939:
Import what we can from ZODB.persistentclass to avoid duplication.
Changed:
U Zope/trunk/lib/python/ZClasses/_pmc.py
-=-
Modified: Zope/trunk/lib/python/ZClasses/_pmc.py
===================================================================
--- Zope/trunk/lib/python/ZClasses/_pmc.py 2005-04-10 13:15:31 UTC (rev 29938)
+++ Zope/trunk/lib/python/ZClasses/_pmc.py 2005-04-10 13:42:00 UTC (rev 29939)
@@ -18,136 +18,24 @@
$Id$
"""
-
-
-# Notes:
-#
-# Persistent classes are non-ghostable. This has some interesting
-# ramifications:
-#
-# - When an object is invalidated, it must reload it's state
-#
-# - When an object is loaded from the database, it's state must be
-# loaded. Unfortunately, there isn't a clear signal when an object is
-# loaded from the database. This should probably be fixed.
-#
-# In the mean time, we need to infer. This should be viewed as a
-# short term hack.
-#
-# Here's the strategy we'll use:
-#
-# - We'll have a need to be loaded flag that we'll set in
-# __new__, through an extra argument.
-#
-# - When setting _p_oid and _p_jar, if both are set and we need to be
-# loaded, then we'll load out state.
-#
-# - We'll use _p_changed is None to indicate that we're in this state.
-#
-
import ExtensionClass
+import ZODB.persistentclass
-class _p_DataDescr(object):
- # Descr used as base for _p_ data. Data are stored in
- # _p_class_dict.
+# See the comments in ZODB.persistentclass
- def __init__(self, name):
- self.__name__ = name
-
- def __get__(self, inst, cls):
- if inst is None:
- return self
-
- if '__global_persistent_class_not_stored_in_DB__' in inst.__dict__:
- raise AttributeError, self.__name__
- return inst._p_class_dict.get(self.__name__)
-
- def __set__(self, inst, v):
- inst._p_class_dict[self.__name__] = v
-
- def __delete__(self, inst):
- raise AttributeError, self.__name__
-
-class _p_oid_or_jar_Descr(_p_DataDescr):
- # Special descr for _p_oid and _p_jar that loads
- # state when set if both are set and and _p_changed is None
- #
- # See notes above
-
- def __set__(self, inst, v):
- get = inst._p_class_dict.get
- if v == get(self.__name__):
- return
-
- inst._p_class_dict[self.__name__] = v
-
- jar = get('_p_jar')
- if (jar is not None
- and get('_p_oid') is not None
- and get('_p_changed') is None
- ):
- jar.setstate(inst)
-
-class _p_ChangedDescr(object):
- # descriptor to handle special weird emantics of _p_changed
-
- def __get__(self, inst, cls):
- if inst is None:
- return self
- return inst._p_class_dict['_p_changed']
-
- def __set__(self, inst, v):
- if v is None:
- return
- inst._p_class_dict['_p_changed'] = bool(v)
-
- def __delete__(self, inst):
- inst._p_invalidate()
-
-class _p_MethodDescr(object):
- """Provide unassignable class attributes
- """
-
- def __init__(self, func):
- self.func = func
-
- def __get__(self, inst, cls):
- if inst is None:
- return cls
- return self.func.__get__(inst, cls)
-
- def __set__(self, inst, v):
- raise AttributeError, self.__name__
-
- def __delete__(self, inst):
- raise AttributeError, self.__name__
-
-
-special_class_descrs = '__dict__', '__weakref__'
-
-
-def _p_maybeupdate(self, name):
- get = self._p_class_dict.get
- data_manager = get('_p_jar')
-
- if (
- (data_manager is not None)
- and
- (get('_p_oid') is not None)
- and
- (get('_p_changed') == False)
- ):
-
- self._p_changed = True
- data_manager.register(self)
-
class ZClassPersistentMetaClass(ExtensionClass.ExtensionClass):
- _p_jar = _p_oid_or_jar_Descr('_p_jar')
- _p_oid = _p_oid_or_jar_Descr('_p_oid')
- _p_changed = _p_ChangedDescr()
- _p_serial = _p_DataDescr('_p_serial')
+ # For weird reasons having to do with restrictions on built-in
+ # types, we can't subclass
+ # ZODB.persistentclass.PersistentMetaClass, so we do the next best
+ # thing:
+ for name in ('_p_jar', '_p_oid', '_p_changed', '_p_serial',
+ '__getnewargs__', '_p_maybeupdate', '_p_deactivate',
+ '_p_invalidate', '__getstate__', '_p_activate', ):
+ locals()[name] = ZODB.persistentclass.PersistentMetaClass.__dict__[
+ name]
+
def __new__(self, name, bases, cdict, _p_changed=False):
# _p_changed will be None if we are being loaded from the
@@ -168,46 +56,15 @@
ExtensionClass.pmc_init_of(result)
return result
- def __getnewargs__(self):
- return self.__name__, self.__bases__, {}, None
-
- __getnewargs__ = _p_MethodDescr(__getnewargs__)
-
def __setattr__(self, name, v):
if not ((name.startswith('_p_') or name.startswith('_v'))):
- _p_maybeupdate(self, name)
+ self._p_maybeupdate(name)
super(ZClassPersistentMetaClass, self).__setattr__(name, v)
def __delattr__(self, name):
if not ((name.startswith('_p_') or name.startswith('_v'))):
- _p_maybeupdate(self, name)
+ self._p_maybeupdate(name)
super(ZClassPersistentMetaClass, self).__delattr__(name)
-
- def _p_deactivate(self):
- # persistent classes can't be ghosts
- pass
-
- _p_deactivate = _p_MethodDescr(_p_deactivate)
-
- def _p_invalidate(self):
- # reset state
- self._p_class_dict['_p_changed'] = None
- self._p_jar.setstate(self)
-
- _p_invalidate = _p_MethodDescr(_p_invalidate)
-
-
- def __getstate__(self):
- return (self.__bases__,
- dict([(k, v) for (k, v) in self.__dict__.items()
- if not (k.startswith('_p_')
- or k.startswith('_v_')
- or k in special_class_descrs
- )
- ]),
- )
-
- __getstate__ = _p_MethodDescr(__getstate__)
def __setstate__(self, state):
try:
@@ -224,13 +81,14 @@
_p_class_dict = self._p_class_dict
self._p_class_dict = {}
- to_remove = [k for k in self.__dict__
- if ((k not in cdict)
- and
- (k not in special_class_descrs)
- and
- (k != '_p_class_dict')
- )]
+ to_remove = [
+ k for k in self.__dict__
+ if ((k not in cdict)
+ and
+ (k not in ZODB.persistentclass.special_class_descrs)
+ and
+ (k != '_p_class_dict')
+ )]
for k in to_remove:
delattr(self, k)
@@ -244,9 +102,4 @@
self._p_changed = False
- __setstate__ = _p_MethodDescr(__setstate__)
-
- def _p_activate(self):
- self._p_jar.setstate(self)
-
- _p_activate = _p_MethodDescr(_p_activate)
+ __setstate__ = ZODB.persistentclass._p_MethodDescr(__setstate__)
More information about the Zope-Checkins
mailing list