Skip to content

Commit b6c6cd6

Browse files
miss-islingtonvstinnerAniketsyStanFromIreland
authored
[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 160810d) Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Aniket Singh Yadav <singhyadavaniket43@gmail.com> Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
1 parent 7d04956 commit b6c6cd6

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

Lib/test/test_descr.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5065,6 +5065,26 @@ def foo(self):
50655065
with self.assertRaisesRegex(NotImplementedError, "BAR"):
50665066
B().foo
50675067

5068+
def test_staticmethod_new(self):
5069+
class MyStaticMethod(staticmethod):
5070+
def __init__(self, func):
5071+
pass
5072+
def func(): pass
5073+
sm = MyStaticMethod(func)
5074+
self.assertEqual(repr(sm), '<staticmethod(None)>')
5075+
self.assertIsNone(sm.__func__)
5076+
self.assertIsNone(sm.__wrapped__)
5077+
5078+
def test_classmethod_new(self):
5079+
class MyClassMethod(classmethod):
5080+
def __init__(self, func):
5081+
pass
5082+
def func(): pass
5083+
cm = MyClassMethod(func)
5084+
self.assertEqual(repr(cm), '<classmethod(None)>')
5085+
self.assertIsNone(cm.__func__)
5086+
self.assertIsNone(cm.__wrapped__)
5087+
50685088

50695089
class DictProxyTests(unittest.TestCase):
50705090
def setUp(self):

Objects/funcobject.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,18 @@ cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
12261226
return PyMethod_New(cm->cm_callable, type);
12271227
}
12281228

1229+
static PyObject *
1230+
cm_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1231+
{
1232+
classmethod *cm = (classmethod *)PyType_GenericAlloc(type, 0);
1233+
if (cm == NULL) {
1234+
return NULL;
1235+
}
1236+
cm->cm_callable = Py_None;
1237+
cm->cm_dict = NULL;
1238+
return (PyObject *)cm;
1239+
}
1240+
12291241
static int
12301242
cm_init(PyObject *self, PyObject *args, PyObject *kwds)
12311243
{
@@ -1337,7 +1349,7 @@ PyTypeObject PyClassMethod_Type = {
13371349
offsetof(classmethod, cm_dict), /* tp_dictoffset */
13381350
cm_init, /* tp_init */
13391351
PyType_GenericAlloc, /* tp_alloc */
1340-
PyType_GenericNew, /* tp_new */
1352+
cm_new, /* tp_new */
13411353
PyObject_GC_Del, /* tp_free */
13421354
};
13431355

@@ -1415,6 +1427,18 @@ sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
14151427
return Py_NewRef(sm->sm_callable);
14161428
}
14171429

1430+
static PyObject *
1431+
sm_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1432+
{
1433+
staticmethod *sm = (staticmethod *)PyType_GenericAlloc(type, 0);
1434+
if (sm == NULL) {
1435+
return NULL;
1436+
}
1437+
sm->sm_callable = Py_None;
1438+
sm->sm_dict = NULL;
1439+
return (PyObject *)sm;
1440+
}
1441+
14181442
static int
14191443
sm_init(PyObject *self, PyObject *args, PyObject *kwds)
14201444
{
@@ -1531,7 +1555,7 @@ PyTypeObject PyStaticMethod_Type = {
15311555
offsetof(staticmethod, sm_dict), /* tp_dictoffset */
15321556
sm_init, /* tp_init */
15331557
PyType_GenericAlloc, /* tp_alloc */
1534-
PyType_GenericNew, /* tp_new */
1558+
sm_new, /* tp_new */
15351559
PyObject_GC_Del, /* tp_free */
15361560
};
15371561

0 commit comments

Comments
 (0)