https://github.com/python/cpython/commit/ca6e733efcb624ebcd63a38b73eb92496bc7ca1b
commit: ca6e733efcb624ebcd63a38b73eb92496bc7ca1b
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-21T10:05:50+03:00
summary:
gh-156124: Fix a crash when deleting ctypes Pointer.contents (GH-156125)
In the free-threaded build the setter passed the value to
Py_BEGIN_CRITICAL_SECTION2() before checking it for NULL.
files:
A Misc/NEWS.d/next/Library/2026-08-20-16-30-00.gh-issue-156124.Kq3vXz.rst
M Lib/test/test_ctypes/test_delattr.py
M Modules/_ctypes/_ctypes.c
diff --git a/Lib/test/test_ctypes/test_delattr.py
b/Lib/test/test_ctypes/test_delattr.py
index e80b5fa6efb5455..eb99c0dafc86563 100644
--- a/Lib/test/test_ctypes/test_delattr.py
+++ b/Lib/test/test_ctypes/test_delattr.py
@@ -1,5 +1,5 @@
import unittest
-from ctypes import Structure, c_char, c_int
+from ctypes import POINTER, Structure, c_char, c_int
class X(Structure):
@@ -16,6 +16,11 @@ def test_chararray(self):
with self.assertRaises(TypeError):
del chararray.value
+ def test_pointer_contents(self):
+ ptr = POINTER(c_int)(c_int(42))
+ with self.assertRaises(TypeError):
+ del ptr.contents
+
def test_struct(self):
struct = X()
with self.assertRaises(TypeError):
diff --git
a/Misc/NEWS.d/next/Library/2026-08-20-16-30-00.gh-issue-156124.Kq3vXz.rst
b/Misc/NEWS.d/next/Library/2026-08-20-16-30-00.gh-issue-156124.Kq3vXz.rst
new file mode 100644
index 000000000000000..64882cbc40e2450
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-08-20-16-30-00.gh-issue-156124.Kq3vXz.rst
@@ -0,0 +1,2 @@
+Fix a crash in the free-threaded build when deleting the :attr:`!contents`
+attribute of a :mod:`ctypes` pointer.
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 034f26807f84aa8..3882b9a5ddff3c6 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -5713,11 +5713,6 @@ Pointer_set_contents_lock_held(PyObject *op, PyObject
*value, void *closure)
PyObject *keep;
CDataObject *self = _CDataObject_CAST(op);
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "Pointer does not support item deletion");
- return -1;
- }
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *stginfo;
if (PyStgInfo_FromObject(st, op, &stginfo) < 0) {
@@ -5761,6 +5756,11 @@ Pointer_set_contents_lock_held(PyObject *op, PyObject
*value, void *closure)
static int
Pointer_set_contents(PyObject *op, PyObject *value, void *closure)
{
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Pointer does not support item deletion");
+ return -1;
+ }
int res;
Py_BEGIN_CRITICAL_SECTION2(op, value);
res = Pointer_set_contents_lock_held(op, value, closure);
_______________________________________________
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]