Skip to content

gh-144330: Initialize classmethod and staticmethod in new#144469

Open
vstinner wants to merge 2 commits intopython:mainfrom
vstinner:cm_new
Open

gh-144330: Initialize classmethod and staticmethod in new#144469
vstinner wants to merge 2 commits intopython:mainfrom
vstinner:cm_new

Conversation

@vstinner
Copy link
Member

@vstinner vstinner commented Feb 4, 2026

Move classmethod and staticmethod initialization from __init__() to __new__().

PyClassMethod_New() and PyStaticMethod_New() now copy attributes of the wrapped functions: __module__, __name__, __qualname__ and __doc__.

Change static type initialization: initialize PyStaticMethod_Type and PyCFunction_Type earlier.

Remove test_refleaks_in_classmethod___init__() and test_refleaks_in_staticmethod___init__() tests from test_descr since classmethod and staticmethod have no __init__() method anymore.

Move classmethod and staticmethod initialization from __init__() to
__new__().

PyClassMethod_New() and PyStaticMethod_New() now copy attributes of
the wrapped functions: __module__, __name__, __qualname__ and
__doc__.

Change static type initialization: initialize PyStaticMethod_Type and
PyCFunction_Type earlier.

Remove test_refleaks_in_classmethod___init__() and
test_refleaks_in_staticmethod___init__() tests from test_descr since
classmethod and staticmethod have no __init__() method anymore.
@vstinner
Copy link
Member Author

vstinner commented Feb 4, 2026

cc @colesbury

@vstinner
Copy link
Member Author

vstinner commented Feb 4, 2026

With this change, cm->cm_callable and sm->sm_callable cannot be NULL anymore (except in cm_dealloc() and sm_dealloc() to handle erros in cm_new() and sm_new()), but they can be equal to None: cm_new() and sm_new() don't check the callable type (no change compared to the current code).

@vstinner
Copy link
Member Author

vstinner commented Feb 4, 2026

I modified my PR to keep __init__() methods for backward compatibility. For example, __init__() is needed by abc.abstractclassmethod which calls super().__init__(callable):

class abstractclassmethod(classmethod):
    __isabstractmethod__ = True
    def __init__(self, callable):
        callable.__isabstractmethod__ = True
        super().__init__(callable)

Copy link
Contributor

@colesbury colesbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@sergey-miryanov sergey-miryanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants