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

Reply via email to