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

+25-1
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

+30-3
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',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added multiline statement support for :mod:`pdb`

0 commit comments

Comments
 (0)