Skip to content

Commit e75f528

Browse files
[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 2590774) Co-authored-by: Petr Viktorin <[email protected]>
1 parent 16e9e74 commit e75f528

File tree

3 files changed

+15
-11
lines changed

3 files changed

+15
-11
lines changed

Lib/test/test_ctypes/test_pointers.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,17 @@ def test_pointer_type_str_name(self):
224224
def test_abstract(self):
225225
self.assertRaises(TypeError, _Pointer.set_type, 42)
226226

227+
def test_repeated_set_type(self):
228+
# Regression test for gh-133290
229+
class C(Structure):
230+
_fields_ = [('a', c_int)]
231+
ptr = POINTER(C)
232+
# Read _type_ several times to warm up cache
233+
for i in range(5):
234+
self.assertIs(ptr._type_, C)
235+
ptr.set_type(c_int)
236+
self.assertIs(ptr._type_, c_int)
237+
227238

228239
if __name__ == '__main__':
229240
unittest.main()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix attribute caching issue when setting :attr:`ctypes._Pointer._type_` in
2+
the undocumented and deprecated :func:`!ctypes.SetPointerType` function and the
3+
undocumented :meth:`!set_type` method.

Modules/_ctypes/_ctypes.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,34 +1280,24 @@ PyCPointerType_set_type_impl(PyTypeObject *self, PyTypeObject *cls,
12801280
PyObject *type)
12811281
/*[clinic end generated code: output=51459d8f429a70ac input=67e1e8df921f123e]*/
12821282
{
1283-
PyObject *attrdict = PyType_GetDict(self);
1284-
if (!attrdict) {
1285-
return NULL;
1286-
}
12871283
ctypes_state *st = get_module_state_by_class(cls);
12881284
StgInfo *info;
12891285
if (PyStgInfo_FromType(st, (PyObject *)self, &info) < 0) {
1290-
Py_DECREF(attrdict);
12911286
return NULL;
12921287
}
12931288
if (!info) {
12941289
PyErr_SetString(PyExc_TypeError,
12951290
"abstract class");
1296-
Py_DECREF(attrdict);
12971291
return NULL;
12981292
}
12991293

13001294
if (PyCPointerType_SetProto(st, info, type) < 0) {
1301-
Py_DECREF(attrdict);
13021295
return NULL;
13031296
}
13041297

1305-
if (-1 == PyDict_SetItem(attrdict, &_Py_ID(_type_), type)) {
1306-
Py_DECREF(attrdict);
1298+
if (PyObject_SetAttr((PyObject *)self, &_Py_ID(_type_), type) < 0) {
13071299
return NULL;
13081300
}
1309-
1310-
Py_DECREF(attrdict);
13111301
Py_RETURN_NONE;
13121302
}
13131303

0 commit comments

Comments
 (0)