https://github.com/python/cpython/commit/2590774c9bb96ec75ca8a13b0c061fcc9db3eb65
commit: 2590774c9bb96ec75ca8a13b0c061fcc9db3eb65
branch: main
author: Petr Viktorin <[email protected]>
committer: encukou <[email protected]>
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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]