From 537bac7a23d53658bf1bf172fcaf28495f722d15 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sun, 23 Jun 2024 14:29:32 -0700 Subject: [PATCH 1/3] =?UTF-8?q?Revert=20"[3.12]=20gh-119824:=20Print=20sta?= =?UTF-8?q?ck=20entry=20when=20user=20input=20is=20needed=20=E2=80=A6=20(#?= =?UTF-8?q?120594)"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit e4f1fed5f6bb788d6d5a86bdbb770d25066636d1. --- Lib/pdb.py | 47 +++-------------- Lib/test/test_pdb.py | 50 +++---------------- ...-05-31-21-17-43.gh-issue-119824.CQlxWV.rst | 1 - 3 files changed, 16 insertions(+), 82 deletions(-) delete mode 100644 Misc/NEWS.d/next/Library/2024-05-31-21-17-43.gh-issue-119824.CQlxWV.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index 2ad5a321a43c46..225c9f253ef310 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -419,18 +419,10 @@ def interaction(self, frame, traceback): else: Pdb._previous_sigint_handler = None 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: + # if we have more commands to process, do not show the stack entry + if not self.cmdqueue: self.print_stack_entry(self.stack[self.curindex]) self._cmdloop() - # If "w 0" is not used, pop it out - if self.cmdqueue and self.cmdqueue[-1] == 'w 0': - self.cmdqueue.pop() self.forget() def displayhook(self, obj): @@ -1053,24 +1045,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 @@ -1642,22 +1623,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 diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 15c50ba01fdf39..24324a37804ca0 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -703,7 +703,7 @@ def test_pdb_where_command(): ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() >>> def f(): - ... g() + ... g(); >>> def test_function(): ... f() @@ -711,13 +711,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() @@ -726,63 +721,35 @@ def test_pdb_where_command(): -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() (Pdb) w ... - (13)() + (8)() -> test_function() (2)test_function() -> f() (2)f() - -> g() + -> g(); > (2)g()->None -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() (Pdb) where ... - (13)() + (8)() -> test_function() (2)test_function() -> f() (2)f() - -> g() + -> g(); > (2)g()->None -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() - (Pdb) w 1 - > (2)g()->None - -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() - (Pdb) w invalid - *** Invalid count (invalid) (Pdb) u > (2)f() - -> g() + -> g(); (Pdb) w ... - (13)() - -> test_function() - (2)test_function() - -> f() - > (2)f() - -> g() - (2)g()->None - -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() - (Pdb) w 0 - > (2)f() - -> g() - (Pdb) w 100 - ... - (13)() + (8)() -> test_function() (2)test_function() -> f() > (2)f() - -> g() - (2)g()->None - -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() - (Pdb) w -100 - ... - (13)() - -> test_function() - (2)test_function() - -> f() - > (2)f() - -> g() + -> g(); (2)g()->None -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() (Pdb) continue @@ -2299,7 +2266,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.""" 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 fd6d8d79a9d157..00000000000000 --- 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. From 5b0cf9bb6cd160d710e96bea7d49b4a9514d8247 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 20 Jun 2024 10:38:07 -0700 Subject: [PATCH 2/3] gh-120769: Add pdb meta command to print frame status. (#120770) --- Lib/pdb.py | 24 +++++++++++--- Lib/test/test_pdb.py | 32 +++++++++++++++++++ ...-06-20-01-31-24.gh-issue-120769.PfiMrc.rst | 1 + 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-06-20-01-31-24.gh-issue-120769.PfiMrc.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index 225c9f253ef310..89cf975164ac04 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -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(): @@ -419,10 +419,16 @@ def interaction(self, frame, traceback): else: Pdb._previous_sigint_handler = None self.setup(frame, traceback) - # if we have more commands to process, do not show the stack entry - if not self.cmdqueue: - self.print_stack_entry(self.stack[self.curindex]) + # 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. + # 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 _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() def displayhook(self, obj): @@ -524,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) @@ -623,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 diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 24324a37804ca0..5abe7b865214b2 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -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() + > (4)test_function() + -> pass + (Pdb) p x + 1 + (Pdb) + 1 + (Pdb) n ;; p 0 ;; p x + 0 + 1 + > (5)test_function() + -> y = 2 + (Pdb) + 1 + (Pdb) continue + """ def do_nothing(): pass 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 00000000000000..8ee6bf1a9c6480 --- /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``. From 98ec82244d3cb4f8b9b47a8c4ac94627720b2315 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sun, 23 Jun 2024 14:36:53 -0700 Subject: [PATCH 3/3] Fix empty line --- Lib/test/test_pdb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 5abe7b865214b2..8a7e41b281165e 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -467,14 +467,14 @@ def test_pdb_empty_line(): -> pass (Pdb) p x 1 - (Pdb) + (Pdb) 1 (Pdb) n ;; p 0 ;; p x 0 1 > (5)test_function() -> y = 2 - (Pdb) + (Pdb) 1 (Pdb) continue """