Skip to content

Commit 3129c67

Browse files
Add basic line ignore
1 parent 77ede62 commit 3129c67

File tree

2 files changed

+57
-25
lines changed

2 files changed

+57
-25
lines changed

Lib/bdb.py

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import sys
55
import os
66
from inspect import CO_GENERATOR, CO_COROUTINE, CO_ASYNC_GENERATOR
7-
from functools import partial
87

98
__all__ = ["BdbQuit", "Bdb", "Breakpoint"]
109

@@ -18,10 +17,25 @@ class BdbQuit(Exception):
1817
E = sys.monitoring.events
1918

2019
class _MonitoringTracer:
20+
EVENT_CALLBACK_MAP = {
21+
E.PY_START: 'call',
22+
E.PY_RESUME: 'call',
23+
E.PY_THROW: 'call',
24+
E.LINE: 'line',
25+
E.JUMP: 'jump',
26+
E.PY_RETURN: 'return',
27+
E.PY_YIELD: 'return',
28+
E.PY_UNWIND: 'unwind',
29+
E.RAISE: 'exception',
30+
E.STOP_ITERATION: 'exception',
31+
E.INSTRUCTION: 'opcode',
32+
}
33+
2134
def __init__(self):
2235
self._tool_id = sys.monitoring.DEBUGGER_ID
2336
self._name = 'bdbtracer'
2437
self._tracefunc = None
38+
self._disable_current_event = False
2539

2640
def start_trace(self, tracefunc):
2741
self._tracefunc = tracefunc
@@ -34,48 +48,49 @@ def start_trace(self, tracefunc):
3448
raise ValueError('Another debugger is using the monitoring tool')
3549
E = sys.monitoring.events
3650
all_events = 0
37-
for event in (E.PY_START, E.PY_RESUME, E.PY_THROW):
38-
sys.monitoring.register_callback(self._tool_id, event, self.call_callback)
39-
all_events |= event
40-
for event in (E.LINE, ):
41-
sys.monitoring.register_callback(self._tool_id, event, self.line_callback)
42-
all_events |= event
43-
for event in (E.JUMP, ):
44-
sys.monitoring.register_callback(self._tool_id, event, self.jump_callback)
45-
all_events |= event
46-
for event in (E.PY_RETURN, E.PY_YIELD):
47-
sys.monitoring.register_callback(self._tool_id, event, self.return_callback)
48-
all_events |= event
49-
for event in (E.PY_UNWIND, ):
50-
sys.monitoring.register_callback(self._tool_id, event, self.unwind_callback)
51-
all_events |= event
52-
for event in (E.RAISE, E.STOP_ITERATION):
53-
sys.monitoring.register_callback(self._tool_id, event, self.exception_callback)
54-
all_events |= event
55-
for event in (E.INSTRUCTION, ):
56-
sys.monitoring.register_callback(self._tool_id, event, self.opcode_callback)
51+
for event, cb_name in self.EVENT_CALLBACK_MAP.items():
52+
callback = getattr(self, f'{cb_name}_callback')
53+
sys.monitoring.register_callback(self._tool_id, event, callback)
54+
if event != E.INSTRUCTION:
55+
all_events |= event
5756
self.check_trace_opcodes()
5857
sys.monitoring.set_events(self._tool_id, all_events)
5958

6059
def stop_trace(self):
6160
curr_tool = sys.monitoring.get_tool(self._tool_id)
6261
if curr_tool != self._name:
6362
return
64-
for event in (E.PY_START, E.PY_RESUME, E.PY_RETURN, E.PY_YIELD, E.RAISE, E.LINE,
65-
E.JUMP, E.PY_UNWIND, E.PY_THROW, E.STOP_ITERATION):
63+
for event in self.EVENT_CALLBACK_MAP.keys():
6664
sys.monitoring.register_callback(self._tool_id, event, None)
6765
sys.monitoring.set_events(self._tool_id, 0)
6866
self.check_trace_opcodes()
6967
sys.monitoring.free_tool_id(self._tool_id)
7068

69+
def disable_current_event(self):
70+
self._disable_current_event = True
71+
72+
def restart_events(self):
73+
if sys.monitoring.get_tool(self._tool_id) == self._name:
74+
sys.monitoring.restart_events()
75+
7176
def callback_wrapper(func):
77+
import functools
78+
79+
@functools.wraps(func)
7280
def wrapper(self, *args):
7381
try:
7482
frame = sys._getframe().f_back
75-
return func(self, frame, *args)
83+
ret = func(self, frame, *args)
84+
if self._disable_current_event:
85+
return sys.monitoring.DISABLE
86+
else:
87+
return ret
7688
except Exception:
7789
self.stop_trace()
7890
raise
91+
finally:
92+
self._disable_current_event = False
93+
7994
return wrapper
8095

8196
@callback_wrapper
@@ -275,6 +290,8 @@ def dispatch_line(self, frame):
275290
if self.stop_here(frame) or self.break_here(frame):
276291
self.user_line(frame)
277292
if self.quitting: raise BdbQuit
293+
else:
294+
self.disable_current_event()
278295
return self.trace_dispatch
279296

280297
def dispatch_call(self, frame, arg):
@@ -296,6 +313,7 @@ def dispatch_call(self, frame, arg):
296313
if self.stopframe and frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
297314
return self.trace_dispatch
298315
self.user_call(frame, arg)
316+
self.restart_events()
299317
if self.quitting: raise BdbQuit
300318
return self.trace_dispatch
301319

@@ -313,6 +331,7 @@ def dispatch_return(self, frame, arg):
313331
try:
314332
self.frame_returning = frame
315333
self.user_return(frame, arg)
334+
self.restart_events()
316335
finally:
317336
self.frame_returning = None
318337
if self.quitting: raise BdbQuit
@@ -340,6 +359,7 @@ def dispatch_exception(self, frame, arg):
340359
if not (frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS
341360
and arg[0] is StopIteration and arg[2] is None):
342361
self.user_exception(frame, arg)
362+
self.restart_events()
343363
if self.quitting: raise BdbQuit
344364
# Stop at the StopIteration or GeneratorExit exception when the user
345365
# has set stopframe in a generator by issuing a return command, or a
@@ -349,6 +369,7 @@ def dispatch_exception(self, frame, arg):
349369
and self.stopframe.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS
350370
and arg[0] in (StopIteration, GeneratorExit)):
351371
self.user_exception(frame, arg)
372+
self.restart_events()
352373
if self.quitting: raise BdbQuit
353374

354375
return self.trace_dispatch
@@ -361,6 +382,7 @@ def dispatch_opcode(self, frame, arg):
361382
"""
362383
if self.stop_here(frame) or self.break_here(frame):
363384
self.user_opcode(frame)
385+
self.restart_events()
364386
if self.quitting: raise BdbQuit
365387
return self.trace_dispatch
366388

@@ -788,6 +810,16 @@ def format_stack_entry(self, frame_lineno, lprefix=': '):
788810
s += f'{lprefix}Warning: lineno is None'
789811
return s
790812

813+
def disable_current_event(self):
814+
"""Disable the current event."""
815+
if self.backend == 'monitoring':
816+
self.monitoring_tracer.disable_current_event()
817+
818+
def restart_events(self):
819+
"""Restart all events."""
820+
if self.backend == 'monitoring':
821+
self.monitoring_tracer.restart_events()
822+
791823
# The following methods can be called by clients to use
792824
# a debugger to debug a statement or an expression.
793825
# Both can be given as a string, or a code object.

Lib/pdb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
310310

311311
def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
312312
nosigint=False, readrc=True, mode=None):
313-
bdb.Bdb.__init__(self, skip=skip)
313+
bdb.Bdb.__init__(self, skip=skip, backend='monitoring')
314314
cmd.Cmd.__init__(self, completekey, stdin, stdout)
315315
sys.audit("pdb.Pdb")
316316
if stdout:

0 commit comments

Comments
 (0)