Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.4k
Description
Bug report
Hello there, this is my first bug report so apologies if there's something I miss.
Consider the following code:
import pickleclassmethod_descriptor = dict.__dict__["fromkeys"]unpickled_classmethod_descriptor = pickle.loads(pickle.dumps(classmethod_descriptor, protocol=5))
While it passes without raising any errors,classmethod_descriptor
differs fromunpickled_classmethod_descriptor
. Instead of the original descriptor, the pickling process yields the function itself:
>>> classmethod_descriptor<method 'fromkeys' of 'dict' objects>>>> unpickled_classmethod_descriptor<function dict.fromkeys(iterable, value=None, /)>
Manually calling the descriptor's__reduce_ex__
allows us to see the reason:
>>> classmethod_descriptor.__reduce_ex__(5)(<function getattr>, (dict, 'fromkeys'))
This behavior differs from python implemented classmethods:
import pickleclass A: @classmethod def method(cls): passclassmethod_descriptor = A.__dict__["method"]# Any of these lines will raise "TypeError: cannot pickle 'classmethod' object"pickle.dumps(classmethod_descriptor, protocol=5)classmethod_descriptor.__reduce_ex__(5)
Since it fails with normal classmethods, I would expect it to fail with their c counterparts as well so their behavior would match.
Either that, or having both of them succeed during the pickling process, in which case,__reduce_ex__
should return a valid result in both cases.
The bug occurs with other c implemented class methods as well:
import picklefrom datetime import datetimeclassmethod_descriptor = datetime.__dict__["now"]# Returns Falsepickle.loads(pickle.dumps(classmethod_descriptor, 5)) == classmethod_descriptor# Returns Truepickle.loads(pickle.dumps(classmethod_descriptor, 5)) == datetime.now
Your environment
Python Versions:
I've tested it with both 3.10.5 and 3.11.04b
OS - Windows 10 Pro 64 bit
Metadata
Metadata
Assignees
Projects
Status