mirror of
https://github.com/python/cpython.git
synced 2025-12-23 09:19:18 +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)
|
self.write(STOP)
|
||||||
|
|
||||||
def dump_special(self, callable, args, state = None):
|
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 " \
|
raise PicklingError, "Second argument to dump_special " \
|
||||||
"must be a tuple"
|
"must be a tuple"
|
||||||
|
|
||||||
|
|
@ -162,6 +162,10 @@ class Pickler:
|
||||||
else:
|
else:
|
||||||
tup = reduce(object)
|
tup = reduce(object)
|
||||||
|
|
||||||
|
if type(tup) is StringType:
|
||||||
|
self.save_global(object, tup)
|
||||||
|
return
|
||||||
|
|
||||||
if (type(tup) is not TupleType):
|
if (type(tup) is not TupleType):
|
||||||
raise PicklingError, "Value returned by %s must be a " \
|
raise PicklingError, "Value returned by %s must be a " \
|
||||||
"tuple" % reduce
|
"tuple" % reduce
|
||||||
|
|
@ -180,7 +184,7 @@ class Pickler:
|
||||||
else:
|
else:
|
||||||
state = None
|
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 " \
|
raise PicklingError, "Second element of tuple returned " \
|
||||||
"by %s must be a tuple" % reduce
|
"by %s must be a tuple" % reduce
|
||||||
|
|
||||||
|
|
@ -648,8 +652,8 @@ class Unpickler:
|
||||||
arg_tup = stack[-1]
|
arg_tup = stack[-1]
|
||||||
del stack[-2:]
|
del stack[-2:]
|
||||||
|
|
||||||
if (type(callable) is not ClassType):
|
if type(callable) is not ClassType:
|
||||||
if (not safe_constructors.has_key(callable)):
|
if not safe_constructors.has_key(callable):
|
||||||
try:
|
try:
|
||||||
safe = callable.__safe_for_unpickling__
|
safe = callable.__safe_for_unpickling__
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|
@ -659,7 +663,10 @@ class Unpickler:
|
||||||
raise UnpicklingError, "%s is not safe for " \
|
raise UnpicklingError, "%s is not safe for " \
|
||||||
"unpickling" % callable
|
"unpickling" % callable
|
||||||
|
|
||||||
value = apply(callable, arg_tup)
|
if arg_tup is None:
|
||||||
|
value = callable.__basicnew__()
|
||||||
|
else:
|
||||||
|
value = apply(callable, arg_tup)
|
||||||
self.append(value)
|
self.append(value)
|
||||||
dispatch[REDUCE] = load_reduce
|
dispatch[REDUCE] = load_reduce
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue