Skip to content

Commit

Permalink
[3.12] gh-119824: Revert the where solution and use meta commands (#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
gaogaotiantian authored Jun 23, 2024
1 parent 4e47f8a commit 69bd1a8
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 81 deletions.
61 changes: 23 additions & 38 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def _cmdloop(self):

# 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():
Expand All @@ -421,15 +421,13 @@ def interaction(self, frame, traceback):
self.setup(frame, traceback)
# 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()

Expand Down Expand Up @@ -532,6 +530,10 @@ def onecmd(self, line):
a breakpoint command list definition.
"""
if not self.commands_defining:
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)
Expand Down Expand Up @@ -631,6 +633,12 @@ def _complete_expression(self, text, line, begidx, endidx):
# Complete a simple name.
return [n for n in ns.keys() if n.startswith(text)]

# Pdb meta commands, only intended to be used internally by pdb

def _pdbcmd_print_frame_status(self, arg):
self.print_stack_entry(self.stack[self.curindex])
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
Expand Down Expand Up @@ -1053,24 +1061,13 @@ def do_clear(self, arg):
complete_cl = _complete_location

def do_where(self, arg):
"""w(here) [count]
"""w(here)
Print a stack trace. If count is not specified, print the full stack.
If count is 0, print the current frame entry. If count is positive,
print count entries from the most recent frame. If count is negative,
print -count entries from the least recent frame.
Print a stack trace, with the most recent frame at the bottom.
An arrow indicates the "current frame", which determines the
context of most commands. 'bt' is an alias for this command.
"""
if not arg:
count = None
else:
try:
count = int(arg)
except ValueError:
self.error('Invalid count (%s)' % arg)
return
self.print_stack_trace(count)
self.print_stack_trace()
do_w = do_where
do_bt = do_where

Expand Down Expand Up @@ -1642,22 +1639,10 @@ def complete_unalias(self, text, line, begidx, endidx):
# It is also consistent with the up/down commands (which are
# compatible with dbx and gdb: up moves towards 'main()'
# and down moves towards the most recent stack frame).
# * if count is None, prints the full stack
# * if count = 0, prints the current frame entry
# * if count < 0, prints -count least recent frame entries
# * if count > 0, prints count most recent frame entries

def print_stack_trace(self, count=None):
if count is None:
stack_to_print = self.stack
elif count == 0:
stack_to_print = [self.stack[self.curindex]]
elif count < 0:
stack_to_print = self.stack[:-count]
else:
stack_to_print = self.stack[-count:]

def print_stack_trace(self):
try:
for frame_lineno in stack_to_print:
for frame_lineno in self.stack:
self.print_stack_entry(frame_lineno)
except KeyboardInterrupt:
pass
Expand Down
82 changes: 40 additions & 42 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,38 @@ 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()
... pass
... 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]>(4)test_function()
-> pass
(Pdb) p x
1
(Pdb)
1
(Pdb) n ;; p 0 ;; p x
0
1
> <doctest test.test_pdb.test_pdb_empty_line[0]>(5)test_function()
-> y = 2
(Pdb)
1
(Pdb) continue
"""

def do_nothing():
pass
Expand Down Expand Up @@ -703,21 +735,16 @@ def test_pdb_where_command():
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
>>> def f():
... g()
... g();
>>> def test_function():
... f()
>>> with PdbTestInput([ # doctest: +ELLIPSIS
... 'w',
... 'where',
... 'w 1',
... 'w invalid',
... 'u',
... 'w',
... 'w 0',
... 'w 100',
... 'w -100',
... 'continue',
... ]):
... test_function()
Expand All @@ -726,63 +753,35 @@ def test_pdb_where_command():
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) w
...
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
-> test_function()
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
-> f()
<doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
-> g()
-> g();
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) where
...
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
-> test_function()
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
-> f()
<doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
-> g()
-> g();
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) w 1
> <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) w invalid
*** Invalid count (invalid)
(Pdb) u
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
-> g()
-> g();
(Pdb) w
...
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
-> test_function()
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
-> f()
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
-> g()
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) w 0
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
-> g()
(Pdb) w 100
...
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
<doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>()
-> test_function()
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
-> f()
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
-> g()
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) w -100
...
<doctest test.test_pdb.test_pdb_where_command[3]>(13)<module>()
-> test_function()
<doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function()
-> f()
> <doctest test.test_pdb.test_pdb_where_command[1]>(2)f()
-> g()
-> g();
<doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) continue
Expand Down Expand Up @@ -2299,7 +2298,6 @@ def test_pdbrc_basic(self):
stdout, stderr = self.run_pdb_script(script, 'q\n', pdbrc=pdbrc, remove_home=True)
self.assertNotIn("SyntaxError", stdout)
self.assertIn("a+8=9", stdout)
self.assertIn("-> b = 2", stdout)

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

This file was deleted.

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

0 comments on commit 69bd1a8

Please sign in to comment.