https://github.com/python/cpython/commit/78c254582b1757c15098ae65e97a2589ae663cd7
commit: 78c254582b1757c15098ae65e97a2589ae663cd7
branch: main
author: Albert Zeyer <[email protected]>
committer: iritkatriel <[email protected]>
date: 2024-01-31T19:14:44Z
summary:

gh-113939: Frame clear, clear locals (#113940)

files:
A Misc/NEWS.d/next/Core and 
Builtins/2024-01-12-16-40-07.gh-issue-113939.Yi3L-e.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 7f17666a8d9697..244ce8af7cdf08 100644
--- a/Lib/test/test_frame.py
+++ b/Lib/test/test_frame.py
@@ -55,6 +55,28 @@ class C:
         # The reference was released by .clear()
         self.assertIs(None, wr())
 
+    def test_clear_locals_after_f_locals_access(self):
+        # see gh-113939
+        class C:
+            pass
+
+        wr = None
+        def inner():
+            nonlocal wr
+            c = C()
+            wr = weakref.ref(c)
+            1/0
+
+        try:
+            inner()
+        except ZeroDivisionError as exc:
+            support.gc_collect()
+            self.assertIsNotNone(wr())
+            print(exc.__traceback__.tb_next.tb_frame.f_locals)
+            exc.__traceback__.tb_next.tb_frame.clear()
+            support.gc_collect()
+            self.assertIsNone(wr())
+
     def test_clear_does_not_clear_specials(self):
         class C:
             pass
diff --git a/Misc/NEWS.d/next/Core and 
Builtins/2024-01-12-16-40-07.gh-issue-113939.Yi3L-e.rst b/Misc/NEWS.d/next/Core 
and Builtins/2024-01-12-16-40-07.gh-issue-113939.Yi3L-e.rst
new file mode 100644
index 00000000000000..28b8e4bdda6be4
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and 
Builtins/2024-01-12-16-40-07.gh-issue-113939.Yi3L-e.rst 
@@ -0,0 +1,4 @@
+frame.clear():
+Clear frame.f_locals as well, and not only the fast locals.
+This is relevant once frame.f_locals was accessed,
+which would contain also references to all the locals.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index cafe4ef6141d9a..a914c61aac2fd5 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -926,6 +926,7 @@ frame_tp_clear(PyFrameObject *f)
         Py_CLEAR(locals[i]);
     }
     f->f_frame->stacktop = 0;
+    Py_CLEAR(f->f_frame->f_locals);
     return 0;
 }
 

_______________________________________________
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