https://github.com/python/cpython/commit/61b35f74aa4a6ac606635e245147ff3658628d99
commit: 61b35f74aa4a6ac606635e245147ff3658628d99
branch: main
author: Tian Gao <[email protected]>
committer: gaogaotiantian <[email protected]>
date: 2025-01-18T16:53:06-05:00
summary:

gh-128991: Release the enter frame reference within bdb callback (#128992)

* Release the enter frame reference within bdb callback

* 📜🤖 Added by blurb_it.

---------

Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2025-01-18-16-58-10.gh-issue-128991.EzJit9.rst
M Lib/bdb.py

diff --git a/Lib/bdb.py b/Lib/bdb.py
index 73e249621a053b..a741628e32a981 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -4,6 +4,7 @@
 import sys
 import os
 import weakref
+from contextlib import contextmanager
 from inspect import CO_GENERATOR, CO_COROUTINE, CO_ASYNC_GENERATOR
 
 __all__ = ["BdbQuit", "Bdb", "Breakpoint"]
@@ -65,6 +66,12 @@ def reset(self):
         self.botframe = None
         self._set_stopinfo(None, None)
 
+    @contextmanager
+    def set_enterframe(self, frame):
+        self.enterframe = frame
+        yield
+        self.enterframe = None
+
     def trace_dispatch(self, frame, event, arg):
         """Dispatch a trace function for debugged frames based on the event.
 
@@ -90,28 +97,27 @@ def trace_dispatch(self, frame, event, arg):
         The arg parameter depends on the previous event.
         """
 
-        self.enterframe = frame
-
-        if self.quitting:
-            return # None
-        if event == 'line':
-            return self.dispatch_line(frame)
-        if event == 'call':
-            return self.dispatch_call(frame, arg)
-        if event == 'return':
-            return self.dispatch_return(frame, arg)
-        if event == 'exception':
-            return self.dispatch_exception(frame, arg)
-        if event == 'c_call':
-            return self.trace_dispatch
-        if event == 'c_exception':
-            return self.trace_dispatch
-        if event == 'c_return':
+        with self.set_enterframe(frame):
+            if self.quitting:
+                return # None
+            if event == 'line':
+                return self.dispatch_line(frame)
+            if event == 'call':
+                return self.dispatch_call(frame, arg)
+            if event == 'return':
+                return self.dispatch_return(frame, arg)
+            if event == 'exception':
+                return self.dispatch_exception(frame, arg)
+            if event == 'c_call':
+                return self.trace_dispatch
+            if event == 'c_exception':
+                return self.trace_dispatch
+            if event == 'c_return':
+                return self.trace_dispatch
+            if event == 'opcode':
+                return self.dispatch_opcode(frame, arg)
+            print('bdb.Bdb.dispatch: unknown debugging event:', repr(event))
             return self.trace_dispatch
-        if event == 'opcode':
-            return self.dispatch_opcode(frame, arg)
-        print('bdb.Bdb.dispatch: unknown debugging event:', repr(event))
-        return self.trace_dispatch
 
     def dispatch_line(self, frame):
         """Invoke user function and return trace function for line event.
@@ -395,16 +401,15 @@ def set_trace(self, frame=None):
         if frame is None:
             frame = sys._getframe().f_back
         self.reset()
-        self.enterframe = frame
-        while frame:
-            frame.f_trace = self.trace_dispatch
-            self.botframe = frame
-            self.frame_trace_lines_opcodes[frame] = (frame.f_trace_lines, 
frame.f_trace_opcodes)
-            # We need f_trace_lines == True for the debugger to work
-            frame.f_trace_lines = True
-            frame = frame.f_back
-        self.set_stepinstr()
-        self.enterframe = None
+        with self.set_enterframe(frame):
+            while frame:
+                frame.f_trace = self.trace_dispatch
+                self.botframe = frame
+                self.frame_trace_lines_opcodes[frame] = (frame.f_trace_lines, 
frame.f_trace_opcodes)
+                # We need f_trace_lines == True for the debugger to work
+                frame.f_trace_lines = True
+                frame = frame.f_back
+            self.set_stepinstr()
         sys.settrace(self.trace_dispatch)
 
     def set_continue(self):
@@ -424,7 +429,6 @@ def set_continue(self):
             for frame, (trace_lines, trace_opcodes) in 
self.frame_trace_lines_opcodes.items():
                 frame.f_trace_lines, frame.f_trace_opcodes = trace_lines, 
trace_opcodes
             self.frame_trace_lines_opcodes = {}
-            self.enterframe = None
 
     def set_quit(self):
         """Set quitting attribute to True.
diff --git 
a/Misc/NEWS.d/next/Library/2025-01-18-16-58-10.gh-issue-128991.EzJit9.rst 
b/Misc/NEWS.d/next/Library/2025-01-18-16-58-10.gh-issue-128991.EzJit9.rst
new file mode 100644
index 00000000000000..64fa04fb53e89c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-01-18-16-58-10.gh-issue-128991.EzJit9.rst
@@ -0,0 +1 @@
+Release the enter frame reference within :mod:`bdb` callback

_______________________________________________
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