[Zodb-checkins] CVS: Zope3/src/zodb/code - patch.py:1.4.2.1
Jeremy Hylton
jeremy@zope.com
Tue, 21 Jan 2003 18:10:35 -0500
Update of /cvs-repository/Zope3/src/zodb/code
In directory cvs.zope.org:/tmp/cvs-serv7423
Modified Files:
Tag: new-pickle-branch
patch.py
Log Message:
Fix persistent_id() used for patching.
If a persistent object has been newly created it's _p_oid will be
None. So the getattr() default value of None isn't a good test. Use
an explicit object() for the default instead and make up an
unforgeable oid for the object.
=== Zope3/src/zodb/code/patch.py 1.4 => 1.4.2.1 ===
--- Zope3/src/zodb/code/patch.py:1.4 Mon Dec 30 19:15:58 2002
+++ Zope3/src/zodb/code/patch.py Tue Jan 21 18:10:33 2003
@@ -143,6 +143,8 @@
return PersistentClassMetaClass(self._obj.__name__, newbases, dict)
+marker = object()
+
class Pickler(pickle.Pickler):
dispatch = {}
@@ -155,13 +157,13 @@
self._repl = replacements
self._builtins = module.__builtins__
- def wrap(self, wrapperclass, object):
- return wrapperclass(object, self._module, self._repl.get(id(object)))
+ def wrap(self, wrapperclass, obj):
+ return wrapperclass(obj, self._module, self._repl.get(id(obj)))
- def persistent_id(self, object, force=False):
- if isinstance(object, Wrapper) or object is self._builtins or force:
- oid = id(object)
- self._pmemo[oid] = object
+ def persistent_id(self, obj, force=False):
+ if isinstance(obj, Wrapper) or obj is self._builtins or force:
+ oid = id(obj)
+ self._pmemo[oid] = obj
return oid
else:
# If the object is a real persistent object, patch it by
@@ -172,10 +174,13 @@
# doesn't use sys.modules.
# XXX Is this safe in all cases?
- oid = getattr(object, "_p_oid", None)
- if oid is None:
+ oid = getattr(obj, "_p_oid", marker)
+ if oid is marker:
return None
- self._pmemo[oid] = object
+ elif oid is None:
+ # It's a persistent object, but it's newly created.
+ oid = object()
+ self._pmemo[oid] = obj
return oid
def save_type(self, atype):
@@ -199,7 +204,7 @@
# to get it by using type() on an example.
dispatch[type(Wrapper.__dict__)] = pickle.Pickler.save_dict
- def save(self, object, ignore=None):
+ def save(self, obj, ignore=None):
# Override the save() implementation from pickle.py, because
# we don't ever want to invoke __reduce__() on builtin types
# that aren't picklable. Instead, we'd like to pickle all of
@@ -209,18 +214,18 @@
# The ignored parameter is for compatible with Python 2.2,
# which has the old inst_persistent_id feature.
- pid = self.persistent_id(object)
+ pid = self.persistent_id(obj)
if pid is not None:
self.save_pers(pid)
return
- d = id(object)
- t = type(object)
- if (t is TupleType) and (len(object) == 0):
+ d = id(obj)
+ t = type(obj)
+ if (t is TupleType) and (len(obj) == 0):
if self.bin:
- self.save_empty_tuple(object)
+ self.save_empty_tuple(obj)
else:
- self.save_tuple(object)
+ self.save_tuple(obj)
return
if d in self.memo:
@@ -235,19 +240,19 @@
except TypeError: # t is not a class
issc = 0
if issc:
- self.save_global(object)
+ self.save_global(obj)
return
try:
reduce = dispatch_table[t]
except KeyError:
- self.save_pers(self.persistent_id(object, True))
+ self.save_pers(self.persistent_id(obj, True))
return
else:
- tup = reduce(object)
+ tup = reduce(obj)
if type(tup) is StringType:
- self.save_global(object, tup)
+ self.save_global(obj, tup)
return
if type(tup) is not TupleType:
raise pickle.PicklingError("Value returned by %s must be a "
@@ -274,10 +279,10 @@
self.save_reduce(callable, arg_tup, state)
memo_len = len(self.memo)
self.write(self.put(memo_len))
- self.memo[d] = (memo_len, object)
+ self.memo[d] = (memo_len, obj)
return
- f(self, object)
+ f(self, obj)
class Unpickler(pickle.Unpickler):