https://github.com/python/cpython/commit/a23ed8b3793aa684e312711cfda9c9fd76168399 commit: a23ed8b3793aa684e312711cfda9c9fd76168399 branch: main author: Tomasz Pytel <tompy...@gmail.com> committer: iritkatriel <1055913+iritkatr...@users.noreply.github.com> date: 2025-04-17T18:08:59+01:00 summary:
gh-132284: Don't wrap base PyCFunction slots on class creation if not overridden (#132329) files: A Misc/NEWS.d/next/Core_and_Builtins/2025-04-09-20-49-04.gh-issue-132284.TxTNka.rst M Doc/whatsnew/3.14.rst M Lib/test/test_types.py M Objects/typeobject.c diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index c50d1669fef84c..7d469e83dc27ad 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -469,6 +469,10 @@ Other language changes of HMAC is not available. (Contributed by Bénédikt Tran in :gh:`99108`.) +* When subclassing from a pure C type, the C slots for the new type are no + longer replaced with a wrapped version on class creation if they are not + explicitly overridden in the subclass. + (Contributed by Tomasz Pytel in :gh:`132329`.) .. _whatsnew314-pep765: diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 87081a6db4ea48..e5d80ee8eb7aca 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -1838,6 +1838,23 @@ class Model(metaclass=ModelBase): with self.assertRaises(RuntimeWarning): type("SouthPonies", (Model,), {}) + def test_subclass_inherited_slot_update(self): + # gh-132284: Make sure slot update still works after fix. + # Note that after assignment to D.__getitem__ the actual C slot will + # never go back to dict_subscript as it was on class type creation but + # rather be set to slot_mp_subscript, unfortunately there is no way to + # check that here. + + class D(dict): + pass + + d = D({None: None}) + self.assertIs(d[None], None) + D.__getitem__ = lambda self, item: 42 + self.assertEqual(d[None], 42) + D.__getitem__ = dict.__getitem__ + self.assertIs(d[None], None) + def test_tuple_subclass_as_bases(self): # gh-132176: it used to crash on using # tuple subclass for as base classes. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-09-20-49-04.gh-issue-132284.TxTNka.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-09-20-49-04.gh-issue-132284.TxTNka.rst new file mode 100644 index 00000000000000..b63a75f1e7e058 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-09-20-49-04.gh-issue-132284.TxTNka.rst @@ -0,0 +1 @@ +Don't wrap base ``PyCFunction`` slots on class creation if not overridden. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f65695360a7483..982f41fd47f92c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -11233,7 +11233,14 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p) } else { use_generic = 1; - generic = p->function; + if (generic == NULL && Py_IS_TYPE(descr, &PyMethodDescr_Type) && + *ptr == ((PyMethodDescrObject *)descr)->d_method->ml_meth) + { + generic = *ptr; + } + else { + generic = p->function; + } if (p->function == slot_tp_call) { /* A generic __call__ is incompatible with vectorcall */ type_clear_flags(type, Py_TPFLAGS_HAVE_VECTORCALL); _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com