gh-120769: Add pdb meta command to print frame status. (#120770)

This commit is contained in:
Tian Gao 2024-06-20 10:38:07 -07:00 committed by GitHub
parent 3af7263037
commit 31ce5c05a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 9 deletions

View File

@ -517,7 +517,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
# Called before loop, handles display expressions
# Set up convenience variable containers
def preloop(self):
def _show_display(self):
displaying = self.displaying.get(self.curframe)
if displaying:
for expr, oldvalue in displaying.items():
@ -605,15 +605,13 @@ class Pdb(bdb.Bdb, cmd.Cmd):
self.setup(frame, tb)
# We should print the stack entry if and only if the user input
# is expected, and we should print it right before the user input.
# If self.cmdqueue is not empty, we append a "w 0" command to the
# queue, which is equivalent to print_stack_entry
if self.cmdqueue:
self.cmdqueue.append('w 0')
else:
self.print_stack_entry(self.stack[self.curindex])
# We achieve this by appending _pdbcmd_print_frame_status to the
# command queue. If cmdqueue is not exausted, the user input is
# not expected and we will not print the stack entry.
self.cmdqueue.append('_pdbcmd_print_frame_status')
self._cmdloop()
# If "w 0" is not used, pop it out
if self.cmdqueue and self.cmdqueue[-1] == 'w 0':
# If _pdbcmd_print_frame_status is not used, pop it out
if self.cmdqueue and self.cmdqueue[-1] == '_pdbcmd_print_frame_status':
self.cmdqueue.pop()
self.forget()
@ -846,6 +844,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
"""
if not self.commands_defining:
self._validate_file_mtime()
if line.startswith('_pdbcmd'):
command, arg, line = self.parseline(line)
if hasattr(self, command):
return getattr(self, command)(arg)
return cmd.Cmd.onecmd(self, line)
else:
return self.handle_command_def(line)
@ -982,6 +984,12 @@ class Pdb(bdb.Bdb, cmd.Cmd):
state += 1
return matches
# Pdb meta commands, only intended to be used internally by pdb
def _pdbcmd_print_frame_status(self, arg):
self.print_stack_trace(0)
self._show_display()
# Command definitions, called by cmdloop()
# The argument is the remaining string on the command line
# Return true to exit from the command loop

View File

@ -496,6 +496,37 @@ def test_pdb_pp_repr_exc():
(Pdb) continue
"""
def test_pdb_empty_line():
"""Test that empty line repeats the last command.
>>> def test_function():
... x = 1
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
... y = 2
>>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
... 'p x',
... '', # Should repeat p x
... 'n ;; p 0 ;; p x', # Fill cmdqueue with multiple commands
... '', # Should still repeat p x
... 'continue',
... ]):
... test_function()
> <doctest test.test_pdb.test_pdb_empty_line[0]>(3)test_function()
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) p x
1
(Pdb)
1
(Pdb) n ;; p 0 ;; p x
0
1
> <doctest test.test_pdb.test_pdb_empty_line[0]>(4)test_function()
-> y = 2
(Pdb)
1
(Pdb) continue
"""
def do_nothing():
pass

View File

@ -0,0 +1 @@
Make empty line in :mod:`pdb` repeats the last command even when the command is from ``cmdqueue``.