classification
Title: deepcopy erroneously doesn't call __setstate__ if __getstate__ returns empty dict
Type: behavior Stage:
Components: Library (Lib) Versions: Python 2.5
process
Status: pending Resolution: works for me
Dependencies: Superseder:
Assigned To: Nosy List: amaury.forgeotdarc, shauncutts (2)
Priority: Keywords

Created on 2009-09-02 21:29 by shauncutts, last changed 2009-09-03 11:30 by amaury.forgeotdarc.

Files
File name Uploaded Description Edit Remove
deepcopy_bug.py shauncutts, 2009-09-02 21:29 Gives example showing bug
Messages (2)
msg92186 - (view) Author: Shaun Cutts (shauncutts) Date: 2009-09-02 21:29
Line 335 of copy.py guards call to __setstate__ with

if state:
    ...

However, __getstate__ may legitimately return an empty dictionary even
if __setstate__ still needs to be called. For example,
__setstate__/__getstate__ pair may not want to "persist" default values
(as is the case for me).

The fix would be to change this line to (e.g.):

if state is not None:
    ...
msg92200 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) Date: 2009-09-03 11:30
This is precisely documented here:
http://docs.python.org/library/pickle.html#object.__setstate__
"Note: For new-style classes, if __getstate__() returns a false value,
the __setstate__() method will not be called."

If you want some default value even when the state is empty, you could
set it in the __new__ method:
[__new__ is always called, but __init__ is skipped by the copy protocol]

class A(object):
    def __new__(cls):
        self = super(cls, A).__new__(cls)
        self.a = 1
        return self
    def __setstate__(self, d):
        self.__dict__.update(d)
    def __getstate__(self):
        d = self.__dict__.copy()
        d.pop('a')
        return d

The __setstate__ is even not necessary here, since it implements the
default behaviour.
History
Date User Action Args
2009-09-03 11:30:54amaury.forgeotdarcsetstatus: open -> pending

nosy: + amaury.forgeotdarc
messages: + msg92200

resolution: works for me
2009-09-02 21:29:51shauncuttscreate