summaryrefslogtreecommitdiffstats
path: root/Lib/pickle.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-01-30 05:39:04 (GMT)
committerGuido van Rossum <guido@python.org>2003-01-30 05:39:04 (GMT)
commit45486176ea14884400188c604d5d3488f803ff2d (patch)
tree1d1015f4e7e6ea85999653e054404a8d39399852 /Lib/pickle.py
parent301eb71fb9fe45eabdf50763a28925c746403100 (diff)
downloadcpython-45486176ea14884400188c604d5d3488f803ff2d.zip
cpython-45486176ea14884400188c604d5d3488f803ff2d.tar.gz
cpython-45486176ea14884400188c604d5d3488f803ff2d.tar.bz2
In save_newobj(), if an object's __getnewargs__ and __getstate__ are
the same function, don't save the state or write a BUILD opcode. This is so that a type (e.g. datetime :-) can support protocol 2 using __getnewargs__ while also supporting protocol 0 and 1 using __getstate__. (Without this, the state would be pickled twice with protocol 2, unless __getstate__ is defined to return None, which breaks protocol 0 and 1.)
Diffstat (limited to 'Lib/pickle.py')
-rw-r--r--Lib/pickle.py23
1 files changed, 23 insertions, 0 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py
index 9630d33..d62a5bd 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -416,6 +416,29 @@ class Pickler:
write(SETITEM)
getstate = getattr(obj, "__getstate__", None)
+
+ # A class may define both __getstate__ and __getnewargs__.
+ # If they are the same function, we ignore __getstate__.
+ # This is for the benefit of protocols 0 and 1, which don't
+ # use __getnewargs__. Note that the only way to make them
+ # the same function is something like this:
+ #
+ # class C(object):
+ # def __getstate__(self):
+ # return ...
+ # __getnewargs__ = __getstate__
+ #
+ # No tricks are needed to ignore __setstate__; it simply
+ # won't be called when we don't generate BUILD.
+ # Also note that when __getnewargs__ and __getstate__ are
+ # the same function, we don't do the default thing of
+ # looking for __dict__ and slots either -- it is assumed
+ # that __getnewargs__ returns all the state there is
+ # (which should be a safe assumption since __getstate__
+ # returns the *same* state).
+ if getstate and getstate == getnewargs:
+ return
+
if getstate:
try:
state = getstate()