Skip to content

Commit b7240ed

Browse files
[3.13] gh-119824: Revert the where solution and use meta commands (#120919)
1 parent 1aadb51 commit b7240ed

File tree

4 files changed

+66
-81
lines changed

4 files changed

+66
-81
lines changed

Lib/pdb.py

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ def _validate_file_mtime(self):
519519

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

@@ -848,6 +846,10 @@ def onecmd(self, line):
848846
"""
849847
if not self.commands_defining:
850848
self._validate_file_mtime()
849+
if line.startswith('_pdbcmd'):
850+
command, arg, line = self.parseline(line)
851+
if hasattr(self, command):
852+
return getattr(self, command)(arg)
851853
return cmd.Cmd.onecmd(self, line)
852854
else:
853855
return self.handle_command_def(line)
@@ -981,6 +983,12 @@ def completedefault(self, text, line, begidx, endidx):
981983
state += 1
982984
return matches
983985

986+
# Pdb meta commands, only intended to be used internally by pdb
987+
988+
def _pdbcmd_print_frame_status(self, arg):
989+
self.print_stack_entry(self.stack[self.curindex])
990+
self._show_display()
991+
984992
# Command definitions, called by cmdloop()
985993
# The argument is the remaining string on the command line
986994
# Return true to exit from the command loop
@@ -1411,24 +1419,16 @@ def do_clear(self, arg):
14111419
complete_cl = _complete_location
14121420

14131421
def do_where(self, arg):
1414-
"""w(here) [count]
1422+
"""w(here)
14151423
1416-
Print a stack trace. If count is not specified, print the full stack.
1417-
If count is 0, print the current frame entry. If count is positive,
1418-
print count entries from the most recent frame. If count is negative,
1419-
print -count entries from the least recent frame.
1424+
Print a stack trace, with the most recent frame at the bottom.
14201425
An arrow indicates the "current frame", which determines the
14211426
context of most commands. 'bt' is an alias for this command.
14221427
"""
1423-
if not arg:
1424-
count = None
1425-
else:
1426-
try:
1427-
count = int(arg)
1428-
except ValueError:
1429-
self.error('Invalid count (%s)' % arg)
1430-
return
1431-
self.print_stack_trace(count)
1428+
if arg:
1429+
self._print_invalid_arg(arg)
1430+
return
1431+
self.print_stack_trace()
14321432
do_w = do_where
14331433
do_bt = do_where
14341434

@@ -2083,22 +2083,10 @@ def complete_unalias(self, text, line, begidx, endidx):
20832083
# It is also consistent with the up/down commands (which are
20842084
# compatible with dbx and gdb: up moves towards 'main()'
20852085
# and down moves towards the most recent stack frame).
2086-
# * if count is None, prints the full stack
2087-
# * if count = 0, prints the current frame entry
2088-
# * if count < 0, prints -count least recent frame entries
2089-
# * if count > 0, prints count most recent frame entries
2090-
2091-
def print_stack_trace(self, count=None):
2092-
if count is None:
2093-
stack_to_print = self.stack
2094-
elif count == 0:
2095-
stack_to_print = [self.stack[self.curindex]]
2096-
elif count < 0:
2097-
stack_to_print = self.stack[:-count]
2098-
else:
2099-
stack_to_print = self.stack[-count:]
2086+
2087+
def print_stack_trace(self):
21002088
try:
2101-
for frame_lineno in stack_to_print:
2089+
for frame_lineno in self.stack:
21022090
self.print_stack_entry(frame_lineno)
21032091
except KeyboardInterrupt:
21042092
pass

Lib/test/test_pdb.py

Lines changed: 39 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,37 @@ def test_pdb_pp_repr_exc():
491491
(Pdb) continue
492492
"""
493493

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

495526
def do_nothing():
496527
pass
@@ -781,85 +812,52 @@ def test_pdb_where_command():
781812
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
782813
783814
>>> def f():
784-
... g()
815+
... g();
785816
786817
>>> def test_function():
787818
... f()
788819
789820
>>> with PdbTestInput([ # doctest: +ELLIPSIS
790821
... 'w',
791822
... 'where',
792-
... 'w 1',
793-
... 'w invalid',
794823
... 'u',
795824
... 'w',
796-
... 'w 0',
797-
... 'w 100',
798-
... 'w -100',
799825
... 'continue',
800826
... ]):
801827
... test_function()
802828
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()
803829
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
804830
(Pdb) w
805831
...
806-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
832+
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
807833
-> test_function()
808834
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
809835
-> f()
810836
<doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
811-
-> g()
837+
-> g();
812838
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()
813839
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
814840
(Pdb) where
815841
...
816-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
842+
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
817843
-> test_function()
818844
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
819845
-> f()
820846
<doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
821-
-> g()
847+
-> g();
822848
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()
823849
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
824-
(Pdb) w 1
825-
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()
826-
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
827-
(Pdb) w invalid
828-
*** Invalid count (invalid)
829850
(Pdb) u
830851
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
831-
-> g()
852+
-> g();
832853
(Pdb) w
833854
...
834-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
835-
-> test_function()
836-
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
837-
-> f()
838-
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
839-
-> g()
840-
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()
841-
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
842-
(Pdb) w 0
843-
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
844-
-> g()
845-
(Pdb) w 100
846-
...
847-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
855+
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
848856
-> test_function()
849857
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
850858
-> f()
851859
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
852-
-> g()
853-
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()
854-
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
855-
(Pdb) w -100
856-
...
857-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
858-
-> test_function()
859-
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
860-
-> f()
861-
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
862-
-> g()
860+
-> g();
863861
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()
864862
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
865863
(Pdb) continue
@@ -3198,7 +3196,6 @@ def test_pdbrc_basic(self):
31983196
stdout, stderr = self.run_pdb_script(script, 'q\n', pdbrc=pdbrc, remove_home=True)
31993197
self.assertNotIn("SyntaxError", stdout)
32003198
self.assertIn("a+8=9", stdout)
3201-
self.assertIn("-> b = 2", stdout)
32023199

32033200
def test_pdbrc_empty_line(self):
32043201
"""Test that empty lines in .pdbrc are ignored."""

Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst

Lines changed: 0 additions & 1 deletion
This file was deleted.
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)