diff options
author | Guido van Rossum <guido@python.org> | 1997-12-10 23:40:18 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1997-12-10 23:40:18 (GMT) |
commit | d1f4984a9bb2e90d4fc473be1a169917277efa4d (patch) | |
tree | 982f832ef006fbd566ff1807911b55e925e3e0dc | |
parent | 79f016a262bfc287e0a617a65290b0b71c8936c2 (diff) | |
download | cpython-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.
-rw-r--r-- | Lib/pickle.py | 17 |
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 |