Issue 628925: pickle won't dump instances after reload (original) (raw)

The fix for bug http://python.org/sf/451547 has made the follow sequence fail:

import pickle, copy o = copy._EmptyClass() reload(copy) <module 'copy' from '/usr/lib/python2.2/copy.pyc'> pickle.dumps(o, 1) Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.2/pickle.py", line 978, in dumps Pickler(file, bin).dump(object) File "/usr/lib/python2.2/pickle.py", line 115, in dump self.save(object) File "/usr/lib/python2.2/pickle.py", line 225, in save f(self, object) File "/usr/lib/python2.2/pickle.py", line 477, in save_inst save(cls) File "/usr/lib/python2.2/pickle.py", line 225, in save f(self, object) File "/usr/lib/python2.2/pickle.py", line 524, in save_global raise PicklingError( pickle.PicklingError: Can't pickle <class copy._EmptyClass at 0x819478c>: it's not the same object as copy._EmptyClass

Looking at bug 451547 the reported problem was that pickle would allow you to dump lambdas. When you try to dump lambdas you now see the following:

f = lambda x: x in (1,2,3) s = pickle.dumps(f, 1) Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.2/pickle.py", line 978, in dumps Pickler(file, bin).dump(object) File "/usr/lib/python2.2/pickle.py", line 115, in dump self.save(object) File "/usr/lib/python2.2/pickle.py", line 225, in save f(self, object) File "/usr/lib/python2.2/pickle.py", line 519, in save_global raise PicklingError( pickle.PicklingError: Can't pickle <function at 0x8157edc>: it's not found as main.

The reported lambda problem is found without having to check that the manually resolved class object is at the same memory address as the class object referenced by the lambda. I think the pickle code is being too careful.

From pickle.py: the "klass is not object" test in the else clause should probably be removed.

    try:
        __import__(module)
        mod = sys.modules[module]
        klass = getattr(mod, name)
    except (ImportError, KeyError, AttributeError):
        raise PicklingError(
            "Can't pickle %r: it's not found as

%s.%s" % (object, module, name)) else: if klass is not object: raise PicklingError( "Can't pickle %r: it's not the same object as %s.%s" % (object, module, name))