Skip to content

Commit 31ce5c0

Browse files
gh-120769: Add pdb meta command to print frame status. (#120770)
1 parent 3af7263 commit 31ce5c0

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

Lib/pdb.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ def _validate_file_mtime(self):
517517

518518
# Called before loop, handles display expressions
519519
# Set up convenience variable containers
520-
def preloop(self):
520+
def _show_display(self):
521521
displaying = self.displaying.get(self.curframe)
522522
if displaying:
523523
for expr, oldvalue in displaying.items():
@@ -605,15 +605,13 @@ def interaction(self, frame, tb_or_exc):
605605
self.setup(frame, tb)
606606
# We should print the stack entry if and only if the user input
607607
# is expected, and we should print it right before the user input.
608-
# If self.cmdqueue is not empty, we append a "w 0" command to the
609-
# queue, which is equivalent to print_stack_entry
610-
if self.cmdqueue:
611-
self.cmdqueue.append('w 0')
612-
else:
613-
self.print_stack_entry(self.stack[self.curindex])
608+
# We achieve this by appending _pdbcmd_print_frame_status to the
609+
# command queue. If cmdqueue is not exausted, the user input is
610+
# not expected and we will not print the stack entry.
611+
self.cmdqueue.append('_pdbcmd_print_frame_status')
614612
self._cmdloop()
615-
# If "w 0" is not used, pop it out
616-
if self.cmdqueue and self.cmdqueue[-1] == 'w 0':
613+
# If _pdbcmd_print_frame_status is not used, pop it out
614+
if self.cmdqueue and self.cmdqueue[-1] == '_pdbcmd_print_frame_status':
617615
self.cmdqueue.pop()
618616
self.forget()
619617

@@ -846,6 +844,10 @@ def onecmd(self, line):
846844
"""
847845
if not self.commands_defining:
848846
self._validate_file_mtime()
847+
if line.startswith('_pdbcmd'):
848+
command, arg, line = self.parseline(line)
849+
if hasattr(self, command):
850+
return getattr(self, command)(arg)
849851
return cmd.Cmd.onecmd(self, line)
850852
else:
851853
return self.handle_command_def(line)
@@ -982,6 +984,12 @@ def completedefault(self, text, line, begidx, endidx):
982984
state += 1
983985
return matches
984986

987+
# Pdb meta commands, only intended to be used internally by pdb
988+
989+
def _pdbcmd_print_frame_status(self, arg):
990+
self.print_stack_trace(0)
991+
self._show_display()
992+
985993
# Command definitions, called by cmdloop()
986994
# The argument is the remaining string on the command line
987995
# Return true to exit from the command loop

Lib/test/test_pdb.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,37 @@ def test_pdb_pp_repr_exc():
496496
(Pdb) continue
497497
"""
498498

499+
def test_pdb_empty_line():
500+
"""Test that empty line repeats the last command.
501+
502+
>>> def test_function():
503+
... x = 1
504+
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
505+
... y = 2
506+
507+
>>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
508+
... 'p x',
509+
... '', # Should repeat p x
510+
... 'n ;; p 0 ;; p x', # Fill cmdqueue with multiple commands
511+
... '', # Should still repeat p x
512+
... 'continue',
513+
... ]):
514+
... test_function()
515+
> <doctest test.test_pdb.test_pdb_empty_line[0]>(3)test_function()
516+
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
517+
(Pdb) p x
518+
1
519+
(Pdb)
520+
1
521+
(Pdb) n ;; p 0 ;; p x
522+
0
523+
1
524+
> <doctest test.test_pdb.test_pdb_empty_line[0]>(4)test_function()
525+
-> y = 2
526+
(Pdb)
527+
1
528+
(Pdb) continue
529+
"""
499530

500531
def do_nothing():
501532
pass
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make empty line in :mod:`pdb` repeats the last command even when the command is from ``cmdqueue``.

0 commit comments

Comments
 (0)