mirror of
https://github.com/python/cpython.git
synced 2025-09-01 14:38:00 +00:00
gh-133349: Enable auto-indent for pdb's multi-line mode (#133350)
This commit is contained in:
parent
4ac916ae33
commit
0eeaa0ef8b
4 changed files with 66 additions and 12 deletions
|
@ -1443,6 +1443,11 @@ pdb
|
||||||
fill in a 4-space indentation now, instead of inserting a ``\t`` character.
|
fill in a 4-space indentation now, instead of inserting a ``\t`` character.
|
||||||
(Contributed by Tian Gao in :gh:`130471`.)
|
(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.
|
* ``$_asynctask`` is added to access the current asyncio task if applicable.
|
||||||
(Contributed by Tian Gao in :gh:`124367`.)
|
(Contributed by Tian Gao in :gh:`124367`.)
|
||||||
|
|
||||||
|
|
30
Lib/pdb.py
30
Lib/pdb.py
|
@ -745,12 +745,34 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
self.message(repr(obj))
|
self.message(repr(obj))
|
||||||
|
|
||||||
@contextmanager
|
@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
|
completenames = self.completenames
|
||||||
try:
|
try:
|
||||||
self.completenames = self.complete_multiline_names
|
self.completenames = self.complete_multiline_names
|
||||||
|
readline.set_startup_hook(input_auto_indent)
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
|
readline.set_startup_hook()
|
||||||
self.completenames = completenames
|
self.completenames = completenames
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -859,7 +881,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
try:
|
try:
|
||||||
if (code := codeop.compile_command(line + '\n', '<stdin>', 'single')) is None:
|
if (code := codeop.compile_command(line + '\n', '<stdin>', 'single')) is None:
|
||||||
# Multi-line mode
|
# Multi-line mode
|
||||||
with self._enable_multiline_completion():
|
with self._enable_multiline_input():
|
||||||
buffer = line
|
buffer = line
|
||||||
continue_prompt = "... "
|
continue_prompt = "... "
|
||||||
while (code := codeop.compile_command(buffer, '<stdin>', 'single')) is None:
|
while (code := codeop.compile_command(buffer, '<stdin>', 'single')) is None:
|
||||||
|
@ -881,6 +903,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
return None, None, False
|
return None, None, False
|
||||||
else:
|
else:
|
||||||
line = line.rstrip('\r\n')
|
line = line.rstrip('\r\n')
|
||||||
|
if line.isspace():
|
||||||
|
# empty line, just continue
|
||||||
|
buffer += '\n'
|
||||||
|
else:
|
||||||
buffer += '\n' + line
|
buffer += '\n' + line
|
||||||
self.lastcmd = buffer
|
self.lastcmd = buffer
|
||||||
except SyntaxError as e:
|
except SyntaxError as e:
|
||||||
|
|
|
@ -4849,14 +4849,35 @@ class PdbTestReadline(unittest.TestCase):
|
||||||
|
|
||||||
self.assertIn(b'I love Python', output)
|
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):
|
def test_multiline_completion(self):
|
||||||
script = textwrap.dedent("""
|
script = textwrap.dedent("""
|
||||||
import pdb; pdb.Pdb().set_trace()
|
import pdb; pdb.Pdb().set_trace()
|
||||||
""")
|
""")
|
||||||
|
|
||||||
input = b"def func():\n"
|
input = b"def func():\n"
|
||||||
# Complete: \treturn 40 + 2
|
# Auto-indent
|
||||||
input += b"\tret\t 40 + 2\n"
|
# Complete: return 40 + 2
|
||||||
|
input += b"ret\t 40 + 2\n"
|
||||||
input += b"\n"
|
input += b"\n"
|
||||||
# Complete: func()
|
# Complete: func()
|
||||||
input += b"fun\t()\n"
|
input += b"fun\t()\n"
|
||||||
|
@ -4876,12 +4897,13 @@ class PdbTestReadline(unittest.TestCase):
|
||||||
# if the completion is not working as expected
|
# if the completion is not working as expected
|
||||||
input = textwrap.dedent("""\
|
input = textwrap.dedent("""\
|
||||||
def func():
|
def func():
|
||||||
\ta = 1
|
a = 1
|
||||||
\ta += 1
|
\x08\ta += 1
|
||||||
\ta += 1
|
\x08\x08\ta += 1
|
||||||
\tif a > 0:
|
\x08\x08\x08\ta += 1
|
||||||
|
\x08\x08\x08\x08\tif a > 0:
|
||||||
a += 1
|
a += 1
|
||||||
\t\treturn a
|
\x08\x08\x08\x08return a
|
||||||
|
|
||||||
func()
|
func()
|
||||||
c
|
c
|
||||||
|
@ -4889,7 +4911,7 @@ class PdbTestReadline(unittest.TestCase):
|
||||||
|
|
||||||
output = run_pty(script, input)
|
output = run_pty(script, input)
|
||||||
|
|
||||||
self.assertIn(b'4', output)
|
self.assertIn(b'5', output)
|
||||||
self.assertNotIn(b'Error', output)
|
self.assertNotIn(b'Error', output)
|
||||||
|
|
||||||
def test_interact_completion(self):
|
def test_interact_completion(self):
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Introduced auto-indent in :mod:`pdb` multi-line input.
|
Loading…
Add table
Add a link
Reference in a new issue