https://github.com/python/cpython/commit/0eeaa0ef8bf60fd3b1448a615b6b1662d558990e
commit: 0eeaa0ef8bf60fd3b1448a615b6b1662d558990e
branch: main
author: Tian Gao <[email protected]>
committer: gaogaotiantian <[email protected]>
date: 2025-05-05T13:48:09-04:00
summary:
gh-133349: Enable auto-indent for pdb's multi-line mode (#133350)
files:
A Misc/NEWS.d/next/Library/2025-05-03-16-04-04.gh-issue-133349.kAhJDY.rst
M Doc/whatsnew/3.14.rst
M Lib/pdb.py
M Lib/test/test_pdb.py
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 0c4bd8600858f6..795403a9b7c107 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -1443,6 +1443,11 @@ pdb
fill in a 4-space indentation now, instead of inserting a ``\t`` character.
(Contributed by Tian Gao in :gh:`130471`.)
+* Auto-indent is introduced in :mod:`pdb` multi-line input. It will either
+ keep the indentation of the last line or insert a 4-space indentation when
+ it detects a new code block.
+ (Contributed by Tian Gao in :gh:`133350`.)
+
* ``$_asynctask`` is added to access the current asyncio task if applicable.
(Contributed by Tian Gao in :gh:`124367`.)
diff --git a/Lib/pdb.py b/Lib/pdb.py
index b30df59d793f24..0de8bbe37e471e 100644
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -745,12 +745,34 @@ def displayhook(self, obj):
self.message(repr(obj))
@contextmanager
- def _enable_multiline_completion(self):
+ def _enable_multiline_input(self):
+ try:
+ import readline
+ except ImportError:
+ yield
+ return
+
+ def input_auto_indent():
+ last_index = readline.get_current_history_length()
+ last_line = readline.get_history_item(last_index)
+ if last_line:
+ if last_line.isspace():
+ # If the last line is empty, we don't need to indent
+ return
+
+ last_line = last_line.rstrip('\r\n')
+ indent = len(last_line) - len(last_line.lstrip())
+ if last_line.endswith(":"):
+ indent += 4
+ readline.insert_text(' ' * indent)
+
completenames = self.completenames
try:
self.completenames = self.complete_multiline_names
+ readline.set_startup_hook(input_auto_indent)
yield
finally:
+ readline.set_startup_hook()
self.completenames = completenames
return
@@ -859,7 +881,7 @@ def _read_code(self, line):
try:
if (code := codeop.compile_command(line + '\n', '<stdin>',
'single')) is None:
# Multi-line mode
- with self._enable_multiline_completion():
+ with self._enable_multiline_input():
buffer = line
continue_prompt = "... "
while (code := codeop.compile_command(buffer, '<stdin>',
'single')) is None:
@@ -881,7 +903,11 @@ def _read_code(self, line):
return None, None, False
else:
line = line.rstrip('\r\n')
- buffer += '\n' + line
+ if line.isspace():
+ # empty line, just continue
+ buffer += '\n'
+ else:
+ buffer += '\n' + line
self.lastcmd = buffer
except SyntaxError as e:
# Maybe it's an await expression/statement
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 9223a7130d4e0d..05f2ec191d4e1c 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -4849,14 +4849,35 @@ def f():
self.assertIn(b'I love Python', output)
+ def test_multiline_auto_indent(self):
+ script = textwrap.dedent("""
+ import pdb; pdb.Pdb().set_trace()
+ """)
+
+ input = b"def f(x):\n"
+ input += b"if x > 0:\n"
+ input += b"x += 1\n"
+ input += b"return x\n"
+ # We need to do backspaces to remove the auto-indentation
+ input += b"\x08\x08\x08\x08else:\n"
+ input += b"return -x\n"
+ input += b"\n"
+ input += b"f(-21-21)\n"
+ input += b"c\n"
+
+ output = run_pty(script, input)
+
+ self.assertIn(b'42', output)
+
def test_multiline_completion(self):
script = textwrap.dedent("""
import pdb; pdb.Pdb().set_trace()
""")
input = b"def func():\n"
- # Complete: \treturn 40 + 2
- input += b"\tret\t 40 + 2\n"
+ # Auto-indent
+ # Complete: return 40 + 2
+ input += b"ret\t 40 + 2\n"
input += b"\n"
# Complete: func()
input += b"fun\t()\n"
@@ -4876,12 +4897,13 @@ def test_multiline_indent_completion(self):
# if the completion is not working as expected
input = textwrap.dedent("""\
def func():
- \ta = 1
- \ta += 1
- \ta += 1
- \tif a > 0:
- a += 1
- \t\treturn a
+ a = 1
+ \x08\ta += 1
+ \x08\x08\ta += 1
+ \x08\x08\x08\ta += 1
+ \x08\x08\x08\x08\tif a > 0:
+ a += 1
+ \x08\x08\x08\x08return a
func()
c
@@ -4889,7 +4911,7 @@ def func():
output = run_pty(script, input)
- self.assertIn(b'4', output)
+ self.assertIn(b'5', output)
self.assertNotIn(b'Error', output)
def test_interact_completion(self):
diff --git
a/Misc/NEWS.d/next/Library/2025-05-03-16-04-04.gh-issue-133349.kAhJDY.rst
b/Misc/NEWS.d/next/Library/2025-05-03-16-04-04.gh-issue-133349.kAhJDY.rst
new file mode 100644
index 00000000000000..cf0c19926c3688
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-05-03-16-04-04.gh-issue-133349.kAhJDY.rst
@@ -0,0 +1 @@
+Introduced auto-indent in :mod:`pdb` multi-line input.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]