New submission from George Xie <george...@gmail.com>:

if we create a bound method object `f` with function object `A.f` and instance 
object `B()`,
when pickling this bound method object:

        import pickle

        class A():
            def f(self):
                pass

        class B():
            def f(self):
                pass

        o = B()
        f = A.f.__get__(o)
        pf = pickle.loads(pickle.dumps(f))
        print(f)
        print(pf)

we get:

        <bound method A.f of <__main__.B object at 0x10b82ac18>>
        <bound method B.f of <__main__.B object at 0x10b82ac88>>

the underlaying function are lost, changed from `A.f` to `B.f`.

as pickle calls `__reduce__` method of `method object`, IMO [its 
implementation][1] simply ignored the real function, whcih is not right.

I have tried a [wordaround][2]:

        import types
        import copyreg

        def my_reduce(obj):
            return (obj.__func__.__get__, (obj.__self__,))

        copyreg.pickle(types.MethodType, my_reduce)


[1]: https://github.com/python/cpython/blob/v3.7.3/Objects/classobject.c#L75-L89
[2]: https://stackoverflow.com/a/56614748/4201810

----------
components: Library (Lib)
messages: 345721
nosy: georgexsh
priority: normal
severity: normal
status: open
title: function changed when pickle bound method object
type: behavior
versions: Python 3.7

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue37297>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to