https://github.com/python/cpython/commit/ddfdf9b8df2f24481ceffc3a3fd04baf56f65f55
commit: ddfdf9b8df2f24481ceffc3a3fd04baf56f65f55
branch: main
author: Tian Gao <[email protected]>
committer: gaogaotiantian <[email protected]>
date: 2026-05-05T01:25:45-07:00
summary:
gh-145378: Generate consistent colors for pdb commands (#149305)
files:
A Misc/NEWS.d/next/Library/2026-05-03-01-49-57.gh-issue-145378.rtyAWM.rst
M Lib/pdb.py
M Lib/test/test_pdb.py
diff --git a/Lib/pdb.py b/Lib/pdb.py
index bdc9caf80ec26e..f2a653cf53c748 100644
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -402,6 +402,7 @@ def __init__(self, pdb_instance, stdin, stdout, prompt):
completer_delims=frozenset(' \t\n`@#%^&*()=+[{]}\\|;:\'",<>?')
)
)
+ self.readline_wrapper.get_reader().gen_colors = self.gen_colors
def readline(self):
@@ -463,6 +464,26 @@ def complete(self, text, state):
except IndexError:
return None
+ def gen_colors(self, buffer):
+ from _pyrepl.utils import ColorSpan, Span
+
+ if not buffer.strip():
+ return
+
+ leading_spaces = len(buffer) - len(buffer.lstrip())
+ leading_text = buffer.split()[0]
+ if hasattr(self.pdb_instance, 'do_' + leading_text):
+ yield ColorSpan(
+ Span(leading_spaces, leading_spaces + len(leading_text) - 1),
+ "soft_keyword"
+ )
+ # Redact the command text with spaces so there will be no
duplicated
+ # color span generated for it later.
+ redact_length = leading_spaces + len(leading_text)
+ buffer = ' ' * redact_length + buffer[redact_length:]
+
+ yield from _pyrepl.utils.gen_colors(buffer)
+
class Pdb(bdb.Bdb, cmd.Cmd):
_previous_sigint_handler = None
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index db90019975521e..8b6ccfbf051e6e 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -4981,6 +4981,29 @@ def test_stack_entry(self):
p.set_trace(commands=['w', 'c'])
self.assertIn("\x1b", output.getvalue())
+ @unittest.skipIf(not pdb._pyrepl_available(), "pyrepl is not available")
+ def test_gen_colors(self):
+ p = pdb.Pdb()
+ gen_colors = p.pyrepl_input.gen_colors
+
+ test_cases = [
+ ("longlist", [((0, 7), "soft_keyword")]),
+ ("!longlist", [((0, 0), "op")]),
+ ("list", [((0, 3), "soft_keyword")]),
+ ("list(", [((0, 3), "builtin"), ((4, 4), "op")]),
+ ("a = 1", [
+ ((0, 0), "soft_keyword"),
+ ((2, 2), "op"),
+ ((4, 4), "number"),
+ ])
+ ]
+
+ for buffer, expected in test_cases:
+ for color_span, ((start, end), tag) in zip(gen_colors(buffer),
expected, strict=True):
+ self.assertEqual(color_span.span.start, start)
+ self.assertEqual(color_span.span.end, end)
+ self.assertEqual(color_span.tag, tag)
+
@support.force_not_colorized_test_class
@support.requires_subprocess()
diff --git
a/Misc/NEWS.d/next/Library/2026-05-03-01-49-57.gh-issue-145378.rtyAWM.rst
b/Misc/NEWS.d/next/Library/2026-05-03-01-49-57.gh-issue-145378.rtyAWM.rst
new file mode 100644
index 00000000000000..416ad4b1e2072d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-03-01-49-57.gh-issue-145378.rtyAWM.rst
@@ -0,0 +1 @@
+Generate consistent colors for :mod:`pdb` commands in :mod:`pdb` REPL.
_______________________________________________
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]