[Zope3-checkins] CVS: Zope3/lib/python/Persistence - Class.py:1.8

Jeremy Hylton jeremy@zope.com
Fri, 22 Nov 2002 11:33:31 -0500


Update of /cvs-repository/Zope3/lib/python/Persistence
In directory cvs.zope.org:/tmp/cvs-serv8260/Persistence

Modified Files:
	Class.py 
Log Message:
Write __newstate__() that works correctly with 2.2.2.
Re-enable testClassUpdate().

(The current 2.3 has a bug that allowed the old version to work by
accident.)


=== Zope3/lib/python/Persistence/Class.py 1.7 => 1.8 ===
--- Zope3/lib/python/Persistence/Class.py:1.7	Fri Nov 22 00:33:58 2002
+++ Zope3/lib/python/Persistence/Class.py	Fri Nov 22 11:33:29 2002
@@ -290,11 +290,24 @@
         for k, v in dict.items():
             setattr(cls, k, v)
 
-    # XXX hack method to support update in place
-
     def __newstate__(cls, acls):
-        cls.__dict__.clear()
-        cls.__dict__.update(acls.__dict__)
+        # Update a class's __dict__ in place.  Must use setattr and
+        # delattr because __dict__ is a read-only proxy.
+        # XXX This doesn't handle __methods__ correctly.
+        def getkeys(cls):
+            L = [n for n in cls.__dict__.keys()
+                 if not (n.startswith("__") and n.endswith("__"))]
+            d = {}
+            for elt in L:
+                d[elt] = True
+            return d
+        oldnames = getkeys(cls)
+        newnames = getkeys(acls)
+        for name in oldnames:
+            if not name in newnames:
+                delattr(cls, name)
+        for name in newnames:
+            setattr(cls, name, acls.__dict__[name])
 
     def _p_deactivate(cls):
         # do nothing but mark the state change for now