https://github.com/python/cpython/commit/acdb9a78595e9f04df9a3de2283476d2c9e450af
commit: acdb9a78595e9f04df9a3de2283476d2c9e450af
branch: 3.13
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-21T15:30:44Z
summary:

[3.13] gh-156189: Fix a crash when deleting frame.f_trace_opcodes (GH-156190)

The setter passed the value to PyBool_Check() without checking it for
NULL.

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-08-21-16-00-00.gh-issue-156189.Zt4nQp.rst
M Lib/test/test_frame.py
M Objects/frameobject.c

diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py
index 2f802179cb3f58..d11240c451790a 100644
--- a/Lib/test/test_frame.py
+++ b/Lib/test/test_frame.py
@@ -219,6 +219,14 @@ def test_locals_clear_locals(self):
         self.assertEqual(outer.f_locals, {})
         self.assertEqual(inner.f_locals, {})
 
+    def test_f_trace_opcodes_del(self):
+        f, _, _ = self.make_frames()
+        f.f_trace_opcodes = True
+        with self.assertRaisesRegex(AttributeError, 'cannot delete attribute'):
+            del f.f_trace_opcodes
+        # a failed deletion does not change the value
+        self.assertIs(f.f_trace_opcodes, True)
+
     def test_f_lineno_del_segfault(self):
         f, _, _ = self.make_frames()
         with self.assertRaises(AttributeError):
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2026-08-21-16-00-00.gh-issue-156189.Zt4nQp.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-08-21-16-00-00.gh-issue-156189.Zt4nQp.rst
new file mode 100644
index 00000000000000..2ced97c87956f0
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-08-21-16-00-00.gh-issue-156189.Zt4nQp.rst
@@ -0,0 +1,2 @@
+Fix a crash when deleting the :attr:`~frame.f_trace_opcodes` attribute of
+a frame object.  It now raises :exc:`AttributeError`.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 9d26a3cdeed4e7..546a60215dc4f4 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -979,6 +979,11 @@ frame_gettrace_opcodes(PyFrameObject *f, void *closure)
 static int
 frame_settrace_opcodes(PyFrameObject *f, PyObject* value, void 
*Py_UNUSED(ignored))
 {
+    if (value == NULL) {
+        PyErr_SetString(PyExc_AttributeError,
+                        "cannot delete attribute f_trace_opcodes");
+        return -1;
+    }
     if (!PyBool_Check(value)) {
         PyErr_SetString(PyExc_TypeError,
                         "attribute value type must be bool");

_______________________________________________
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]

Reply via email to