mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-132536: Do not disable PY_THROW event in bdb (#132537)
This commit is contained in:
parent
4f10b93d1b
commit
d19af00b90
3 changed files with 44 additions and 12 deletions
20
Lib/bdb.py
20
Lib/bdb.py
|
@ -58,7 +58,7 @@ class _MonitoringTracer:
|
||||||
E = sys.monitoring.events
|
E = sys.monitoring.events
|
||||||
all_events = 0
|
all_events = 0
|
||||||
for event, cb_name in self.EVENT_CALLBACK_MAP.items():
|
for event, cb_name in self.EVENT_CALLBACK_MAP.items():
|
||||||
callback = getattr(self, f'{cb_name}_callback')
|
callback = self.callback_wrapper(getattr(self, f'{cb_name}_callback'), event)
|
||||||
sys.monitoring.register_callback(self._tool_id, event, callback)
|
sys.monitoring.register_callback(self._tool_id, event, callback)
|
||||||
if event != E.INSTRUCTION:
|
if event != E.INSTRUCTION:
|
||||||
all_events |= event
|
all_events |= event
|
||||||
|
@ -82,19 +82,22 @@ class _MonitoringTracer:
|
||||||
if sys.monitoring.get_tool(self._tool_id) == self._name:
|
if sys.monitoring.get_tool(self._tool_id) == self._name:
|
||||||
sys.monitoring.restart_events()
|
sys.monitoring.restart_events()
|
||||||
|
|
||||||
def callback_wrapper(func):
|
def callback_wrapper(self, func, event):
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapper(self, *args):
|
def wrapper(*args):
|
||||||
if self._tracing_thread != threading.current_thread():
|
if self._tracing_thread != threading.current_thread():
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
frame = sys._getframe().f_back
|
frame = sys._getframe().f_back
|
||||||
ret = func(self, frame, *args)
|
ret = func(frame, *args)
|
||||||
if self._enabled and frame.f_trace:
|
if self._enabled and frame.f_trace:
|
||||||
self.update_local_events()
|
self.update_local_events()
|
||||||
if self._disable_current_event:
|
if (
|
||||||
|
self._disable_current_event
|
||||||
|
and event not in (E.PY_THROW, E.PY_UNWIND, E.RAISE)
|
||||||
|
):
|
||||||
return sys.monitoring.DISABLE
|
return sys.monitoring.DISABLE
|
||||||
else:
|
else:
|
||||||
return ret
|
return ret
|
||||||
|
@ -107,7 +110,6 @@ class _MonitoringTracer:
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
@callback_wrapper
|
|
||||||
def call_callback(self, frame, code, *args):
|
def call_callback(self, frame, code, *args):
|
||||||
local_tracefunc = self._tracefunc(frame, 'call', None)
|
local_tracefunc = self._tracefunc(frame, 'call', None)
|
||||||
if local_tracefunc is not None:
|
if local_tracefunc is not None:
|
||||||
|
@ -115,22 +117,18 @@ class _MonitoringTracer:
|
||||||
if self._enabled:
|
if self._enabled:
|
||||||
sys.monitoring.set_local_events(self._tool_id, code, self.LOCAL_EVENTS)
|
sys.monitoring.set_local_events(self._tool_id, code, self.LOCAL_EVENTS)
|
||||||
|
|
||||||
@callback_wrapper
|
|
||||||
def return_callback(self, frame, code, offset, retval):
|
def return_callback(self, frame, code, offset, retval):
|
||||||
if frame.f_trace:
|
if frame.f_trace:
|
||||||
frame.f_trace(frame, 'return', retval)
|
frame.f_trace(frame, 'return', retval)
|
||||||
|
|
||||||
@callback_wrapper
|
|
||||||
def unwind_callback(self, frame, code, *args):
|
def unwind_callback(self, frame, code, *args):
|
||||||
if frame.f_trace:
|
if frame.f_trace:
|
||||||
frame.f_trace(frame, 'return', None)
|
frame.f_trace(frame, 'return', None)
|
||||||
|
|
||||||
@callback_wrapper
|
|
||||||
def line_callback(self, frame, code, *args):
|
def line_callback(self, frame, code, *args):
|
||||||
if frame.f_trace and frame.f_trace_lines:
|
if frame.f_trace and frame.f_trace_lines:
|
||||||
frame.f_trace(frame, 'line', None)
|
frame.f_trace(frame, 'line', None)
|
||||||
|
|
||||||
@callback_wrapper
|
|
||||||
def jump_callback(self, frame, code, inst_offset, dest_offset):
|
def jump_callback(self, frame, code, inst_offset, dest_offset):
|
||||||
if dest_offset > inst_offset:
|
if dest_offset > inst_offset:
|
||||||
return sys.monitoring.DISABLE
|
return sys.monitoring.DISABLE
|
||||||
|
@ -141,7 +139,6 @@ class _MonitoringTracer:
|
||||||
if frame.f_trace and frame.f_trace_lines:
|
if frame.f_trace and frame.f_trace_lines:
|
||||||
frame.f_trace(frame, 'line', None)
|
frame.f_trace(frame, 'line', None)
|
||||||
|
|
||||||
@callback_wrapper
|
|
||||||
def exception_callback(self, frame, code, offset, exc):
|
def exception_callback(self, frame, code, offset, exc):
|
||||||
if frame.f_trace:
|
if frame.f_trace:
|
||||||
if exc.__traceback__ and hasattr(exc.__traceback__, 'tb_frame'):
|
if exc.__traceback__ and hasattr(exc.__traceback__, 'tb_frame'):
|
||||||
|
@ -152,7 +149,6 @@ class _MonitoringTracer:
|
||||||
tb = tb.tb_next
|
tb = tb.tb_next
|
||||||
frame.f_trace(frame, 'exception', (type(exc), exc, exc.__traceback__))
|
frame.f_trace(frame, 'exception', (type(exc), exc, exc.__traceback__))
|
||||||
|
|
||||||
@callback_wrapper
|
|
||||||
def opcode_callback(self, frame, code, offset):
|
def opcode_callback(self, frame, code, offset):
|
||||||
if frame.f_trace and frame.f_trace_opcodes:
|
if frame.f_trace and frame.f_trace_opcodes:
|
||||||
frame.f_trace(frame, 'opcode', None)
|
frame.f_trace(frame, 'opcode', None)
|
||||||
|
|
|
@ -2581,6 +2581,41 @@ def test_pdb_next_command_subiterator():
|
||||||
(Pdb) continue
|
(Pdb) continue
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def test_pdb_breakpoint_with_throw():
|
||||||
|
"""GH-132536: PY_THROW event should not be turned off
|
||||||
|
|
||||||
|
>>> reset_Breakpoint()
|
||||||
|
|
||||||
|
>>> def gen():
|
||||||
|
... yield 0
|
||||||
|
|
||||||
|
>>> def test_function():
|
||||||
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
|
... g = gen()
|
||||||
|
... try:
|
||||||
|
... g.throw(TypeError)
|
||||||
|
... except TypeError:
|
||||||
|
... pass
|
||||||
|
|
||||||
|
>>> with PdbTestInput([
|
||||||
|
... 'b 7',
|
||||||
|
... 'continue',
|
||||||
|
... 'clear 1',
|
||||||
|
... 'continue',
|
||||||
|
... ]):
|
||||||
|
... test_function()
|
||||||
|
> <doctest test.test_pdb.test_pdb_breakpoint_with_throw[2]>(2)test_function()
|
||||||
|
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
|
(Pdb) b 7
|
||||||
|
Breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_with_throw[2]>:7
|
||||||
|
(Pdb) continue
|
||||||
|
> <doctest test.test_pdb.test_pdb_breakpoint_with_throw[2]>(7)test_function()
|
||||||
|
-> pass
|
||||||
|
(Pdb) clear 1
|
||||||
|
Deleted breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_with_throw[2]>:7
|
||||||
|
(Pdb) continue
|
||||||
|
"""
|
||||||
|
|
||||||
def test_pdb_multiline_statement():
|
def test_pdb_multiline_statement():
|
||||||
"""Test for multiline statement
|
"""Test for multiline statement
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Do not disable :monitoring-event:`PY_THROW` event in :mod:`bdb` because it can't be disabled.
|
Loading…
Add table
Add a link
Reference in a new issue