Skip to content

Regression caused by #449? #510

@johnomotani

Description

@johnomotani

Pickling of a rather complicated object in one of my projects broke when updating dill from 0.3.4 to 0.3.5. I've constructed a MWE that I think shows the problem.

import dill
import numpy as np
from scipy.interpolate import RectBivariateSpline

#dill.detect.trace(True)

class Foo:
    def __init__(self):
        x = np.linspace(0,1,10)[:,None]
        y = np.linspace(2,3,9)[None,:]
        self.f = RectBivariateSpline(x,y,x*y)
        def f2(self,x,y):
            return self.f(x,y)
        self.f2 = f2.__get__(self)

foo = Foo()
pickled = dill.dumps(foo)
unpickled = dill.loads(pickled)

print(unpickled.f2(0.5, 0.6))

Up to e2831d0, this script ran without errors, and just printed [[1.]], but at 914d47f (where #449 was merged), instead I get an error

Traceback (most recent call last):
  File ".../dill-test.py", line 20, in <module>
    unpickled = dill.loads(pickled)
  File ".../dill/dill/_dill.py", line 387, in loads
    return load(file, ignore, **kwds)
  File ".../dill/dill/_dill.py", line 373, in load
    return Unpickler(file, ignore=ignore, **kwds).load()
  File ".../dill/dill/_dill.py", line 606, in load
    obj = StockUnpickler.load(self)
AttributeError: 'Foo' object has no attribute 'f2'

In case it's helpful, here is the output with tracing enabled. For the successful version (e2831d0):

T2: <class '__main__.Foo'>
F2: <function _create_type at 0x7fd58af151f0>
# F2
T1: <class 'type'>
F2: <function _load_type at 0x7fd58af15160>
# F2
# T1
T1: <class 'object'>
# T1
D2: <dict object at 0x7fd56cb7f600>
F1: <function Foo.__init__ at 0x7fd56e42bca0>
F2: <function _create_function at 0x7fd58af15280>
# F2
Co: <code object __init__ at 0x7fd58b309c90, file "/home/jomotani/temp/dill-test/./dill-test.py", line 10>
F2: <function _create_code at 0x7fd58af15310>
# F2
Co: <code object f2 at 0x7fd58b309920, file "/home/jomotani/temp/dill-test/./dill-test.py", line 14>
# Co
# Co
D1: <dict object at 0x7fd58b3a9500>
# D1
D2: <dict object at 0x7fd56cb7fb00>
# D2
# F1
# D2
# T2
D2: <dict object at 0x7fd58af32940>
T4: <class 'scipy.interpolate._fitpack2.RectBivariateSpline'>
# T4
D2: <dict object at 0x7fd58b3a9680>
B3: <built-in function _reconstruct>
F2: <function _get_attr at 0x7fd58af15dc0>
# F2
M2: <module 'numpy.core._multiarray_umath' from '/home/jomotani/miniconda3/lib/python3.9/site-packages/numpy/core/_multiarray_umath.cpython-39-x86_64-linux-gnu.so'>
F2: <function _import_module at 0x7fd58af15ee0>
# F2
# M2
# B3
T4: <class 'numpy.ndarray'>
# T4
T4: <class 'numpy.dtype'>
# T4
# D2
Me: <bound method Foo.__init__.<locals>.f2 of <__main__.Foo object at 0x7fd58b114be0>>
T1: <class 'method'>
# T1
F1: <function Foo.__init__.<locals>.f2 at 0x7fd58b1f5f70>
D1: <dict object at 0x7fd58b3a9500>
# D1
D2: <dict object at 0x7fd56cb7fa80>
# D2
# F1
# Me
# D2
[[1.]]

and for the failing version (914d47f):

T2: <class '__main__.Foo'>
F2: <function _create_type at 0x7fe74f16b1f0>
# F2
T1: <class 'type'>
F2: <function _load_type at 0x7fe74f16b160>
# F2
# T1
T1: <class 'object'>
# T1
D2: <dict object at 0x7fe730d4b500>
F1: <function Foo.__init__ at 0x7fe7325f7e50>
F2: <function _create_function at 0x7fe74f16b280>
# F2
Co: <code object __init__ at 0x7fe74f4d4c90, file "/home/jomotani/temp/dill-test/./dill-test.py", line 10>
F2: <function _create_code at 0x7fe74f16b310>
# F2
Co: <code object f2 at 0x7fe74f4d4920, file "/home/jomotani/temp/dill-test/./dill-test.py", line 14>
# Co
# Co
D1: <dict object at 0x7fe74f574500>
# D1
D2: <dict object at 0x7fe730d4ba40>
# D2
# F1
# D2
# T2
D2: <dict object at 0x7fe74f0fe9c0>
T4: <class 'scipy.interpolate._fitpack2.RectBivariateSpline'>
# T4
D2: <dict object at 0x7fe74f574680>
T4: <class 'numpy.ndarray'>
# T4
T4: <class 'numpy.dtype'>
# T4
# D2
# D2
Traceback (most recent call last):
  File ".../dill-test.py", line 20, in <module>
    unpickled = dill.loads(pickled)
  File ".../dill/dill/_dill.py", line 387, in loads
    return load(file, ignore, **kwds)
  File ".../dill/dill/_dill.py", line 373, in load
    return Unpickler(file, ignore=ignore, **kwds).load()
  File ".../dill/dill/_dill.py", line 606, in load
    obj = StockUnpickler.load(self)
AttributeError: 'Foo' object has no attribute 'f2'

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions