mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
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.)
This commit is contained in:
parent
301eb71fb9
commit
45486176ea
1 changed files with 23 additions and 0 deletions
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue