100
100
import _pyrepl .utils
101
101
102
102
from contextlib import ExitStack , closing , contextmanager
103
- from rlcompleter import Completer
104
103
from types import CodeType
105
104
from warnings import deprecated
106
105
@@ -364,6 +363,15 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
364
363
readline .set_completer_delims (' \t \n `@#%^&*()=+[{]}\\ |;:\' ",<>?' )
365
364
except ImportError :
366
365
pass
366
+
367
+ # GH-138860
368
+ # We need to lazy-import rlcompleter to avoid deadlock
369
+ # We cannot import it during self.complete* methods because importing
370
+ # rlcompleter for the first time will overwrite readline's completer
371
+ # So we import it here and save the Completer class
372
+ from rlcompleter import Completer
373
+ self .RlCompleter = Completer
374
+
367
375
self .allow_kbdint = False
368
376
self .nosigint = nosigint
369
377
# Consider these characters as part of the command so when the users type
@@ -1186,10 +1194,9 @@ def completedefault(self, text, line, begidx, endidx):
1186
1194
conv_vars = self .curframe .f_globals .get ('__pdb_convenience_variables' , {})
1187
1195
return [f"${ name } " for name in conv_vars if name .startswith (text [1 :])]
1188
1196
1189
- # Use rlcompleter to do the completion
1190
1197
state = 0
1191
1198
matches = []
1192
- completer = Completer (self .curframe .f_globals | self .curframe .f_locals )
1199
+ completer = self . RlCompleter (self .curframe .f_globals | self .curframe .f_locals )
1193
1200
while (match := completer .complete (text , state )) is not None :
1194
1201
matches .append (match )
1195
1202
state += 1
@@ -1204,8 +1211,8 @@ def _enable_rlcompleter(self, ns):
1204
1211
return
1205
1212
1206
1213
try :
1214
+ completer = self .RlCompleter (ns )
1207
1215
old_completer = readline .get_completer ()
1208
- completer = Completer (ns )
1209
1216
readline .set_completer (completer .complete )
1210
1217
yield
1211
1218
finally :
0 commit comments