Skip to content

Commit e4f1fed

Browse files
[3.12] gh-119824: Print stack entry when user input is needed … (#120594)
Co-authored-by: Irit Katriel <[email protected]>
1 parent e004914 commit e4f1fed

File tree

3 files changed

+82
-16
lines changed

3 files changed

+82
-16
lines changed

Lib/pdb.py

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,18 @@ def interaction(self, frame, traceback):
419419
else:
420420
Pdb._previous_sigint_handler = None
421421
self.setup(frame, traceback)
422-
# if we have more commands to process, do not show the stack entry
423-
if not self.cmdqueue:
422+
# We should print the stack entry if and only if the user input
423+
# 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:
424429
self.print_stack_entry(self.stack[self.curindex])
425430
self._cmdloop()
431+
# If "w 0" is not used, pop it out
432+
if self.cmdqueue and self.cmdqueue[-1] == 'w 0':
433+
self.cmdqueue.pop()
426434
self.forget()
427435

428436
def displayhook(self, obj):
@@ -1045,13 +1053,24 @@ def do_clear(self, arg):
10451053
complete_cl = _complete_location
10461054

10471055
def do_where(self, arg):
1048-
"""w(here)
1056+
"""w(here) [count]
10491057
1050-
Print a stack trace, with the most recent frame at the bottom.
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.
10511062
An arrow indicates the "current frame", which determines the
10521063
context of most commands. 'bt' is an alias for this command.
10531064
"""
1054-
self.print_stack_trace()
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)
10551074
do_w = do_where
10561075
do_bt = do_where
10571076

@@ -1623,10 +1642,22 @@ def complete_unalias(self, text, line, begidx, endidx):
16231642
# It is also consistent with the up/down commands (which are
16241643
# compatible with dbx and gdb: up moves towards 'main()'
16251644
# and down moves towards the most recent stack frame).
1626-
1627-
def print_stack_trace(self):
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:]
16281659
try:
1629-
for frame_lineno in self.stack:
1660+
for frame_lineno in stack_to_print:
16301661
self.print_stack_entry(frame_lineno)
16311662
except KeyboardInterrupt:
16321663
pass

Lib/test/test_pdb.py

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -703,16 +703,21 @@ def test_pdb_where_command():
703703
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
704704
705705
>>> def f():
706-
... g();
706+
... g()
707707
708708
>>> def test_function():
709709
... f()
710710
711711
>>> with PdbTestInput([ # doctest: +ELLIPSIS
712712
... 'w',
713713
... 'where',
714+
... 'w 1',
715+
... 'w invalid',
714716
... 'u',
715717
... 'w',
718+
... 'w 0',
719+
... 'w 100',
720+
... 'w -100',
716721
... 'continue',
717722
... ]):
718723
... test_function()
@@ -721,35 +726,63 @@ def test_pdb_where_command():
721726
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
722727
(Pdb) w
723728
...
724-
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
729+
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
725730
-> test_function()
726731
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
727732
-> f()
728733
<doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
729-
-> g();
734+
-> g()
730735
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
731736
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
732737
(Pdb) where
733738
...
734-
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
739+
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
735740
-> test_function()
736741
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
737742
-> f()
738743
<doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
739-
-> g();
744+
-> g()
740745
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
741746
-> 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)
742752
(Pdb) u
743753
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
744-
-> g();
754+
-> g()
745755
(Pdb) w
746756
...
747-
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
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>()
748771
-> test_function()
749772
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
750773
-> f()
751774
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
752-
-> g();
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()
753786
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
754787
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
755788
(Pdb) continue
@@ -2266,6 +2299,7 @@ def test_pdbrc_basic(self):
22662299
stdout, stderr = self.run_pdb_script(script, 'q\n', pdbrc=pdbrc, remove_home=True)
22672300
self.assertNotIn("SyntaxError", stdout)
22682301
self.assertIn("a+8=9", stdout)
2302+
self.assertIn("-> b = 2", stdout)
22692303

22702304
def test_pdbrc_empty_line(self):
22712305
"""Test that empty lines in .pdbrc are ignored."""
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Print stack entry in :mod:`pdb` when and only when user input is needed.

0 commit comments

Comments
 (0)