Skip to content

Commit ddfdf9b

Browse files
gh-145378: Generate consistent colors for pdb commands (#149305)
1 parent a76d957 commit ddfdf9b

3 files changed

Lines changed: 45 additions & 0 deletions

File tree

Lib/pdb.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ def __init__(self, pdb_instance, stdin, stdout, prompt):
402402
completer_delims=frozenset(' \t\n`@#%^&*()=+[{]}\\|;:\'",<>?')
403403
)
404404
)
405+
self.readline_wrapper.get_reader().gen_colors = self.gen_colors
405406

406407
def readline(self):
407408

@@ -463,6 +464,26 @@ def complete(self, text, state):
463464
except IndexError:
464465
return None
465466

467+
def gen_colors(self, buffer):
468+
from _pyrepl.utils import ColorSpan, Span
469+
470+
if not buffer.strip():
471+
return
472+
473+
leading_spaces = len(buffer) - len(buffer.lstrip())
474+
leading_text = buffer.split()[0]
475+
if hasattr(self.pdb_instance, 'do_' + leading_text):
476+
yield ColorSpan(
477+
Span(leading_spaces, leading_spaces + len(leading_text) - 1),
478+
"soft_keyword"
479+
)
480+
# Redact the command text with spaces so there will be no duplicated
481+
# color span generated for it later.
482+
redact_length = leading_spaces + len(leading_text)
483+
buffer = ' ' * redact_length + buffer[redact_length:]
484+
485+
yield from _pyrepl.utils.gen_colors(buffer)
486+
466487

467488
class Pdb(bdb.Bdb, cmd.Cmd):
468489
_previous_sigint_handler = None

Lib/test/test_pdb.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4981,6 +4981,29 @@ def test_stack_entry(self):
49814981
p.set_trace(commands=['w', 'c'])
49824982
self.assertIn("\x1b", output.getvalue())
49834983

4984+
@unittest.skipIf(not pdb._pyrepl_available(), "pyrepl is not available")
4985+
def test_gen_colors(self):
4986+
p = pdb.Pdb()
4987+
gen_colors = p.pyrepl_input.gen_colors
4988+
4989+
test_cases = [
4990+
("longlist", [((0, 7), "soft_keyword")]),
4991+
("!longlist", [((0, 0), "op")]),
4992+
("list", [((0, 3), "soft_keyword")]),
4993+
("list(", [((0, 3), "builtin"), ((4, 4), "op")]),
4994+
("a = 1", [
4995+
((0, 0), "soft_keyword"),
4996+
((2, 2), "op"),
4997+
((4, 4), "number"),
4998+
])
4999+
]
5000+
5001+
for buffer, expected in test_cases:
5002+
for color_span, ((start, end), tag) in zip(gen_colors(buffer), expected, strict=True):
5003+
self.assertEqual(color_span.span.start, start)
5004+
self.assertEqual(color_span.span.end, end)
5005+
self.assertEqual(color_span.tag, tag)
5006+
49845007

49855008
@support.force_not_colorized_test_class
49865009
@support.requires_subprocess()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Generate consistent colors for :mod:`pdb` commands in :mod:`pdb` REPL.

0 commit comments

Comments
 (0)