3
3
import fnmatch
4
4
import sys
5
5
import os
6
+ from contextlib import contextmanager
6
7
from inspect import CO_GENERATOR , CO_COROUTINE , CO_ASYNC_GENERATOR
7
8
8
9
__all__ = ["BdbQuit" , "Bdb" , "Breakpoint" ]
@@ -63,6 +64,12 @@ def reset(self):
63
64
self .botframe = None
64
65
self ._set_stopinfo (None , None )
65
66
67
+ @contextmanager
68
+ def set_enterframe (self , frame ):
69
+ self .enterframe = frame
70
+ yield
71
+ self .enterframe = None
72
+
66
73
def trace_dispatch (self , frame , event , arg ):
67
74
"""Dispatch a trace function for debugged frames based on the event.
68
75
@@ -88,28 +95,27 @@ def trace_dispatch(self, frame, event, arg):
88
95
The arg parameter depends on the previous event.
89
96
"""
90
97
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 ))
108
118
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
113
119
114
120
def dispatch_line (self , frame ):
115
121
"""Invoke user function and return trace function for line event.
@@ -373,16 +379,15 @@ def set_trace(self, frame=None):
373
379
if frame is None :
374
380
frame = sys ._getframe ().f_back
375
381
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 ()
386
391
sys .settrace (self .trace_dispatch )
387
392
388
393
def set_continue (self ):
@@ -402,7 +407,6 @@ def set_continue(self):
402
407
for frame , (trace_lines , trace_opcodes ) in self .frame_trace_lines_opcodes .items ():
403
408
frame .f_trace_lines , frame .f_trace_opcodes = trace_lines , trace_opcodes
404
409
self .frame_trace_lines_opcodes = {}
405
- self .enterframe = None
406
410
407
411
def set_quit (self ):
408
412
"""Set quitting attribute to True.
0 commit comments