]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-133363: Fix Cmd completion for lines beginning with `! ` (#133364)
authorMatt Wozniski <mwozniski@bloomberg.net>
Sun, 4 May 2025 02:50:37 +0000 (22:50 -0400)
committerGitHub <noreply@github.com>
Sun, 4 May 2025 02:50:37 +0000 (22:50 -0400)
Lib/cmd.py
Lib/test/test_cmd.py
Misc/NEWS.d/next/Library/2025-05-03-21-55-33.gh-issue-133363.PTLnRP.rst [new file with mode: 0644]

index 438b88aa1049cca6e60a4e03ad3579f222665754..51495fb32160b06ea0ca118e1f458afc41859d59 100644 (file)
@@ -273,7 +273,7 @@ class Cmd:
             endidx = readline.get_endidx() - stripped
             if begidx>0:
                 cmd, args, foo = self.parseline(line)
-                if cmd == '':
+                if not cmd:
                     compfunc = self.completedefault
                 else:
                     try:
index 46ec82b704963da65caa9d43fe09c8a399747963..0ae44f3987d324461a486346a6e9354cbafd7e93 100644 (file)
@@ -289,6 +289,30 @@ class CmdTestReadline(unittest.TestCase):
         self.assertIn(b'ab_completion_test', output)
         self.assertIn(b'tab completion success', output)
 
+    def test_bang_completion_without_do_shell(self):
+        script = textwrap.dedent("""
+            import cmd
+            class simplecmd(cmd.Cmd):
+                def completedefault(self, text, line, begidx, endidx):
+                    return ["hello"]
+
+                def default(self, line):
+                    if line.replace(" ", "") == "!hello":
+                        print('tab completion success')
+                    else:
+                        print('tab completion failure')
+                    return True
+
+            simplecmd().cmdloop()
+        """)
+
+        # '! h' or '!h' and complete 'ello' to 'hello'
+        for input in [b"! h\t\n", b"!h\t\n"]:
+            with self.subTest(input=input):
+                output = run_pty(script, input)
+                self.assertIn(b'hello', output)
+                self.assertIn(b'tab completion success', output)
+
 def load_tests(loader, tests, pattern):
     tests.addTest(doctest.DocTestSuite())
     return tests
diff --git a/Misc/NEWS.d/next/Library/2025-05-03-21-55-33.gh-issue-133363.PTLnRP.rst b/Misc/NEWS.d/next/Library/2025-05-03-21-55-33.gh-issue-133363.PTLnRP.rst
new file mode 100644 (file)
index 0000000..d44c685
--- /dev/null
@@ -0,0 +1,3 @@
+The :class:`cmd.Cmd` class has been fixed to reliably call the ``completedefault``
+method whenever the ``do_shell`` method is not defined and tab completion is
+requested for a line beginning with ``!``.