diff --git a/Lib/pdb.py b/Lib/pdb.py index 1af511788749db..3db3e6a5be1a7b 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -76,6 +76,7 @@ import dis import code import glob +import codeop import pprint import signal import inspect @@ -444,7 +445,30 @@ def default(self, line): locals = self.curframe_locals globals = self.curframe.f_globals try: - code = compile(line + '\n', '', 'single') + if (code := codeop.compile_command(line + '\n', '', 'single')) is None: + # Multi-line mode + buffer = line + continue_prompt = "... " + while (code := codeop.compile_command(buffer, '', 'single')) is None: + if self.use_rawinput: + try: + line = input(continue_prompt) + except (EOFError, KeyboardInterrupt): + self.lastcmd = "" + print('\n') + return + else: + self.stdout.write(continue_prompt) + self.stdout.flush() + line = self.stdin.readline() + if not len(line): + self.lastcmd = "" + self.stdout.write('\n') + self.stdout.flush() + return + else: + line = line.rstrip('\r\n') + buffer += '\n' + line save_stdout = sys.stdout save_stdin = sys.stdin save_displayhook = sys.displayhook diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 277400e152476f..a66953557e52dc 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -389,7 +389,7 @@ def test_pdb_breakpoints_preserved_across_interactive_sessions(): 1 breakpoint keep yes at ...test_pdb.py:... 2 breakpoint keep yes at ...test_pdb.py:... (Pdb) break pdb.find_function - Breakpoint 3 at ...pdb.py:97 + Breakpoint 3 at ...pdb.py:... (Pdb) break Num Type Disp Enb Where 1 breakpoint keep yes at ...test_pdb.py:... @@ -1589,6 +1589,32 @@ def test_pdb_next_command_subiterator(): (Pdb) continue """ +def test_pdb_multiline_statement(): + """Test for multiline statement + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... pass + + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'def f(x):', + ... ' return x * 2', + ... '', + ... 'f(2)', + ... 'c' + ... ]): + ... test_function() + > (3)test_function() + -> pass + (Pdb) def f(x): + ... return x * 2 + ... + (Pdb) f(2) + 4 + (Pdb) c + """ + + def test_pdb_issue_20766(): """Test for reference leaks when the SIGINT handler is set. @@ -2362,7 +2388,7 @@ def test_relative_imports_on_plain_module(self): def test_errors_in_command(self): commands = "\n".join([ - 'print(', + 'print(]', 'debug print(', 'debug doesnotexist', 'c', @@ -2371,7 +2397,8 @@ def test_errors_in_command(self): self.assertEqual(stdout.splitlines()[1:], [ '-> pass', - '(Pdb) *** SyntaxError: \'(\' was never closed', + "(Pdb) *** SyntaxError: closing parenthesis ']' does not match opening " + "parenthesis '('", '(Pdb) ENTERING RECURSIVE DEBUGGER', '*** SyntaxError: \'(\' was never closed', diff --git a/Misc/NEWS.d/next/Library/2023-04-09-03-53-02.gh-issue-103124.JspiNN.rst b/Misc/NEWS.d/next/Library/2023-04-09-03-53-02.gh-issue-103124.JspiNN.rst new file mode 100644 index 00000000000000..022524b369aa10 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-09-03-53-02.gh-issue-103124.JspiNN.rst @@ -0,0 +1 @@ +Added multiline statement support for :mod:`pdb` pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy