]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Jim Fulton writes:
authorGuido van Rossum <guido@python.org>
Wed, 10 Dec 1997 23:40:18 +0000 (23:40 +0000)
committerGuido van Rossum <guido@python.org>
Wed, 10 Dec 1997 23:40:18 +0000 (23:40 +0000)
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

index 2ec9a4351fe6ee53fb64d526300176aeb453569b..4644ee9b53034e8901f72465354d45796601071b 100644 (file)
@@ -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