[Zope-Checkins] CVS: Zope/lib/python/ZODB - serialize.py:1.4

Jeremy Hylton jeremy at zope.com
Thu Feb 19 13:12:32 EST 2004


Update of /cvs-repository/Zope/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv18604/lib/python/ZODB

Modified Files:
	serialize.py 
Log Message:
Backport Fred's recent changes from the branch.

- inline getClassMetadata() into serialize()
- get __getnewargs__() from the object instance, not the class, since
  the PersistentClassMetaClass does things strangely


=== Zope/lib/python/ZODB/serialize.py 1.3 => 1.4 ===
--- Zope/lib/python/ZODB/serialize.py:1.3	Wed Feb 18 21:59:06 2004
+++ Zope/lib/python/ZODB/serialize.py	Thu Feb 19 13:12:32 2004
@@ -76,17 +76,6 @@
     """
     return getattr(obj, name, _marker) is not _marker
 
-def getClassMetadata(obj):
-
-    # We don't use __class__ here, because obj could be a persistent proxy.
-    # We don't want to be folled by proxies.
-    klass = type(obj)
-
-    newargs = getattr(klass, "__getnewargs__", None)
-    if newargs is None:
-        return klass
-    else:
-        return klass, newargs(obj)
 
 class BaseObjectWriter:
     """Serializes objects for storage in the database.
@@ -105,8 +94,84 @@
             assert myhasattr(jar, "new_oid")
         self._jar = jar
 
-
     def persistent_id(self, obj):
+        """Return the persistent id for obj.
+
+        >>> from ZODB.tests.util import P
+        >>> class DummyJar:
+        ...     def new_oid(self):
+        ...         return 42
+        >>> jar = DummyJar()
+        >>> writer = BaseObjectWriter(jar)
+
+        Normally, object references include the oid and a cached
+        reference to the class.  Having the class available allows
+        fast creation of the ghost, avoiding requiring an additional
+        database lookup.
+
+        >>> bob = P('bob')
+        >>> oid, cls = writer.persistent_id(bob)
+        >>> oid
+        42
+        >>> cls is P
+        True
+
+        If a persistent object does not already have an oid and jar,
+        these will be assigned by persistent_id():
+
+        >>> bob._p_oid
+        42
+        >>> bob._p_jar is jar
+        True
+
+        If the object already has a persistent id, it is not changed:
+
+        >>> bob._p_oid = 24
+        >>> oid, cls = writer.persistent_id(bob)
+        >>> oid
+        24
+        >>> cls is P
+        True
+
+        If the jar doesn't match that of the writer, an error is raised:
+
+        >>> bob._p_jar = DummyJar()
+        >>> writer.persistent_id(bob)
+        Traceback (most recent call last):
+          ...
+        InvalidObjectReference: Attempt to store an object from a """ \
+               """foreign database connection
+
+        Constructor arguments used by __new__(), as returned by
+        __getnewargs__(), can affect memory allocation, but also may
+        change over the life of the object.  This makes it useless to
+        cache even the object's class.
+
+        >>> class PNewArgs(P):
+        ...     def __getnewargs__(self):
+        ...         return ()
+
+        >>> sam = PNewArgs('sam')
+        >>> writer.persistent_id(sam)
+        42
+        >>> sam._p_oid
+        42
+        >>> sam._p_jar is jar
+        True
+
+        Check that simple objects don't get accused of persistence:
+
+        >>> writer.persistent_id(42)
+        >>> writer.persistent_id(object())
+
+        Check that a classic class doesn't get identified improperly:
+
+        >>> class ClassicClara:
+        ...    pass
+        >>> clara = ClassicClara()
+
+        >>> writer.persistent_id(clara)
+        """
 
         # Most objects are not persistent. The following cheap test
         # identifies most of them.  For these, we return None,
@@ -179,7 +244,18 @@
         return oid, klass
 
     def serialize(self, obj):
-        return self._dump(getClassMetadata(obj), obj.__getstate__())
+        # We don't use __class__ here, because obj could be a persistent proxy.
+        # We don't want to be folled by proxies.
+        klass = type(obj)
+
+        newargs = getattr(obj, "__getnewargs__", None)
+        if newargs is None:
+            meta = klass
+        else:
+            print "newargs", repr(newargs)
+            meta = klass, newargs()
+
+        return self._dump(meta, obj.__getstate__())
 
     def _dump(self, classmeta, state):
         # To reuse the existing cStringIO object, we must reset




More information about the Zope-Checkins mailing list