Skip to content

Commit bc54b34

Browse files
committed
Add tp_init functions to fix test_abc
1 parent b201ba3 commit bc54b34

File tree

1 file changed

+50
-20
lines changed

1 file changed

+50
-20
lines changed

Objects/funcobject.c

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,16 +1472,16 @@ cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
14721472
}
14731473

14741474
static int
1475-
cm_init(classmethod *cm, PyObject *callable)
1475+
cm_set_callable(classmethod *cm, PyObject *callable)
14761476
{
1477-
assert(cm->cm_callable == NULL);
14781477
assert(callable != NULL);
1479-
cm->cm_callable = Py_NewRef(callable);
1480-
1481-
if (functools_wraps((PyObject *)cm, cm->cm_callable) < 0) {
1482-
return -1;
1478+
if (cm->cm_callable == callable) {
1479+
// cm_init() sets the same callable than cm_new()
1480+
return 0;
14831481
}
1484-
return 0;
1482+
1483+
Py_XSETREF(cm->cm_callable, Py_NewRef(callable));
1484+
return functools_wraps((PyObject *)cm, cm->cm_callable);
14851485
}
14861486

14871487
static PyObject *
@@ -1499,13 +1499,28 @@ cm_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
14991499
if (cm == NULL) {
15001500
return NULL;
15011501
}
1502-
if (cm_init(cm, callable) < 0) {
1502+
if (cm_set_callable(cm, callable) < 0) {
15031503
Py_DECREF(cm);
15041504
return NULL;
15051505
}
15061506
return (PyObject *)cm;
15071507
}
15081508

1509+
static int
1510+
cm_init(PyObject *self, PyObject *args, PyObject *kwds)
1511+
{
1512+
if (!_PyArg_NoKeywords("classmethod", kwds)) {
1513+
return -1;
1514+
}
1515+
PyObject *callable; // borrowed ref
1516+
if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable)) {
1517+
return -1;
1518+
}
1519+
1520+
classmethod *cm = (classmethod *)self;
1521+
return cm_set_callable(cm, callable);
1522+
}
1523+
15091524
static PyMemberDef cm_memberlist[] = {
15101525
{"__func__", _Py_T_OBJECT, offsetof(classmethod, cm_callable), Py_READONLY},
15111526
{"__wrapped__", _Py_T_OBJECT, offsetof(classmethod, cm_callable), Py_READONLY},
@@ -1632,7 +1647,7 @@ PyTypeObject PyClassMethod_Type = {
16321647
cm_descr_get, /* tp_descr_get */
16331648
0, /* tp_descr_set */
16341649
offsetof(classmethod, cm_dict), /* tp_dictoffset */
1635-
0, /* tp_init */
1650+
cm_init, /* tp_init */
16361651
PyType_GenericAlloc, /* tp_alloc */
16371652
cm_new, /* tp_new */
16381653
PyObject_GC_Del, /* tp_free */
@@ -1646,7 +1661,7 @@ PyClassMethod_New(PyObject *callable)
16461661
if (cm == NULL) {
16471662
return NULL;
16481663
}
1649-
if (cm_init(cm, callable) < 0) {
1664+
if (cm_set_callable(cm, callable) < 0) {
16501665
Py_DECREF(cm);
16511666
return NULL;
16521667
}
@@ -1718,16 +1733,16 @@ sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
17181733
}
17191734

17201735
static int
1721-
sm_init(staticmethod *sm, PyObject *callable)
1736+
sm_set_callable(staticmethod *sm, PyObject *callable)
17221737
{
1723-
assert(sm->sm_callable == NULL);
17241738
assert(callable != NULL);
1725-
sm->sm_callable = Py_NewRef(callable);
1726-
1727-
if (functools_wraps((PyObject *)sm, sm->sm_callable) < 0) {
1728-
return -1;
1739+
if (sm->sm_callable == callable) {
1740+
// sm_init() sets the same callable than sm_new()
1741+
return 0;
17291742
}
1730-
return 0;
1743+
1744+
Py_XSETREF(sm->sm_callable, Py_NewRef(callable));
1745+
return functools_wraps((PyObject *)sm, sm->sm_callable);
17311746
}
17321747

17331748
static PyObject *
@@ -1745,13 +1760,28 @@ sm_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
17451760
if (sm == NULL) {
17461761
return NULL;
17471762
}
1748-
if (sm_init(sm, callable) < 0) {
1763+
if (sm_set_callable(sm, callable) < 0) {
17491764
Py_DECREF(sm);
17501765
return NULL;
17511766
}
17521767
return (PyObject *)sm;
17531768
}
17541769

1770+
static int
1771+
sm_init(PyObject *self, PyObject *args, PyObject *kwds)
1772+
{
1773+
if (!_PyArg_NoKeywords("staticmethod", kwds)) {
1774+
return -1;
1775+
}
1776+
PyObject *callable; // borrowed ref
1777+
if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable)) {
1778+
return -1;
1779+
}
1780+
1781+
staticmethod *sm = (staticmethod *)self;
1782+
return sm_set_callable(sm, callable);
1783+
}
1784+
17551785
static PyObject*
17561786
sm_call(PyObject *callable, PyObject *args, PyObject *kwargs)
17571787
{
@@ -1882,7 +1912,7 @@ PyTypeObject PyStaticMethod_Type = {
18821912
sm_descr_get, /* tp_descr_get */
18831913
0, /* tp_descr_set */
18841914
offsetof(staticmethod, sm_dict), /* tp_dictoffset */
1885-
0, /* tp_init */
1915+
sm_init, /* tp_init */
18861916
PyType_GenericAlloc, /* tp_alloc */
18871917
sm_new, /* tp_new */
18881918
PyObject_GC_Del, /* tp_free */
@@ -1896,7 +1926,7 @@ PyStaticMethod_New(PyObject *callable)
18961926
if (sm == NULL) {
18971927
return NULL;
18981928
}
1899-
if (sm_init(sm, callable) < 0) {
1929+
if (sm_set_callable(sm, callable) < 0) {
19001930
Py_DECREF(sm);
19011931
return NULL;
19021932
}

0 commit comments

Comments
 (0)