Skip to content

Commit 69bd1a8

Browse files
[3.12] gh-119824: Revert the where solution and use meta commands (#120928)
1 parent 4e47f8a commit 69bd1a8

File tree

4 files changed

+64
-81
lines changed

4 files changed

+64
-81
lines changed

Lib/pdb.py

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ def _cmdloop(self):
395395

396396
# Called before loop, handles display expressions
397397
# Set up convenience variable containers
398-
def preloop(self):
398+
def _show_display(self):
399399
displaying = self.displaying.get(self.curframe)
400400
if displaying:
401401
for expr, oldvalue in displaying.items():
@@ -421,15 +421,13 @@ def interaction(self, frame, traceback):
421421
self.setup(frame, traceback)
422422
# We should print the stack entry if and only if the user input
423423
# is expected, and we should print it right before the user input.
424-
# If self.cmdqueue is not empty, we append a "w 0" command to the
425-
# queue, which is equivalent to print_stack_entry
426-
if self.cmdqueue:
427-
self.cmdqueue.append('w 0')
428-
else:
429-
self.print_stack_entry(self.stack[self.curindex])
424+
# We achieve this by appending _pdbcmd_print_frame_status to the
425+
# command queue. If cmdqueue is not exausted, the user input is
426+
# not expected and we will not print the stack entry.
427+
self.cmdqueue.append('_pdbcmd_print_frame_status')
430428
self._cmdloop()
431-
# If "w 0" is not used, pop it out
432-
if self.cmdqueue and self.cmdqueue[-1] == 'w 0':
429+
# If _pdbcmd_print_frame_status is not used, pop it out
430+
if self.cmdqueue and self.cmdqueue[-1] == '_pdbcmd_print_frame_status':
433431
self.cmdqueue.pop()
434432
self.forget()
435433

@@ -532,6 +530,10 @@ def onecmd(self, line):
532530
a breakpoint command list definition.
533531
"""
534532
if not self.commands_defining:
533+
if line.startswith('_pdbcmd'):
534+
command, arg, line = self.parseline(line)
535+
if hasattr(self, command):
536+
return getattr(self, command)(arg)
535537
return cmd.Cmd.onecmd(self, line)
536538
else:
537539
return self.handle_command_def(line)
@@ -631,6 +633,12 @@ def _complete_expression(self, text, line, begidx, endidx):
631633
# Complete a simple name.
632634
return [n for n in ns.keys() if n.startswith(text)]
633635

636+
# Pdb meta commands, only intended to be used internally by pdb
637+
638+
def _pdbcmd_print_frame_status(self, arg):
639+
self.print_stack_entry(self.stack[self.curindex])
640+
self._show_display()
641+
634642
# Command definitions, called by cmdloop()
635643
# The argument is the remaining string on the command line
636644
# Return true to exit from the command loop
@@ -1053,24 +1061,13 @@ def do_clear(self, arg):
10531061
complete_cl = _complete_location
10541062

10551063
def do_where(self, arg):
1056-
"""w(here) [count]
1064+
"""w(here)
10571065
1058-
Print a stack trace. If count is not specified, print the full stack.
1059-
If count is 0, print the current frame entry. If count is positive,
1060-
print count entries from the most recent frame. If count is negative,
1061-
print -count entries from the least recent frame.
1066+
Print a stack trace, with the most recent frame at the bottom.
10621067
An arrow indicates the "current frame", which determines the
10631068
context of most commands. 'bt' is an alias for this command.
10641069
"""
1065-
if not arg:
1066-
count = None
1067-
else:
1068-
try:
1069-
count = int(arg)
1070-
except ValueError:
1071-
self.error('Invalid count (%s)' % arg)
1072-
return
1073-
self.print_stack_trace(count)
1070+
self.print_stack_trace()
10741071
do_w = do_where
10751072
do_bt = do_where
10761073

@@ -1642,22 +1639,10 @@ def complete_unalias(self, text, line, begidx, endidx):
16421639
# It is also consistent with the up/down commands (which are
16431640
# compatible with dbx and gdb: up moves towards 'main()'
16441641
# and down moves towards the most recent stack frame).
1645-
# * if count is None, prints the full stack
1646-
# * if count = 0, prints the current frame entry
1647-
# * if count < 0, prints -count least recent frame entries
1648-
# * if count > 0, prints count most recent frame entries
1649-
1650-
def print_stack_trace(self, count=None):
1651-
if count is None:
1652-
stack_to_print = self.stack
1653-
elif count == 0:
1654-
stack_to_print = [self.stack[self.curindex]]
1655-
elif count < 0:
1656-
stack_to_print = self.stack[:-count]
1657-
else:
1658-
stack_to_print = self.stack[-count:]
1642+
1643+
def print_stack_trace(self):
16591644
try:
1660-
for frame_lineno in stack_to_print:
1645+
for frame_lineno in self.stack:
16611646
self.print_stack_entry(frame_lineno)
16621647
except KeyboardInterrupt:
16631648
pass

Lib/test/test_pdb.py

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,38 @@ def test_pdb_pp_repr_exc():
446446
(Pdb) continue
447447
"""
448448

449+
def test_pdb_empty_line():
450+
"""Test that empty line repeats the last command.
451+
452+
>>> def test_function():
453+
... x = 1
454+
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
455+
... pass
456+
... y = 2
457+
458+
>>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
459+
... 'p x',
460+
... '', # Should repeat p x
461+
... 'n ;; p 0 ;; p x', # Fill cmdqueue with multiple commands
462+
... '', # Should still repeat p x
463+
... 'continue',
464+
... ]):
465+
... test_function()
466+
> <doctest test.test_pdb.test_pdb_empty_line[0]>(4)test_function()
467+
-> pass
468+
(Pdb) p x
469+
1
470+
(Pdb)
471+
1
472+
(Pdb) n ;; p 0 ;; p x
473+
0
474+
1
475+
> <doctest test.test_pdb.test_pdb_empty_line[0]>(5)test_function()
476+
-> y = 2
477+
(Pdb)
478+
1
479+
(Pdb) continue
480+
"""
449481

450482
def do_nothing():
451483
pass
@@ -703,21 +735,16 @@ def test_pdb_where_command():
703735
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
704736
705737
>>> def f():
706-
... g()
738+
... g();
707739
708740
>>> def test_function():
709741
... f()
710742
711743
>>> with PdbTestInput([ # doctest: +ELLIPSIS
712744
... 'w',
713745
... 'where',
714-
... 'w 1',
715-
... 'w invalid',
716746
... 'u',
717747
... 'w',
718-
... 'w 0',
719-
... 'w 100',
720-
... 'w -100',
721748
... 'continue',
722749
... ]):
723750
... test_function()
@@ -726,63 +753,35 @@ def test_pdb_where_command():
726753
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
727754
(Pdb) w
728755
...
729-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
756+
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
730757
-> test_function()
731758
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
732759
-> f()
733760
<doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
734-
-> g()
761+
-> g();
735762
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
736763
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
737764
(Pdb) where
738765
...
739-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
766+
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
740767
-> test_function()
741768
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
742769
-> f()
743770
<doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
744-
-> g()
771+
-> g();
745772
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
746773
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
747-
(Pdb) w 1
748-
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
749-
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
750-
(Pdb) w invalid
751-
*** Invalid count (invalid)
752774
(Pdb) u
753775
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
754-
-> g()
776+
-> g();
755777
(Pdb) w
756778
...
757-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
758-
-> test_function()
759-
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
760-
-> f()
761-
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
762-
-> g()
763-
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
764-
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
765-
(Pdb) w 0
766-
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
767-
-> g()
768-
(Pdb) w 100
769-
...
770-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
779+
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
771780
-> test_function()
772781
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
773782
-> f()
774783
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
775-
-> g()
776-
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
777-
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
778-
(Pdb) w -100
779-
...
780-
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
781-
-> test_function()
782-
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
783-
-> f()
784-
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
785-
-> g()
784+
-> g();
786785
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
787786
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
788787
(Pdb) continue
@@ -2299,7 +2298,6 @@ def test_pdbrc_basic(self):
22992298
stdout, stderr = self.run_pdb_script(script, 'q\n', pdbrc=pdbrc, remove_home=True)
23002299
self.assertNotIn("SyntaxError", stdout)
23012300
self.assertIn("a+8=9", stdout)
2302-
self.assertIn("-> b = 2", stdout)
23032301

23042302
def test_pdbrc_empty_line(self):
23052303
"""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)