33import fnmatch
44import sys
55import os
6+ from contextlib import contextmanager
67from inspect import CO_GENERATOR , CO_COROUTINE , CO_ASYNC_GENERATOR
78
89__all__ = ["BdbQuit" , "Bdb" , "Breakpoint" ]
@@ -63,6 +64,12 @@ def reset(self):
6364 self .botframe = None
6465 self ._set_stopinfo (None , None )
6566
67+ @contextmanager
68+ def set_enterframe (self , frame ):
69+ self .enterframe = frame
70+ yield
71+ self .enterframe = None
72+
6673 def trace_dispatch (self , frame , event , arg ):
6774 """Dispatch a trace function for debugged frames based on the event.
6875
@@ -88,28 +95,27 @@ def trace_dispatch(self, frame, event, arg):
8895 The arg parameter depends on the previous event.
8996 """
9097
91- self .enterframe = frame
92-
93- if self .quitting :
94- return # None
95- if event == 'line' :
96- return self .dispatch_line (frame )
97- if event == 'call' :
98- return self .dispatch_call (frame , arg )
99- if event == 'return' :
100- return self .dispatch_return (frame , arg )
101- if event == 'exception' :
102- return self .dispatch_exception (frame , arg )
103- if event == 'c_call' :
104- return self .trace_dispatch
105- if event == 'c_exception' :
106- return self .trace_dispatch
107- if event == 'c_return' :
98+ with self .set_enterframe (frame ):
99+ if self .quitting :
100+ return # None
101+ if event == 'line' :
102+ return self .dispatch_line (frame )
103+ if event == 'call' :
104+ return self .dispatch_call (frame , arg )
105+ if event == 'return' :
106+ return self .dispatch_return (frame , arg )
107+ if event == 'exception' :
108+ return self .dispatch_exception (frame , arg )
109+ if event == 'c_call' :
110+ return self .trace_dispatch
111+ if event == 'c_exception' :
112+ return self .trace_dispatch
113+ if event == 'c_return' :
114+ return self .trace_dispatch
115+ if event == 'opcode' :
116+ return self .dispatch_opcode (frame , arg )
117+ print ('bdb.Bdb.dispatch: unknown debugging event:' , repr (event ))
108118 return self .trace_dispatch
109- if event == 'opcode' :
110- return self .dispatch_opcode (frame , arg )
111- print ('bdb.Bdb.dispatch: unknown debugging event:' , repr (event ))
112- return self .trace_dispatch
113119
114120 def dispatch_line (self , frame ):
115121 """Invoke user function and return trace function for line event.
@@ -373,16 +379,15 @@ def set_trace(self, frame=None):
373379 if frame is None :
374380 frame = sys ._getframe ().f_back
375381 self .reset ()
376- self .enterframe = frame
377- while frame :
378- frame .f_trace = self .trace_dispatch
379- self .botframe = frame
380- self .frame_trace_lines_opcodes [frame ] = (frame .f_trace_lines , frame .f_trace_opcodes )
381- # We need f_trace_lines == True for the debugger to work
382- frame .f_trace_lines = True
383- frame = frame .f_back
384- self .set_stepinstr ()
385- self .enterframe = None
382+ with self .set_enterframe (frame ):
383+ while frame :
384+ frame .f_trace = self .trace_dispatch
385+ self .botframe = frame
386+ self .frame_trace_lines_opcodes [frame ] = (frame .f_trace_lines , frame .f_trace_opcodes )
387+ # We need f_trace_lines == True for the debugger to work
388+ frame .f_trace_lines = True
389+ frame = frame .f_back
390+ self .set_stepinstr ()
386391 sys .settrace (self .trace_dispatch )
387392
388393 def set_continue (self ):
@@ -402,7 +407,6 @@ def set_continue(self):
402407 for frame , (trace_lines , trace_opcodes ) in self .frame_trace_lines_opcodes .items ():
403408 frame .f_trace_lines , frame .f_trace_opcodes = trace_lines , trace_opcodes
404409 self .frame_trace_lines_opcodes = {}
405- self .enterframe = None
406410
407411 def set_quit (self ):
408412 """Set quitting attribute to True.
0 commit comments