mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
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.
This commit is contained in:
parent
79f016a262
commit
d1f4984a9b
1 changed files with 12 additions and 5 deletions
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue