mirror of https://github.com/python/cpython
gh-102980: Redirect output of pdb's `interact` command, add tests and improve docs (#111194)
This commit is contained in:
parent
4b125dd31a
commit
3d712a9f4c
|
@ -570,10 +570,27 @@ can be overridden by the local file.
|
||||||
|
|
||||||
Start an interactive interpreter (using the :mod:`code` module) whose global
|
Start an interactive interpreter (using the :mod:`code` module) whose global
|
||||||
namespace contains all the (global and local) names found in the current
|
namespace contains all the (global and local) names found in the current
|
||||||
scope.
|
scope. Use ``exit()`` or ``quit()`` to exit the interpreter and return to
|
||||||
|
the debugger.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Because interact creates a new global namespace with the current global
|
||||||
|
and local namespace for execution, assignment to variables will not
|
||||||
|
affect the original namespaces.
|
||||||
|
However, modification to the mutable objects will be reflected in the
|
||||||
|
original namespaces.
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
.. versionadded:: 3.13
|
||||||
|
``exit()`` and ``quit()`` can be used to exit :pdbcmd:`interact`
|
||||||
|
command.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.13
|
||||||
|
:pdbcmd:`interact` directs its output to the debugger's
|
||||||
|
output channel rather than :data:`sys.stderr`.
|
||||||
|
|
||||||
.. _debugger-aliases:
|
.. _debugger-aliases:
|
||||||
|
|
||||||
.. pdbcommand:: alias [name [command]]
|
.. pdbcommand:: alias [name [command]]
|
||||||
|
|
17
Lib/pdb.py
17
Lib/pdb.py
|
@ -207,6 +207,15 @@ class _ModuleTarget(str):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class _PdbInteractiveConsole(code.InteractiveConsole):
|
||||||
|
def __init__(self, ns, message):
|
||||||
|
self._message = message
|
||||||
|
super().__init__(locals=ns, local_exit=True)
|
||||||
|
|
||||||
|
def write(self, data):
|
||||||
|
self._message(data, end='')
|
||||||
|
|
||||||
|
|
||||||
# Interaction prompt line will separate file and call info from code
|
# Interaction prompt line will separate file and call info from code
|
||||||
# text using value of line_prefix string. A newline and arrow may
|
# text using value of line_prefix string. A newline and arrow may
|
||||||
# be to your liking. You can set it once pdb is imported using the
|
# be to your liking. You can set it once pdb is imported using the
|
||||||
|
@ -672,8 +681,8 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
|
|
||||||
# interface abstraction functions
|
# interface abstraction functions
|
||||||
|
|
||||||
def message(self, msg):
|
def message(self, msg, end='\n'):
|
||||||
print(msg, file=self.stdout)
|
print(msg, end=end, file=self.stdout)
|
||||||
|
|
||||||
def error(self, msg):
|
def error(self, msg):
|
||||||
print('***', msg, file=self.stdout)
|
print('***', msg, file=self.stdout)
|
||||||
|
@ -1786,7 +1795,9 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
contains all the (global and local) names found in the current scope.
|
contains all the (global and local) names found in the current scope.
|
||||||
"""
|
"""
|
||||||
ns = {**self.curframe.f_globals, **self.curframe_locals}
|
ns = {**self.curframe.f_globals, **self.curframe_locals}
|
||||||
code.interact("*interactive*", local=ns, local_exit=True)
|
console = _PdbInteractiveConsole(ns, message=self.message)
|
||||||
|
console.interact(banner="*pdb interact start*",
|
||||||
|
exitmsg="*exit from pdb interact command*")
|
||||||
|
|
||||||
def do_alias(self, arg):
|
def do_alias(self, arg):
|
||||||
"""alias [name [command]]
|
"""alias [name [command]]
|
||||||
|
|
|
@ -778,6 +778,59 @@ def test_pdb_where_command():
|
||||||
(Pdb) continue
|
(Pdb) continue
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def test_pdb_interact_command():
|
||||||
|
"""Test interact command
|
||||||
|
|
||||||
|
>>> g = 0
|
||||||
|
>>> dict_g = {}
|
||||||
|
|
||||||
|
>>> def test_function():
|
||||||
|
... x = 1
|
||||||
|
... lst_local = []
|
||||||
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
|
|
||||||
|
>>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
|
||||||
|
... 'interact',
|
||||||
|
... 'x',
|
||||||
|
... 'g',
|
||||||
|
... 'x = 2',
|
||||||
|
... 'g = 3',
|
||||||
|
... 'dict_g["a"] = True',
|
||||||
|
... 'lst_local.append(x)',
|
||||||
|
... 'exit()',
|
||||||
|
... 'p x',
|
||||||
|
... 'p g',
|
||||||
|
... 'p dict_g',
|
||||||
|
... 'p lst_local',
|
||||||
|
... 'continue',
|
||||||
|
... ]):
|
||||||
|
... test_function()
|
||||||
|
--Return--
|
||||||
|
> <doctest test.test_pdb.test_pdb_interact_command[2]>(4)test_function()->None
|
||||||
|
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
|
(Pdb) interact
|
||||||
|
*pdb interact start*
|
||||||
|
... x
|
||||||
|
1
|
||||||
|
... g
|
||||||
|
0
|
||||||
|
... x = 2
|
||||||
|
... g = 3
|
||||||
|
... dict_g["a"] = True
|
||||||
|
... lst_local.append(x)
|
||||||
|
... exit()
|
||||||
|
*exit from pdb interact command*
|
||||||
|
(Pdb) p x
|
||||||
|
1
|
||||||
|
(Pdb) p g
|
||||||
|
0
|
||||||
|
(Pdb) p dict_g
|
||||||
|
{'a': True}
|
||||||
|
(Pdb) p lst_local
|
||||||
|
[2]
|
||||||
|
(Pdb) continue
|
||||||
|
"""
|
||||||
|
|
||||||
def test_convenience_variables():
|
def test_convenience_variables():
|
||||||
"""Test convenience variables
|
"""Test convenience variables
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Redirect the output of ``interact`` command of :mod:`pdb` to the same channel as the debugger. Add tests and improve docs.
|
Loading…
Reference in New Issue