[Python-Dev] Method __func__ objects are unpicklable

2022年6月10日 05:00:40 -0700

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
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/N2J6MVLURTBAB5PJLJG3LO6U4PTPJMU2/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to