Skip to content

Commit

Permalink
pythongh-110944: Make pdb completion work for alias and convenience v…
Browse files Browse the repository at this point in the history
  • Loading branch information
gaogaotiantian authored and aisk committed Feb 11, 2024
1 parent 3e89507 commit b7d52b8
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
18 changes: 17 additions & 1 deletion Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
try:
import readline
# remove some common file name delimiters
readline.set_completer_delims(' \t\n`@#$%^&*()=+[{]}\\|;:\'",<>?')
readline.set_completer_delims(' \t\n`@#%^&*()=+[{]}\\|;:\'",<>?')
except ImportError:
pass
self.allow_kbdint = False
Expand Down Expand Up @@ -686,6 +686,18 @@ def set_convenience_variable(self, frame, name, value):
# Generic completion functions. Individual complete_foo methods can be
# assigned below to one of these functions.

def completenames(self, text, line, begidx, endidx):
# Overwrite completenames() of cmd so for the command completion,
# if no current command matches, check for expressions as well
commands = super().completenames(text, line, begidx, endidx)
for alias in self.aliases:
if alias.startswith(text):
commands.append(alias)
if commands:
return commands
else:
return self._complete_expression(text, line, begidx, endidx)

def _complete_location(self, text, line, begidx, endidx):
# Complete a file/module/function location for break/tbreak/clear.
if line.strip().endswith((':', ',')):
Expand Down Expand Up @@ -720,6 +732,10 @@ def _complete_expression(self, text, line, begidx, endidx):
# complete builtins, and they clutter the namespace quite heavily, so we
# leave them out.
ns = {**self.curframe.f_globals, **self.curframe_locals}
if text.startswith("$"):
# Complete convenience variables
conv_vars = self.curframe.f_globals.get('__pdb_convenience_variables', {})
return [f"${name}" for name in conv_vars if name.startswith(text[1:])]
if '.' in text:
# Walk an attribute chain up to the last part, similar to what
# rlcompleter does. This will bail if any of the parts are not
Expand Down
21 changes: 21 additions & 0 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3289,6 +3289,27 @@ def test_basic_completion(self):
self.assertIn(b'continue', output)
self.assertIn(b'hello!', output)

def test_expression_completion(self):
script = textwrap.dedent("""
value = "speci"
import pdb; pdb.Pdb().set_trace()
""")

# Complete: value + 'al'
input = b"val\t + 'al'\n"
# Complete: p value + 'es'
input += b"p val\t + 'es'\n"
# Complete: $_frame
input += b"$_fra\t\n"
# Continue
input += b"c\n"

output = run_pty(script, input)

self.assertIn(b'special', output)
self.assertIn(b'species', output)
self.assertIn(b'$_frame', output)


def load_tests(loader, tests, pattern):
from test import test_pdb
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support alias and convenience vars for :mod:`pdb` completion

0 comments on commit b7d52b8

Please sign in to comment.