Skip to content

Commit 25a64fd

Browse files
GH-103124: Multiline statement support for pdb (GH-103125)
1 parent a4056c8 commit 25a64fd

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

Lib/pdb.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import dis
7777
import code
7878
import glob
79+
import codeop
7980
import pprint
8081
import signal
8182
import inspect
@@ -444,7 +445,30 @@ def default(self, line):
444445
locals = self.curframe_locals
445446
globals = self.curframe.f_globals
446447
try:
447-
code = compile(line + '\n', '<stdin>', 'single')
448+
if (code := codeop.compile_command(line + '\n', '<stdin>', 'single')) is None:
449+
# Multi-line mode
450+
buffer = line
451+
continue_prompt = "... "
452+
while (code := codeop.compile_command(buffer, '<stdin>', 'single')) is None:
453+
if self.use_rawinput:
454+
try:
455+
line = input(continue_prompt)
456+
except (EOFError, KeyboardInterrupt):
457+
self.lastcmd = ""
458+
print('\n')
459+
return
460+
else:
461+
self.stdout.write(continue_prompt)
462+
self.stdout.flush()
463+
line = self.stdin.readline()
464+
if not len(line):
465+
self.lastcmd = ""
466+
self.stdout.write('\n')
467+
self.stdout.flush()
468+
return
469+
else:
470+
line = line.rstrip('\r\n')
471+
buffer += '\n' + line
448472
save_stdout = sys.stdout
449473
save_stdin = sys.stdin
450474
save_displayhook = sys.displayhook

Lib/test/test_pdb.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ def test_pdb_breakpoints_preserved_across_interactive_sessions():
389389
1 breakpoint keep yes at ...test_pdb.py:...
390390
2 breakpoint keep yes at ...test_pdb.py:...
391391
(Pdb) break pdb.find_function
392-
Breakpoint 3 at ...pdb.py:97
392+
Breakpoint 3 at ...pdb.py:...
393393
(Pdb) break
394394
Num Type Disp Enb Where
395395
1 breakpoint keep yes at ...test_pdb.py:...
@@ -1589,6 +1589,32 @@ def test_pdb_next_command_subiterator():
15891589
(Pdb) continue
15901590
"""
15911591

1592+
def test_pdb_multiline_statement():
1593+
"""Test for multiline statement
1594+
1595+
>>> def test_function():
1596+
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
1597+
... pass
1598+
1599+
>>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
1600+
... 'def f(x):',
1601+
... ' return x * 2',
1602+
... '',
1603+
... 'f(2)',
1604+
... 'c'
1605+
... ]):
1606+
... test_function()
1607+
> <doctest test.test_pdb.test_pdb_multiline_statement[0]>(3)test_function()
1608+
-> pass
1609+
(Pdb) def f(x):
1610+
... return x * 2
1611+
...
1612+
(Pdb) f(2)
1613+
4
1614+
(Pdb) c
1615+
"""
1616+
1617+
15921618
def test_pdb_issue_20766():
15931619
"""Test for reference leaks when the SIGINT handler is set.
15941620
@@ -2362,7 +2388,7 @@ def test_relative_imports_on_plain_module(self):
23622388

23632389
def test_errors_in_command(self):
23642390
commands = "\n".join([
2365-
'print(',
2391+
'print(]',
23662392
'debug print(',
23672393
'debug doesnotexist',
23682394
'c',
@@ -2371,7 +2397,8 @@ def test_errors_in_command(self):
23712397

23722398
self.assertEqual(stdout.splitlines()[1:], [
23732399
'-> pass',
2374-
'(Pdb) *** SyntaxError: \'(\' was never closed',
2400+
"(Pdb) *** SyntaxError: closing parenthesis ']' does not match opening "
2401+
"parenthesis '('",
23752402

23762403
'(Pdb) ENTERING RECURSIVE DEBUGGER',
23772404
'*** SyntaxError: \'(\' was never closed',
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added multiline statement support for :mod:`pdb`

0 commit comments

Comments
 (0)
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