Commit d1f4984a authored by Guido van Rossum's avatar Guido van Rossum

Jim Fulton writes:

The attached patch adds the following behavior to the handling
of REDUCE codes:

- A user-defined type may have a __reduce__ method that returns
  a string rather than a tuple, in which case the object is
  saved as a global object with a name given by the string returned
  by reduce.

  This was a feature added to cPickle a long time ago.


- User-defined types can now support unpickling without
  executing a constructor.

  The second value returned from '__reduce__' can now be None,
  rather than an argument tuple.  On unpickling, if the
  second value returned from '__reduce__' during pickling was
  None, then rather than calling the first value returned from
  '__reduce__', directly, the '__basicnew__' method of the
  first value returned from '__reduce__' is called without
  arguments.

I also got rid of a few of Chris' extra ()s, which he used
to make python ifs look like C ifs.
parent 79f016a2
......@@ -89,7 +89,7 @@ class Pickler:
self.write(STOP)
def dump_special(self, callable, args, state = None):
if (type(args) is not TupleType):
if type(args) is not TupleType and args is not None:
raise PicklingError, "Second argument to dump_special " \
"must be a tuple"
......@@ -162,6 +162,10 @@ class Pickler:
else:
tup = reduce(object)
if type(tup) is StringType:
self.save_global(object, tup)
return
if (type(tup) is not TupleType):
raise PicklingError, "Value returned by %s must be a " \
"tuple" % reduce
......@@ -180,7 +184,7 @@ class Pickler:
else:
state = None
if (type(arg_tup) is not TupleType):
if type(arg_tup) is not TupleType and arg_tup is not None:
raise PicklingError, "Second element of tuple returned " \
"by %s must be a tuple" % reduce
......@@ -648,8 +652,8 @@ class Unpickler:
arg_tup = stack[-1]
del stack[-2:]
if (type(callable) is not ClassType):
if (not safe_constructors.has_key(callable)):
if type(callable) is not ClassType:
if not safe_constructors.has_key(callable):
try:
safe = callable.__safe_for_unpickling__
except AttributeError:
......@@ -659,7 +663,10 @@ class Unpickler:
raise UnpicklingError, "%s is not safe for " \
"unpickling" % callable
value = apply(callable, arg_tup)
if arg_tup is None:
value = callable.__basicnew__()
else:
value = apply(callable, arg_tup)
self.append(value)
dispatch[REDUCE] = load_reduce
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment