mirror of
https://github.com/python/cpython.git
synced 2025-09-01 14:38:00 +00:00
gh-125377: Improve tab indentation for pdb multi-line input (#130471)
This commit is contained in:
parent
c989e74446
commit
b6769e9404
4 changed files with 49 additions and 3 deletions
|
@ -785,6 +785,10 @@ pdb
|
||||||
(if any).
|
(if any).
|
||||||
(Contributed by Tian Gao in :gh:`130493`.)
|
(Contributed by Tian Gao in :gh:`130493`.)
|
||||||
|
|
||||||
|
* ``<tab>`` at the beginning of the line in :mod:`pdb` multi-line input will
|
||||||
|
fill in a 4-space indentation now, instead of inserting a ``\t`` character.
|
||||||
|
(Contributed by Tian Gao in :gh:`130471`.)
|
||||||
|
|
||||||
|
|
||||||
pickle
|
pickle
|
||||||
------
|
------
|
||||||
|
|
21
Lib/pdb.py
21
Lib/pdb.py
|
@ -652,10 +652,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
self.message(repr(obj))
|
self.message(repr(obj))
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def _disable_command_completion(self):
|
def _enable_multiline_completion(self):
|
||||||
completenames = self.completenames
|
completenames = self.completenames
|
||||||
try:
|
try:
|
||||||
self.completenames = self.completedefault
|
self.completenames = self.complete_multiline_names
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
self.completenames = completenames
|
self.completenames = completenames
|
||||||
|
@ -753,7 +753,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
buffer = line
|
buffer = line
|
||||||
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._disable_command_completion():
|
with self._enable_multiline_completion():
|
||||||
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:
|
||||||
|
@ -996,6 +996,21 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
# Complete a simple name.
|
# Complete a simple name.
|
||||||
return [n for n in ns.keys() if n.startswith(text)]
|
return [n for n in ns.keys() if n.startswith(text)]
|
||||||
|
|
||||||
|
def _complete_indentation(self, text, line, begidx, endidx):
|
||||||
|
try:
|
||||||
|
import readline
|
||||||
|
except ImportError:
|
||||||
|
return []
|
||||||
|
# Fill in spaces to form a 4-space indent
|
||||||
|
return [' ' * (4 - readline.get_begidx() % 4)]
|
||||||
|
|
||||||
|
def complete_multiline_names(self, text, line, begidx, endidx):
|
||||||
|
# If text is space-only, the user entered <tab> before any text.
|
||||||
|
# That normally means they want to indent the current line.
|
||||||
|
if not text.strip():
|
||||||
|
return self._complete_indentation(text, line, begidx, endidx)
|
||||||
|
return self.completedefault(text, line, begidx, endidx)
|
||||||
|
|
||||||
def completedefault(self, text, line, begidx, endidx):
|
def completedefault(self, text, line, begidx, endidx):
|
||||||
if text.startswith("$"):
|
if text.startswith("$"):
|
||||||
# Complete convenience variables
|
# Complete convenience variables
|
||||||
|
|
|
@ -4513,6 +4513,32 @@ class PdbTestReadline(unittest.TestCase):
|
||||||
|
|
||||||
self.assertIn(b'42', output)
|
self.assertIn(b'42', output)
|
||||||
|
|
||||||
|
def test_multiline_indent_completion(self):
|
||||||
|
script = textwrap.dedent("""
|
||||||
|
import pdb; pdb.Pdb().set_trace()
|
||||||
|
""")
|
||||||
|
|
||||||
|
# \t should always complete a 4-space indent
|
||||||
|
# This piece of code will raise an IndentationError or a SyntaxError
|
||||||
|
# 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
|
||||||
|
|
||||||
|
func()
|
||||||
|
c
|
||||||
|
""").encode()
|
||||||
|
|
||||||
|
output = run_pty(script, input)
|
||||||
|
|
||||||
|
self.assertIn(b'4', output)
|
||||||
|
self.assertNotIn(b'Error', output)
|
||||||
|
|
||||||
|
|
||||||
def load_tests(loader, tests, pattern):
|
def load_tests(loader, tests, pattern):
|
||||||
from test import test_pdb
|
from test import test_pdb
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
``<tab>`` at the beginning of the line in :mod:`pdb` multi-line input will fill in a 4-space indentation now, instead of inserting a ``\t`` character.
|
Loading…
Add table
Add a link
Reference in a new issue