https://github.com/python/cpython/commit/e75f528e78e933b27b45198bf5bbce952542e1fd
commit: e75f528e78e933b27b45198bf5bbce952542e1fd
branch: 3.13
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: encukou <encu...@gmail.com>
date: 2025-05-02T18:10:32+02:00
summary:

[3.13] gh-133290: Use PyObject_SetAttr to set _type_ (GH-133292) (GH-133295)

gh-133290: Use PyObject_SetAttr to set _type_ (GH-133292)
(cherry picked from commit 2590774c9bb96ec75ca8a13b0c061fcc9db3eb65)

Co-authored-by: Petr Viktorin <encu...@gmail.com>

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 3d7cb1b1164843..7f843a201cdb1f 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -1280,34 +1280,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