mirror of https://github.com/python/cpython
gh-120254: Add a `commands` argument to `pdb.set_trace` (#120255)
This commit is contained in:
parent
fc9e6bf53d
commit
af8403a58d
|
@ -159,12 +159,15 @@ slightly different way:
|
||||||
is entered.
|
is entered.
|
||||||
|
|
||||||
|
|
||||||
.. function:: set_trace(*, header=None)
|
.. function:: set_trace(*, header=None, commands=None)
|
||||||
|
|
||||||
Enter the debugger at the calling stack frame. This is useful to hard-code
|
Enter the debugger at the calling stack frame. This is useful to hard-code
|
||||||
a breakpoint at a given point in a program, even if the code is not
|
a breakpoint at a given point in a program, even if the code is not
|
||||||
otherwise being debugged (e.g. when an assertion fails). If given,
|
otherwise being debugged (e.g. when an assertion fails). If given,
|
||||||
*header* is printed to the console just before debugging begins.
|
*header* is printed to the console just before debugging begins.
|
||||||
|
The *commands* argument, if given, is a list of commands to execute
|
||||||
|
when the debugger starts.
|
||||||
|
|
||||||
|
|
||||||
.. versionchanged:: 3.7
|
.. versionchanged:: 3.7
|
||||||
The keyword-only argument *header*.
|
The keyword-only argument *header*.
|
||||||
|
@ -173,6 +176,9 @@ slightly different way:
|
||||||
:func:`set_trace` will enter the debugger immediately, rather than
|
:func:`set_trace` will enter the debugger immediately, rather than
|
||||||
on the next line of code to be executed.
|
on the next line of code to be executed.
|
||||||
|
|
||||||
|
.. versionadded:: 3.14
|
||||||
|
The *commands* argument.
|
||||||
|
|
||||||
.. function:: post_mortem(traceback=None)
|
.. function:: post_mortem(traceback=None)
|
||||||
|
|
||||||
Enter post-mortem debugging of the given *traceback* object. If no
|
Enter post-mortem debugging of the given *traceback* object. If no
|
||||||
|
|
|
@ -389,11 +389,11 @@ class _OutputRedirectingPdb(pdb.Pdb):
|
||||||
# still use input() to get user input
|
# still use input() to get user input
|
||||||
self.use_rawinput = 1
|
self.use_rawinput = 1
|
||||||
|
|
||||||
def set_trace(self, frame=None):
|
def set_trace(self, frame=None, *, commands=None):
|
||||||
self.__debugger_used = True
|
self.__debugger_used = True
|
||||||
if frame is None:
|
if frame is None:
|
||||||
frame = sys._getframe().f_back
|
frame = sys._getframe().f_back
|
||||||
pdb.Pdb.set_trace(self, frame)
|
pdb.Pdb.set_trace(self, frame, commands=commands)
|
||||||
|
|
||||||
def set_continue(self):
|
def set_continue(self):
|
||||||
# Calling set_continue unconditionally would break unit test
|
# Calling set_continue unconditionally would break unit test
|
||||||
|
|
13
Lib/pdb.py
13
Lib/pdb.py
|
@ -361,10 +361,14 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
self._chained_exceptions = tuple()
|
self._chained_exceptions = tuple()
|
||||||
self._chained_exception_index = 0
|
self._chained_exception_index = 0
|
||||||
|
|
||||||
def set_trace(self, frame=None):
|
def set_trace(self, frame=None, *, commands=None):
|
||||||
Pdb._last_pdb_instance = self
|
Pdb._last_pdb_instance = self
|
||||||
if frame is None:
|
if frame is None:
|
||||||
frame = sys._getframe().f_back
|
frame = sys._getframe().f_back
|
||||||
|
|
||||||
|
if commands is not None:
|
||||||
|
self.rcLines.extend(commands)
|
||||||
|
|
||||||
super().set_trace(frame)
|
super().set_trace(frame)
|
||||||
|
|
||||||
def sigint_handler(self, signum, frame):
|
def sigint_handler(self, signum, frame):
|
||||||
|
@ -2350,13 +2354,14 @@ def runcall(*args, **kwds):
|
||||||
"""
|
"""
|
||||||
return Pdb().runcall(*args, **kwds)
|
return Pdb().runcall(*args, **kwds)
|
||||||
|
|
||||||
def set_trace(*, header=None):
|
def set_trace(*, header=None, commands=None):
|
||||||
"""Enter the debugger at the calling stack frame.
|
"""Enter the debugger at the calling stack frame.
|
||||||
|
|
||||||
This is useful to hard-code a breakpoint at a given point in a
|
This is useful to hard-code a breakpoint at a given point in a
|
||||||
program, even if the code is not otherwise being debugged (e.g. when
|
program, even if the code is not otherwise being debugged (e.g. when
|
||||||
an assertion fails). If given, *header* is printed to the console
|
an assertion fails). If given, *header* is printed to the console
|
||||||
just before debugging begins.
|
just before debugging begins. *commands* is an optional list of
|
||||||
|
pdb commands to run when the debugger starts.
|
||||||
"""
|
"""
|
||||||
if Pdb._last_pdb_instance is not None:
|
if Pdb._last_pdb_instance is not None:
|
||||||
pdb = Pdb._last_pdb_instance
|
pdb = Pdb._last_pdb_instance
|
||||||
|
@ -2364,7 +2369,7 @@ def set_trace(*, header=None):
|
||||||
pdb = Pdb()
|
pdb = Pdb()
|
||||||
if header is not None:
|
if header is not None:
|
||||||
pdb.message(header)
|
pdb.message(header)
|
||||||
pdb.set_trace(sys._getframe().f_back)
|
pdb.set_trace(sys._getframe().f_back, commands=commands)
|
||||||
|
|
||||||
# Post-Mortem interface
|
# Post-Mortem interface
|
||||||
|
|
||||||
|
|
|
@ -901,6 +901,17 @@ def test_pdb_where_command():
|
||||||
(Pdb) continue
|
(Pdb) continue
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def test_pdb_commands_with_set_trace():
|
||||||
|
"""Test that commands can be passed to Pdb.set_trace()
|
||||||
|
|
||||||
|
>>> def test_function():
|
||||||
|
... x = 1
|
||||||
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace(commands=['p x', 'c'])
|
||||||
|
|
||||||
|
>>> test_function()
|
||||||
|
1
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
# skip this test if sys.flags.no_site = True;
|
# skip this test if sys.flags.no_site = True;
|
||||||
# exit() isn't defined unless there's a site module.
|
# exit() isn't defined unless there's a site module.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Added ``commands`` argument to :func:`pdb.set_trace` which allows users to send debugger commands from the source file.
|
Loading…
Reference in New Issue