Pass the object to save_reduce(), so the memoize() call can go into

save_reduce(), before the state is pickled.  This makes it possible
for an object to be referenced from its own (mutable) state.
This commit is contained in:
Guido van Rossum 2003-01-31 17:17:49 +00:00
parent d053b4b416
commit f7f4517fae
1 changed files with 8 additions and 3 deletions

View File

@ -329,8 +329,7 @@ class Pickler:
"exactly two or three elements" % reduce) "exactly two or three elements" % reduce)
# Save the reduce() output and finally memoize the object # Save the reduce() output and finally memoize the object
self.save_reduce(func, args, state) self.save_reduce(func, args, state, obj)
self.memoize(obj)
def persistent_id(self, obj): def persistent_id(self, obj):
# This exists so a subclass can override it # This exists so a subclass can override it
@ -344,7 +343,7 @@ class Pickler:
else: else:
self.write(PERSID + str(pid) + '\n') self.write(PERSID + str(pid) + '\n')
def save_reduce(self, func, args, state=None): def save_reduce(self, func, args, state=None, obj=None):
# This API is be called by some subclasses # This API is be called by some subclasses
# Assert that args is a tuple or None # Assert that args is a tuple or None
@ -397,6 +396,9 @@ class Pickler:
if not hasattr(cls, "__new__"): if not hasattr(cls, "__new__"):
raise PicklingError( raise PicklingError(
"args[0] from __newobj__ args has no __new__") "args[0] from __newobj__ args has no __new__")
if obj is not None and cls is not obj.__class__:
raise PicklingError(
"args[0] from __newobj__ args has the wrong class")
args = args[1:] args = args[1:]
save(cls) save(cls)
save(args) save(args)
@ -406,6 +408,9 @@ class Pickler:
save(args) save(args)
write(REDUCE) write(REDUCE)
if obj is not None:
self.memoize(obj)
if state is not None: if state is not None:
save(state) save(state)
write(BUILD) write(BUILD)