Skip to content

Commit 12e2495

Browse files
committed
Fix Cmd completion for lines beginning with !
When a line begins with `!` and there's no `do_shell` method defined, `parsecmd` returns `None` as the `cmd`, which incorrectly leads to `None` being concatenated to `complete_` and triggering a `TypeError`. Instead, recognize `None` as a sentinel that means we should call `completedefault`, as an empty string already is.
1 parent 3b43335 commit 12e2495

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

Lib/cmd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ def complete(self, text, state):
273273
endidx = readline.get_endidx() - stripped
274274
if begidx>0:
275275
cmd, args, foo = self.parseline(line)
276-
if cmd == '':
276+
if cmd in ('', None):
277277
compfunc = self.completedefault
278278
else:
279279
try:

Lib/test/test_cmd.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,31 @@ def do_tab_completion_test(self, args):
289289
self.assertIn(b'ab_completion_test', output)
290290
self.assertIn(b'tab completion success', output)
291291

292+
def test_bang_completion_without_do_shell(self):
293+
script = textwrap.dedent("""
294+
import cmd
295+
class simplecmd(cmd.Cmd):
296+
def completedefault(self, text, line, begidx, endidx):
297+
return ["hello"]
298+
299+
def default(self, line):
300+
if line == "! hello":
301+
print('tab completion success')
302+
else:
303+
print('tab completion failure')
304+
return True
305+
306+
simplecmd().cmdloop()
307+
""")
308+
309+
# '! h' and complete 'ello' to '! hello'
310+
input = b"! h\t\n"
311+
312+
output = run_pty(script, input)
313+
314+
self.assertIn(b'ello', output)
315+
self.assertIn(b'tab completion success', output)
316+
292317
def load_tests(loader, tests, pattern):
293318
tests.addTest(doctest.DocTestSuite())
294319
return tests
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The :class:`cmd.Cmd` class has been fixed to call the ``completedefault``
2+
method whenever the ``do_shell`` method is not defined and tab completion is
3+
requested for a line beginning with ``!``. Previously ``completedefault``
4+
was called only if there were no spaces between the ``!`` and the cursor
5+
position where tab completion was attempted.

0 commit comments

Comments
 (0)