[Zodb-checkins] CVS: Zope3/src/zodb/code - patch.py:1.6

Jeremy Hylton jeremy@zope.com
Tue, 28 Jan 2003 14:24:15 -0500


Update of /cvs-repository/Zope3/src/zodb/code
In directory cvs.zope.org:/tmp/cvs-serv14258/zodb/code

Modified Files:
	patch.py 
Log Message:
Fix patch so that it doesn't touch foreign objects.

If a persistent module imports an object from some other module, it
shouldn't be converted to a persistent object.  Add tests for
functions, classes, and interfaces.


=== Zope3/src/zodb/code/patch.py 1.5 => 1.6 ===
--- Zope3/src/zodb/code/patch.py:1.5	Fri Jan 24 18:20:56 2003
+++ Zope3/src/zodb/code/patch.py	Tue Jan 28 14:23:42 2003
@@ -175,6 +175,7 @@
         self._pmemo = memo
         self._wrapped = {} # set of objects already wrapped
         self._module = module
+        self._module_name = module.__name__
         self._repl = replacements
         self._builtins = module.__builtins__
 
@@ -205,40 +206,46 @@
             return oid
 
     def save_type(self, atype):
-        if atype.__module__ == "__builtin__":
-            self.save_global(atype)
-        else:
-            d = id(atype)
+        if atype.__module__ == self._module_name:
             self.save_reduce(self.wrap(TypeWrapper, atype),
                              (atype.__bases__, atype.__dict__))
             memo_len = len(self.memo)
             self.write(self.put(memo_len))
-            self.memo[d] = memo_len, None
+            self.memo[id(atype)] = memo_len, None
+        else:
+            self.save_global(atype)
 
     dispatch[TypeType] = save_type
     dispatch[ClassType] = save_type
 
     def save_function(self, func):
-        d = id(func)
-        self.save_reduce(self.wrap(FunctionWrapper, func),
-                         (func.func_defaults, func.func_dict))
-        memo_len = len(self.memo)
-        self.write(self.put(memo_len))
-        self.memo[d] = memo_len, None
+        if pickle.whichmodule(func, func.__name__) == "__main__":
+            self.save_reduce(self.wrap(FunctionWrapper, func),
+                             (func.func_defaults, func.func_dict))
+            memo_len = len(self.memo)
+            self.write(self.put(memo_len))
+            self.memo[id(func)] = memo_len, None
+        else:
+            self.save_global(func)
 
     dispatch[FunctionType] = save_function
 
     external = {}
 
     def save_external(self, obj):
-        # Save an external type registered through registerWrapper
-        objtype = type(obj)
-        wrapper, unwrap_thunk = self.external[objtype]
-        d = id(obj)
-        self.save_reduce(self.wrap(wrapper, obj), unwrap_thunk(obj))
-        memo_len = len(self.memo)
-        self.write(self.put(memo_len))
-        self.memo[d] = memo_len, None
+        # XXX Will this object always have an __module__?
+        if obj.__module__ == self._module_name:
+            # Save an external type registered through registerWrapper
+            objtype = type(obj)
+            wrapper, unwrap_thunk = self.external[objtype]
+            self.save_reduce(self.wrap(wrapper, obj), unwrap_thunk(obj))
+            memo_len = len(self.memo)
+            self.write(self.put(memo_len))
+            self.memo[id(obj)] = memo_len, None
+        else:
+            # In general, we don't know how to pickle this object,
+            # so pickle it by reference to the original.
+            self.save_pers(self.persistent_id(obj, True))
 
     # New-style classes don't have real dicts.  They have dictproxies.
     # There's no official way to spell the dictproxy type, so we have
@@ -332,7 +339,6 @@
         self._pmemo = pmemo
 
     def persistent_load(self, oid):
-##        return self._pmemo[int(oid)]
         return self._pmemo[oid]
 
 class NameFinder: