summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xLib/pdb.py64
-rw-r--r--Lib/test/test_pdb.py81
-rw-r--r--Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst1
-rw-r--r--Misc/NEWS.d/next/Library/2024-06-20-01-31-24.gh-issue-120769.PfiMrc.rst1
4 files changed, 66 insertions, 81 deletions
diff --git a/Lib/pdb.py b/Lib/pdb.py
index 9e32423..8783773 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -519,7 +519,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
# 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():
@@ -607,15 +607,13 @@ class Pdb(bdb.Bdb, cmd.Cmd):
self.setup(frame, tb)
# 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()
@@ -848,6 +846,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
"""
if not self.commands_defining:
self._validate_file_mtime()
+ 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)
@@ -981,6 +983,12 @@ class Pdb(bdb.Bdb, cmd.Cmd):
state += 1
return matches
+ # 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
@@ -1411,24 +1419,16 @@ class Pdb(bdb.Bdb, cmd.Cmd):
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)
+ if arg:
+ self._print_invalid_arg(arg)
+ return
+ self.print_stack_trace()
do_w = do_where
do_bt = do_where
@@ -2083,22 +2083,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
# 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
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index d43e744..4b3557f 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -491,6 +491,37 @@ 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()
+ ... 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]>(3)test_function()
+ -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+ (Pdb) p x
+ 1
+ (Pdb)
+ 1
+ (Pdb) n ;; p 0 ;; p x
+ 0
+ 1
+ > <doctest test.test_pdb.test_pdb_empty_line[0]>(4)test_function()
+ -> y = 2
+ (Pdb)
+ 1
+ (Pdb) continue
+ """
def do_nothing():
pass
@@ -781,7 +812,7 @@ def test_pdb_where_command():
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
>>> def f():
- ... g()
+ ... g();
>>> def test_function():
... f()
@@ -789,13 +820,8 @@ def test_pdb_where_command():
>>> with PdbTestInput([ # doctest: +ELLIPSIS
... 'w',
... 'where',
- ... 'w 1',
- ... 'w invalid',
... 'u',
... 'w',
- ... 'w 0',
- ... 'w 100',
- ... 'w -100',
... 'continue',
... ]):
... test_function()
@@ -803,63 +829,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()
-> 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()
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
- (Pdb) w 1
- > <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()
- -> 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()
- -> 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()
- -> 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()
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
(Pdb) continue
@@ -3198,7 +3196,6 @@ def bœr():
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."""
diff --git a/Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst b/Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst
deleted file mode 100644
index fd6d8d7..0000000
--- a/Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst
+++ /dev/null
@@ -1 +0,0 @@
-Print stack entry in :mod:`pdb` when and only when user input is needed.
diff --git a/Misc/NEWS.d/next/Library/2024-06-20-01-31-24.gh-issue-120769.PfiMrc.rst b/Misc/NEWS.d/next/Library/2024-06-20-01-31-24.gh-issue-120769.PfiMrc.rst
new file mode 100644
index 0000000..8ee6bf1
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-20-01-31-24.gh-issue-120769.PfiMrc.rst
@@ -0,0 +1 @@
+Make empty line in :mod:`pdb` repeats the last command even when the command is from ``cmdqueue``.