Cleared up the XXX comments I added earlier today, and fixed some

additional typos.
This commit is contained in:
Tim Peters 2003-02-11 04:50:59 +00:00
parent 5b6409adaf
commit 1264fe2202
1 changed files with 74 additions and 56 deletions

View File

@ -183,8 +183,8 @@ Extended __reduce__ API
Unpickling invokes function(*arguments) to create an initial object,
called obj below. If the remaining items are left off, that's the end
of unpickling and obj is the result. Else obj is modified at
unpickling time by each item specified, as follows.
of unpickling for this object and obj is the result. Else obj is
modified at unpickling time by each item specified, as follows.
state Optional.
Additional state. If this is not None, the state is
@ -367,55 +367,66 @@ Case 2: pickling new-style class instances using protocols 0 or 1
name in that module) is substituted.
The default __reduce__ implementation will fail at pickling time
for built-in types not mentioned above.
for built-in types not mentioned above, and for new-style classes
implemented in C: if they want to be picklable, they must supply
a custom __reduce__ implementation under protocols 0 and 1.
For new-style classes implemented in Python, the default
__reduce__ implementation works as follows:
XXX We seem to be missing a section for new-style classes implemented
XXX in C.
__reduce__ implementation (copy_reg._reduce) works as follows:
Let D be the class on the object to be pickled. First, find the
nearest base class that is implemented in C (either as a
built-in type or as a type defined by an extension class). Call
this base class B, and the class of the object to be pickled D.
Unless B is the class 'object', instances of class B must be
picklable, either by having built-in support (as defined in the
above three bullet points), or by having a non-default
__reduce__ implementation. B must not be the same class as D
(if it were, it would mean that D is not implemented in Python).
Let D be the class on the object to be pickled. First, find the
nearest base class that is implemented in C (either as a
built-in type or as a type defined by an extension class). Call
this base class B, and the class of the object to be pickled D.
Unless B is the class 'object', instances of class B must be
picklable, either by having built-in support (as defined in the
above three bullet points), or by having a non-default
__reduce__ implementation. B must not be the same class as D
(if it were, it would mean that D is not implemented in Python).
The new object is created at unpickling time using the following
code:
The callable produced by the default __reduce__ is
copy_reg._reconstructor, and its arguments tuple is
(D, B, basestate), where basestate is None if B is the builtin
object class, and basestate is
obj = B.__new__(D, state)
B.__init__(obj, state)
basestate = B(obj)
where state is a value computed at pickling time as follows:
if B is not the builtin object class. This is geared toward
pickling subclasses of builtin types, where, for example,
list(some_list_subclass_instance) produces "the list part" of
the list subclass instance.
state = B(obj)
The object is recreated at unpickling time by
copy_reg._reconstructor, like so:
XXX How does the above relate to the steps explained earlier for
XXX __reduce__? For example, what here corresponds to the earlier
XXX description's function(*arguments) step?
obj = B.__new__(D, basestate)
B.__init__(obj, basestate)
XXX Below, does __getstate__() customization replace the source of
XXX the value called "state" just above, or is this customization a
XXX distinct step?
Objects for which this default __reduce__ implementation is used
can customize it by defining __getstate__ and/or __setstate__
methods. These work almost the same as described for classic
classes above, except that if __getstate__ returns an object (of
any type) whose value is considered false (e.g. None, or a number
that is zero, or an empty sequence or mapping), this state is not
pickled and __setstate__ will not be called at all.
Objects using the default __reduce__ implementation can customize
it by defining __getstate__ and/or __setstate__ methods. These
work almost the same as described for classic classes above, except
that if __getstate__ returns an object (of any type) whose value is
considered false (e.g. None, or a number that is zero, or an empty
sequence or mapping), this state is not pickled and __setstate__
will not be called at all. If __getstate__ exists and returns a
true value, that value becomes the third element of the tuple
returned by the default __reduce__, and at unpickling time the
value is passed to __setstate__. If __getstate__ does not exist,
but obj.__dict__ exists, then obj.__dict__ becomes the third
element of the tuple returned by __reduce__, and again at
unpickling time the value is passed to obj.__setstate__. The
default __setstate__ is the same as that for classic classes,
described above.
Note that this strategy ignores slots. Instances of new-style
classes that have slots but no __getstate__ method cannot be
pickled by protocols 0 and 1; the code explicitly checks for
this condition.
XXX Is it the case that "pickling new-style class instances using
XXX protocols 0 or 1" ignores __getinitargs__?
Note that pickling new-style class instances ignores __getinitargs__
if it exists (and under all protocols). __getinitargs__ is
useful only for classic classes.
Case 3: pickling new-style class instances using protocol 2
@ -423,12 +434,15 @@ Case 3: pickling new-style class instances using protocol 2
from the 'object' base class is *ignored*. Instead, a different
default implementation is used, which allows more efficient
pickling of new-style class instances than possible with protocols
0 or 1, at the cost of backward incompatibility with Python 2.2.
0 or 1, at the cost of backward incompatibility with Python 2.2
(meaning no more than that a protocol 2 pickle cannot be unpickled
before Python 2.3).
The customization uses three special methods: __getstate__,
__setstate__ and __getnewargs__. It is fine if a class implements
one or more but not all of these, as long as it is compatible with
the default implementations.
__setstate__ and __getnewargs__ (note that __getinitargs__ is again
ignored). It is fine if a class implements one or more but not all
of these, as long as it is compatible with the default
implementations.
The __getstate__ method
@ -443,20 +457,20 @@ Case 3: pickling new-style class instances using protocol 2
But if a new-style class's __getstate__ returns None, its
__setstate__ won't be called at all as part of unpickling.
If no __getstate__ method exists, a default state is assumed.
If no __getstate__ method exists, a default state is computed.
There are several cases:
- For a new-style class that has no instance __dict__ and no
__slots__, the default state is None.
- For a new-style class that has an instance __dict__ and no
__slots__, the default state is self.__dict__.
- For a new-style class that has no instance __dict__ and no
__slots__, the default __state__ is None.
- For a new-style class that has an instance __dict__ and
__slots__, the default state is a tuple consisting of two
dictionaries: the first being self.__dict__, and the second
being a dictionary mapping slot names to slot values. Only
slots that have a value are included in the latter.
dictionaries: self.__dict__, and a dictionary mapping slot
names to slot values. Only slots that have a value are
included in the latter.
- For a new-style class that has __slots__ and no instance
__dict__, the default state is a tuple whose first item is
@ -465,9 +479,10 @@ Case 3: pickling new-style class instances using protocol 2
The __setstate__ method
The __setstate__ should take one argument; it will be called
with the value returned by __getstate__ or with the default
state described above if no __setstate__ method is defined.
The __setstate__ method should take one argument; it will be
called with the value returned by __getstate__ or with the
default state described above if no __getstate__ method is
defined.
If no __setstate__ method exists, a default implementation is
provided that can handle the state returned by the default
@ -484,10 +499,11 @@ Case 3: pickling new-style class instances using protocol 2
obj = C.__new__(C, *args)
where args is either the empty tuple, or the tuple returned by
the __getnewargs__ method, if defined. __getnewargs__ must
return a tuple. The absence of a __getnewargs__ method is
equivalent to the existence of one that returns ().
where C is the class of the pickled object, and args is either
the empty tuple, or the tuple returned by the __getnewargs__
method, if defined. __getnewargs__ must return a tuple. The
absence of a __getnewargs__ method is equivalent to the existence
of one that returns ().
The __newobj__ unpickling function
@ -672,7 +688,7 @@ The copy module
Pickling Python longs
Pickling and unpickling Python longs takes time quadratic in
the number of digits, in protocols 1 and 2. Under protocol 2,
the number of digits, in protocols 0 and 1. Under protocol 2,
new opcodes support linear-time pickling and unpickling of longs.
@ -681,7 +697,9 @@ Pickling bools
Protocol 2 introduces new opcodes for pickling True and False
directly. Under protocols 0 and 1, bools are pickled as integers,
using a trick in the representation of the integer in the pickle
so that an unpickler can recognize that a bool was intended.
so that an unpickler can recognize that a bool was intended. That
trick consumed 4 bytes per bool pickled. The new bool opcodes
consume 1 byte per bool.
Pickling small tuples