From d1f4984a9bb2e90d4fc473be1a169917277efa4d Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 10 Dec 1997 23:40:18 +0000 Subject: [PATCH] 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. --- Lib/pickle.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Lib/pickle.py b/Lib/pickle.py index 2ec9a4351f..4644ee9b53 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 -- 2.50.1