4
4
import sys
5
5
import os
6
6
import weakref
7
+ from contextlib import contextmanager
7
8
from inspect import CO_GENERATOR , CO_COROUTINE , CO_ASYNC_GENERATOR
8
9
9
10
__all__ = ["BdbQuit" , "Bdb" , "Breakpoint" ]
@@ -65,6 +66,12 @@ def reset(self):
65
66
self .botframe = None
66
67
self ._set_stopinfo (None , None )
67
68
69
+ @contextmanager
70
+ def set_enterframe (self , frame ):
71
+ self .enterframe = frame
72
+ yield
73
+ self .enterframe = None
74
+
68
75
def trace_dispatch (self , frame , event , arg ):
69
76
"""Dispatch a trace function for debugged frames based on the event.
70
77
@@ -90,28 +97,27 @@ def trace_dispatch(self, frame, event, arg):
90
97
The arg parameter depends on the previous event.
91
98
"""
92
99
93
- self .enterframe = frame
94
-
95
- if self .quitting :
96
- return # None
97
- if event == 'line' :
98
- return self .dispatch_line (frame )
99
- if event == 'call' :
100
- return self .dispatch_call (frame , arg )
101
- if event == 'return' :
102
- return self .dispatch_return (frame , arg )
103
- if event == 'exception' :
104
- return self .dispatch_exception (frame , arg )
105
- if event == 'c_call' :
106
- return self .trace_dispatch
107
- if event == 'c_exception' :
108
- return self .trace_dispatch
109
- if event == 'c_return' :
100
+ with self .set_enterframe (frame ):
101
+ if self .quitting :
102
+ return # None
103
+ if event == 'line' :
104
+ return self .dispatch_line (frame )
105
+ if event == 'call' :
106
+ return self .dispatch_call (frame , arg )
107
+ if event == 'return' :
108
+ return self .dispatch_return (frame , arg )
109
+ if event == 'exception' :
110
+ return self .dispatch_exception (frame , arg )
111
+ if event == 'c_call' :
112
+ return self .trace_dispatch
113
+ if event == 'c_exception' :
114
+ return self .trace_dispatch
115
+ if event == 'c_return' :
116
+ return self .trace_dispatch
117
+ if event == 'opcode' :
118
+ return self .dispatch_opcode (frame , arg )
119
+ print ('bdb.Bdb.dispatch: unknown debugging event:' , repr (event ))
110
120
return self .trace_dispatch
111
- if event == 'opcode' :
112
- return self .dispatch_opcode (frame , arg )
113
- print ('bdb.Bdb.dispatch: unknown debugging event:' , repr (event ))
114
- return self .trace_dispatch
115
121
116
122
def dispatch_line (self , frame ):
117
123
"""Invoke user function and return trace function for line event.
@@ -395,16 +401,15 @@ def set_trace(self, frame=None):
395
401
if frame is None :
396
402
frame = sys ._getframe ().f_back
397
403
self .reset ()
398
- self .enterframe = frame
399
- while frame :
400
- frame .f_trace = self .trace_dispatch
401
- self .botframe = frame
402
- self .frame_trace_lines_opcodes [frame ] = (frame .f_trace_lines , frame .f_trace_opcodes )
403
- # We need f_trace_lines == True for the debugger to work
404
- frame .f_trace_lines = True
405
- frame = frame .f_back
406
- self .set_stepinstr ()
407
- self .enterframe = None
404
+ with self .set_enterframe (frame ):
405
+ while frame :
406
+ frame .f_trace = self .trace_dispatch
407
+ self .botframe = frame
408
+ self .frame_trace_lines_opcodes [frame ] = (frame .f_trace_lines , frame .f_trace_opcodes )
409
+ # We need f_trace_lines == True for the debugger to work
410
+ frame .f_trace_lines = True
411
+ frame = frame .f_back
412
+ self .set_stepinstr ()
408
413
sys .settrace (self .trace_dispatch )
409
414
410
415
def set_continue (self ):
@@ -424,7 +429,6 @@ def set_continue(self):
424
429
for frame , (trace_lines , trace_opcodes ) in self .frame_trace_lines_opcodes .items ():
425
430
frame .f_trace_lines , frame .f_trace_opcodes = trace_lines , trace_opcodes
426
431
self .frame_trace_lines_opcodes = {}
427
- self .enterframe = None
428
432
429
433
def set_quit (self ):
430
434
"""Set quitting attribute to True.
0 commit comments