https://github.com/python/cpython/commit/b6c6cd632115a38b0a58aa03a90deff7fb2a1295 commit: b6c6cd632115a38b0a58aa03a90deff7fb2a1295 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: vstinner <[email protected]> date: 2026-02-06T09:48:55Z summary:
[3.13] gh-144330: Initialize classmethod and staticmethod in new (GH-144498) (#144537) [3.14] gh-144330: Initialize classmethod and staticmethod in new (GH-144498) gh-144330: Initialize classmethod and staticmethod in new Initialize cm_callable and sm_callable to None in classmethod and staticmethod constructor. (cherry picked from commit 160810de89477836f2fde7139f7ab0670399efff) Co-authored-by: Victor Stinner <[email protected]> Co-authored-by: Aniket Singh Yadav <[email protected]> Co-authored-by: Stan Ulbrych <[email protected]> files: M Lib/test/test_descr.py M Objects/funcobject.c diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index be49ce8c0660af..e98dccc39c178a 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -5065,6 +5065,26 @@ def foo(self): with self.assertRaisesRegex(NotImplementedError, "BAR"): B().foo + def test_staticmethod_new(self): + class MyStaticMethod(staticmethod): + def __init__(self, func): + pass + def func(): pass + sm = MyStaticMethod(func) + self.assertEqual(repr(sm), '<staticmethod(None)>') + self.assertIsNone(sm.__func__) + self.assertIsNone(sm.__wrapped__) + + def test_classmethod_new(self): + class MyClassMethod(classmethod): + def __init__(self, func): + pass + def func(): pass + cm = MyClassMethod(func) + self.assertEqual(repr(cm), '<classmethod(None)>') + self.assertIsNone(cm.__func__) + self.assertIsNone(cm.__wrapped__) + class DictProxyTests(unittest.TestCase): def setUp(self): diff --git a/Objects/funcobject.c b/Objects/funcobject.c index caa58ad0f18e61..61140fd4f1859e 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -1226,6 +1226,18 @@ cm_descr_get(PyObject *self, PyObject *obj, PyObject *type) return PyMethod_New(cm->cm_callable, type); } +static PyObject * +cm_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + classmethod *cm = (classmethod *)PyType_GenericAlloc(type, 0); + if (cm == NULL) { + return NULL; + } + cm->cm_callable = Py_None; + cm->cm_dict = NULL; + return (PyObject *)cm; +} + static int cm_init(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1337,7 +1349,7 @@ PyTypeObject PyClassMethod_Type = { offsetof(classmethod, cm_dict), /* tp_dictoffset */ cm_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ + cm_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; @@ -1415,6 +1427,18 @@ sm_descr_get(PyObject *self, PyObject *obj, PyObject *type) return Py_NewRef(sm->sm_callable); } +static PyObject * +sm_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + staticmethod *sm = (staticmethod *)PyType_GenericAlloc(type, 0); + if (sm == NULL) { + return NULL; + } + sm->sm_callable = Py_None; + sm->sm_dict = NULL; + return (PyObject *)sm; +} + static int sm_init(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1531,7 +1555,7 @@ PyTypeObject PyStaticMethod_Type = { offsetof(staticmethod, sm_dict), /* tp_dictoffset */ sm_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ + sm_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
