Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Incorrect pickling behavior in the c implemented classmethod descriptors #95196

Closed
Labels
type-bugAn unexpected behavior, bug, or error
@UltimateLobster

Description

@UltimateLobster

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

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp