Method __func__ objects are unpicklable

haael <[email protected]>
Newsgroups gmane.comp.python.devel
Message-ID <[email protected]>

During some sophisticated pickling I noticed that method `__func__` 
objects are unpicklable, because they share the name with the bound 
method object itself.


```
from pickle import dumps

class A:
     @classmethod
     def b(cls):
         pass

print(A.b) # <bound method A.b of <class '__main__.A'>>
print(A.b.__func__) # <function A.b at 0x7f5574570bf8>

dumps(A.b) # works
dumps(A.b.__func__) # breaks
# >Traceback (most recent call last):
# >  File "<stdin>", line 1, in <module>
# >_pickle.PicklingError: Can't pickle <function A.b at 0x7fd1d50d8bf8>: 
# >it's not the same object as __main__.A.b
```


The last call compains that global symbol "A.b" is not the same object 
as `A.b.__func__`.

Everything would work if the `__func__` objects had the suffix 
".__func__" in their qualname.

Actually setting the qualname of the `__func__` object makes it 
picklable, but then the bound method object is unpicklable, as it 
inherits the name from the `__func__`. It would be good if they were 
separate.

This is an attempt at emulating the desired behavior:


```
from pickle import dumps

class A:
     pass

def c(cls):
     pass

A.c = lambda: c(A)
A.c.__qualname__ = "A.c"
A.c.__name__ = "c"
A.c.__self__ = A
A.c.__func__ = c
A.c.__func__.__qualname__ = "A.c.__func__"

print(A.c) # <function A.c at 0x7f83ceabcbf8>
print(A.c.__func__) # <function A.c.__func__ at 0x7f83ceabcb70>

dumps(A.c) # works
dumps(A.c.__func__) # works
```


Can we make the `__func__` objects picklable this way?


haael
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.