mirror of https://github.com/python/cpython
gh-110944: Make pdb completion work for alias and convenience vars (GH-110945)
This commit is contained in:
parent
324531df90
commit
f44d6ff6e0
18
Lib/pdb.py
18
Lib/pdb.py
|
@ -238,7 +238,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
|||
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
|
||||
|
@ -686,6 +686,18 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
|||
# 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((':', ',')):
|
||||
|
@ -720,6 +732,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
|||
# 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
|
||||
|
|
|
@ -3289,6 +3289,27 @@ class PdbTestReadline(unittest.TestCase):
|
|||
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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Support alias and convenience vars for :mod:`pdb` completion
|
Loading…
Reference in New Issue