summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1997-12-10 23:40:18 (GMT)
committerGuido van Rossum <guido@python.org>1997-12-10 23:40:18 (GMT)
commitd1f4984a9bb2e90d4fc473be1a169917277efa4d (patch)
tree982f832ef006fbd566ff1807911b55e925e3e0dc /Lib
parent79f016a262bfc287e0a617a65290b0b71c8936c2 (diff)
downloadcpython-d1f4984a9bb2e90d4fc473be1a169917277efa4d.zip
cpython-d1f4984a9bb2e90d4fc473be1a169917277efa4d.tar.gz
cpython-d1f4984a9bb2e90d4fc473be1a169917277efa4d.tar.bz2
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.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/pickle.py17
1 files changed, 12 insertions, 5 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py
index 2ec9a43..4644ee9 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -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