https://github.com/python/cpython/commit/2590774c9bb96ec75ca8a13b0c061fcc9db3eb65
commit: 2590774c9bb96ec75ca8a13b0c061fcc9db3eb65
branch: main
author: Petr Viktorin <encu...@gmail.com>
committer: encukou <encu...@gmail.com>
date: 2025-05-02T14:47:07+02:00
summary:

gh-133290: Use PyObject_SetAttr to set _type_ (GH-133292)

files:
A Misc/NEWS.d/next/Library/2025-05-02-13-16-44.gh-issue-133290.R5WrLM.rst
M Lib/test/test_ctypes/test_pointers.py
M Modules/_ctypes/_ctypes.c

diff --git a/Lib/test/test_ctypes/test_pointers.py 
b/Lib/test/test_ctypes/test_pointers.py
index fc558e10ba40c5..ed4541335dfca4 100644
--- a/Lib/test/test_ctypes/test_pointers.py
+++ b/Lib/test/test_ctypes/test_pointers.py
@@ -224,6 +224,17 @@ def test_pointer_type_str_name(self):
     def test_abstract(self):
         self.assertRaises(TypeError, _Pointer.set_type, 42)
 
+    def test_repeated_set_type(self):
+        # Regression test for gh-133290
+        class C(Structure):
+            _fields_ = [('a', c_int)]
+        ptr = POINTER(C)
+        # Read _type_ several times to warm up cache
+        for i in range(5):
+            self.assertIs(ptr._type_, C)
+        ptr.set_type(c_int)
+        self.assertIs(ptr._type_, c_int)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git 
a/Misc/NEWS.d/next/Library/2025-05-02-13-16-44.gh-issue-133290.R5WrLM.rst 
b/Misc/NEWS.d/next/Library/2025-05-02-13-16-44.gh-issue-133290.R5WrLM.rst
new file mode 100644
index 00000000000000..538cce9357dfec
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-05-02-13-16-44.gh-issue-133290.R5WrLM.rst
@@ -0,0 +1,3 @@
+Fix attribute caching issue when setting :attr:`ctypes._Pointer._type_` in
+the undocumented and deprecated :func:`!ctypes.SetPointerType` function and the
+undocumented :meth:`!set_type` method.
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 64030685ab0695..3605ca9007c9f8 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -1298,34 +1298,24 @@ PyCPointerType_set_type_impl(PyTypeObject *self, 
PyTypeObject *cls,
                              PyObject *type)
 /*[clinic end generated code: output=51459d8f429a70ac input=67e1e8df921f123e]*/
 {
-    PyObject *attrdict = PyType_GetDict(self);
-    if (!attrdict) {
-        return NULL;
-    }
     ctypes_state *st = get_module_state_by_class(cls);
     StgInfo *info;
     if (PyStgInfo_FromType(st, (PyObject *)self, &info) < 0) {
-        Py_DECREF(attrdict);
         return NULL;
     }
     if (!info) {
         PyErr_SetString(PyExc_TypeError,
                         "abstract class");
-        Py_DECREF(attrdict);
         return NULL;
     }
 
     if (PyCPointerType_SetProto(st, info, type) < 0) {
-        Py_DECREF(attrdict);
         return NULL;
     }
 
-    if (-1 == PyDict_SetItem(attrdict, &_Py_ID(_type_), type)) {
-        Py_DECREF(attrdict);
+    if (PyObject_SetAttr((PyObject *)self, &_Py_ID(_type_), type) < 0) {
         return NULL;
     }
-
-    Py_DECREF(attrdict);
     Py_RETURN_NONE;
 }
 

_______________________________________________
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