gh-133153: Use rlcompleter for pdb's interact command (#133176)

This commit is contained in:
Tian Gao 2025-04-30 15:19:13 -07:00 committed by GitHub
parent 0e21ed7c09
commit 327f5ff9fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 60 additions and 10 deletions

View file

@ -1157,6 +1157,22 @@ class Pdb(bdb.Bdb, cmd.Cmd):
state += 1
return matches
@contextmanager
def _enable_rlcompleter(self, ns):
try:
import readline
except ImportError:
yield
return
try:
old_completer = readline.get_completer()
completer = Completer(ns)
readline.set_completer(completer.complete)
yield
finally:
readline.set_completer(old_completer)
# Pdb meta commands, only intended to be used internally by pdb
def _pdbcmd_print_frame_status(self, arg):
@ -2242,9 +2258,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
contains all the (global and local) names found in the current scope.
"""
ns = {**self.curframe.f_globals, **self.curframe.f_locals}
console = _PdbInteractiveConsole(ns, message=self.message)
console.interact(banner="*pdb interact start*",
exitmsg="*exit from pdb interact command*")
with self._enable_rlcompleter(ns):
console = _PdbInteractiveConsole(ns, message=self.message)
console.interact(banner="*pdb interact start*",
exitmsg="*exit from pdb interact command*")
def do_alias(self, arg):
"""alias [name [command]]
@ -2749,14 +2766,18 @@ class _PdbServer(Pdb):
self.error(f"Ignoring invalid message from client: {msg}")
def _complete_any(self, text, line, begidx, endidx):
if begidx == 0:
return self.completenames(text, line, begidx, endidx)
cmd = self.parseline(line)[0]
if cmd:
compfunc = getattr(self, "complete_" + cmd, self.completedefault)
else:
# If we're in 'interact' mode, we need to use the default completer
if self._interact_state:
compfunc = self.completedefault
else:
if begidx == 0:
return self.completenames(text, line, begidx, endidx)
cmd = self.parseline(line)[0]
if cmd:
compfunc = getattr(self, "complete_" + cmd, self.completedefault)
else:
compfunc = self.completedefault
return compfunc(text, line, begidx, endidx)
def cmdloop(self, intro=None):