From 36723c72e335c98c0419d5a62182b82301c2772a Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sat, 22 Feb 2025 14:33:10 -0500 Subject: [PATCH 1/5] Improve tab indentation for pdb multi-line input --- Lib/pdb.py | 21 ++++++++++++++++++--- Lib/test/test_pdb.py | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index 08a941de79ec55..ff38ccb509db7d 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -652,10 +652,10 @@ def displayhook(self, obj): self.message(repr(obj)) @contextmanager - def _disable_command_completion(self): + def _enable_multiline_completion(self): completenames = self.completenames try: - self.completenames = self.completedefault + self.completenames = self.complete_multiline_names yield finally: self.completenames = completenames @@ -753,7 +753,7 @@ def default(self, line): buffer = line if (code := codeop.compile_command(line + '\n', '', 'single')) is None: # Multi-line mode - with self._disable_command_completion(): + with self._enable_multiline_completion(): buffer = line continue_prompt = "... " while (code := codeop.compile_command(buffer, '', 'single')) is None: @@ -996,6 +996,21 @@ def _complete_expression(self, text, line, begidx, endidx): # Complete a simple name. 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 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): if text.startswith("$"): # Complete convenience variables diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 83753279599f76..a39ca50fd8e928 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -4441,6 +4441,30 @@ def test_multiline_completion(self): 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 = b"def func():\n" + input += b"\ta = 1\n" + input += b" \ta += 1\n" + input += b" \ta += 1\n" + input += b" \tif a > 0:\n" + input += b" a += 1\n" + input += b"\t\treturn a\n" + input += b"\n" + input += b"func()\n" + input += b"c\n" + + output = run_pty(script, input) + + self.assertIn(b'4', output) + self.assertNotIn(b'Error', output) + def load_tests(loader, tests, pattern): from test import test_pdb From cfda7ba886982133454291e724f1557def5ee5dd Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 19:44:04 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2025-02-22-19-44-00.gh-issue-125377.LFTK0H.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-02-22-19-44-00.gh-issue-125377.LFTK0H.rst diff --git a/Misc/NEWS.d/next/Library/2025-02-22-19-44-00.gh-issue-125377.LFTK0H.rst b/Misc/NEWS.d/next/Library/2025-02-22-19-44-00.gh-issue-125377.LFTK0H.rst new file mode 100644 index 00000000000000..b3b5275b4e3389 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-02-22-19-44-00.gh-issue-125377.LFTK0H.rst @@ -0,0 +1 @@ +```` 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. From 9293b21363e63900c523042fae57c513022e0ee7 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sat, 22 Feb 2025 14:45:06 -0500 Subject: [PATCH 3/5] Fix lint issue --- Lib/test/test_pdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index a39ca50fd8e928..57a2caf81edbf2 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -4459,7 +4459,7 @@ def test_multiline_indent_completion(self): input += b"\n" input += b"func()\n" input += b"c\n" - + output = run_pty(script, input) self.assertIn(b'4', output) From 41e37ecaecf21a02f7ba2bd19630ce787143736a Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sat, 22 Feb 2025 18:12:48 -0500 Subject: [PATCH 4/5] Use a single multi-line string input --- Lib/test/test_pdb.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 57a2caf81edbf2..0870cd2874939f 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -4449,16 +4449,18 @@ def test_multiline_indent_completion(self): # \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 = b"def func():\n" - input += b"\ta = 1\n" - input += b" \ta += 1\n" - input += b" \ta += 1\n" - input += b" \tif a > 0:\n" - input += b" a += 1\n" - input += b"\t\treturn a\n" - input += b"\n" - input += b"func()\n" - input += b"c\n" + 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) From 64965f30c67b55098ec471096ebd979d79bbf848 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 4 Mar 2025 11:49:22 -0500 Subject: [PATCH 5/5] Add whatsnew entry --- Doc/whatsnew/3.14.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 7b1a30d5a873ae..f309edab7a8d3c 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -785,6 +785,10 @@ pdb (if any). (Contributed by Tian Gao in :gh:`130493`.) +* ```` 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 ------