Skip to content

Commit d19af00

Browse files
gh-132536: Do not disable PY_THROW event in bdb (#132537)
1 parent 4f10b93 commit d19af00

File tree

3 files changed

+44
-12
lines changed

3 files changed

+44
-12
lines changed

Lib/bdb.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def start_trace(self, tracefunc):
5858
E = sys.monitoring.events
5959
all_events = 0
6060
for event, cb_name in self.EVENT_CALLBACK_MAP.items():
61-
callback = getattr(self, f'{cb_name}_callback')
61+
callback = self.callback_wrapper(getattr(self, f'{cb_name}_callback'), event)
6262
sys.monitoring.register_callback(self._tool_id, event, callback)
6363
if event != E.INSTRUCTION:
6464
all_events |= event
@@ -82,19 +82,22 @@ def restart_events(self):
8282
if sys.monitoring.get_tool(self._tool_id) == self._name:
8383
sys.monitoring.restart_events()
8484

85-
def callback_wrapper(func):
85+
def callback_wrapper(self, func, event):
8686
import functools
8787

8888
@functools.wraps(func)
89-
def wrapper(self, *args):
89+
def wrapper(*args):
9090
if self._tracing_thread != threading.current_thread():
9191
return
9292
try:
9393
frame = sys._getframe().f_back
94-
ret = func(self, frame, *args)
94+
ret = func(frame, *args)
9595
if self._enabled and frame.f_trace:
9696
self.update_local_events()
97-
if self._disable_current_event:
97+
if (
98+
self._disable_current_event
99+
and event not in (E.PY_THROW, E.PY_UNWIND, E.RAISE)
100+
):
98101
return sys.monitoring.DISABLE
99102
else:
100103
return ret
@@ -107,30 +110,25 @@ def wrapper(self, *args):
107110

108111
return wrapper
109112

110-
@callback_wrapper
111113
def call_callback(self, frame, code, *args):
112114
local_tracefunc = self._tracefunc(frame, 'call', None)
113115
if local_tracefunc is not None:
114116
frame.f_trace = local_tracefunc
115117
if self._enabled:
116118
sys.monitoring.set_local_events(self._tool_id, code, self.LOCAL_EVENTS)
117119

118-
@callback_wrapper
119120
def return_callback(self, frame, code, offset, retval):
120121
if frame.f_trace:
121122
frame.f_trace(frame, 'return', retval)
122123

123-
@callback_wrapper
124124
def unwind_callback(self, frame, code, *args):
125125
if frame.f_trace:
126126
frame.f_trace(frame, 'return', None)
127127

128-
@callback_wrapper
129128
def line_callback(self, frame, code, *args):
130129
if frame.f_trace and frame.f_trace_lines:
131130
frame.f_trace(frame, 'line', None)
132131

133-
@callback_wrapper
134132
def jump_callback(self, frame, code, inst_offset, dest_offset):
135133
if dest_offset > inst_offset:
136134
return sys.monitoring.DISABLE
@@ -141,7 +139,6 @@ def jump_callback(self, frame, code, inst_offset, dest_offset):
141139
if frame.f_trace and frame.f_trace_lines:
142140
frame.f_trace(frame, 'line', None)
143141

144-
@callback_wrapper
145142
def exception_callback(self, frame, code, offset, exc):
146143
if frame.f_trace:
147144
if exc.__traceback__ and hasattr(exc.__traceback__, 'tb_frame'):
@@ -152,7 +149,6 @@ def exception_callback(self, frame, code, offset, exc):
152149
tb = tb.tb_next
153150
frame.f_trace(frame, 'exception', (type(exc), exc, exc.__traceback__))
154151

155-
@callback_wrapper
156152
def opcode_callback(self, frame, code, offset):
157153
if frame.f_trace and frame.f_trace_opcodes:
158154
frame.f_trace(frame, 'opcode', None)

Lib/test/test_pdb.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,6 +2581,41 @@ def test_pdb_next_command_subiterator():
25812581
(Pdb) continue
25822582
"""
25832583

2584+
def test_pdb_breakpoint_with_throw():
2585+
"""GH-132536: PY_THROW event should not be turned off
2586+
2587+
>>> reset_Breakpoint()
2588+
2589+
>>> def gen():
2590+
... yield 0
2591+
2592+
>>> def test_function():
2593+
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
2594+
... g = gen()
2595+
... try:
2596+
... g.throw(TypeError)
2597+
... except TypeError:
2598+
... pass
2599+
2600+
>>> with PdbTestInput([
2601+
... 'b 7',
2602+
... 'continue',
2603+
... 'clear 1',
2604+
... 'continue',
2605+
... ]):
2606+
... test_function()
2607+
> <doctest test.test_pdb.test_pdb_breakpoint_with_throw[2]>(2)test_function()
2608+
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
2609+
(Pdb) b 7
2610+
Breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_with_throw[2]>:7
2611+
(Pdb) continue
2612+
> <doctest test.test_pdb.test_pdb_breakpoint_with_throw[2]>(7)test_function()
2613+
-> pass
2614+
(Pdb) clear 1
2615+
Deleted breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_with_throw[2]>:7
2616+
(Pdb) continue
2617+
"""
2618+
25842619
def test_pdb_multiline_statement():
25852620
"""Test for multiline statement
25862621
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not disable :monitoring-event:`PY_THROW` event in :mod:`bdb` because it can't be disabled.

0 commit comments

Comments
 (0)