https://github.com/python/cpython/commit/1bc0ed1ea29f8b85247f4f29b479a6588443dc0d
commit: 1bc0ed1ea29f8b85247f4f29b479a6588443dc0d
branch: main
author: Vasiliy Kiryanov <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-10-22T18:40:41Z
summary:

gh-132414: Make invalid command-line options visible in the error message 
(GH-157921)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-09-21-12-44-38.gh-issue-132414.uwxmd5.rst
M Lib/test/test_cmd_line.py
M Python/getopt.c

diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index 82b9d0f86ba421..80b1e27366bcc5 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -677,7 +677,7 @@ def test_unknown_options(self):
         for option in ('-z', '--long-option', '---'):
             with self.subTest(option=option):
                 rc, out, err = assert_python_failure('-E', option)
-                errmsg = f'Unknown option: {option}'.encode()
+                errmsg = f"Invalid option '{option}'".encode()
                 self.assertIn(errmsg, err)
                 self.assertEqual(err.splitlines().count(errmsg), 1)
                 self.assertEqual(b'', out)
@@ -685,15 +685,21 @@ def test_unknown_options(self):
         # Add "without='-E'" to prevent _assert_python to append -E
         # to env_vars and change the output of stderr
         rc, out, err = assert_python_failure('-z', without='-E')
-        self.assertIn(b'Unknown option: -z', err)
-        self.assertEqual(err.splitlines().count(b'Unknown option: -z'), 1)
+        self.assertIn(b"Invalid option '-z'", err)
+        self.assertEqual(err.splitlines().count(b"Invalid option '-z'"), 1)
         self.assertEqual(b'', out)
 
         rc, out, err = assert_python_failure('-a', '-z', without='-E')
-        self.assertIn(b'Unknown option: -a', err)
+        self.assertIn(b"Invalid option '-a'", err)
         # only the first unknown option is reported
-        self.assertNotIn(b'Unknown option: -z', err)
-        self.assertEqual(err.splitlines().count(b'Unknown option: -a'), 1)
+        self.assertNotIn(b"Invalid option '-z'", err)
+        self.assertEqual(err.splitlines().count(b"Invalid option '-a'"), 1)
+        self.assertEqual(b'', out)
+
+        # gh-132414: a quoted "-q -i" arrives as one argument; the space
+        # after -q must be visible in the error message
+        rc, out, err = assert_python_failure('-q -i', without='-E')
+        self.assertIn(b"Invalid option '- '", err)
         self.assertEqual(b'', out)
 
     @unittest.skipIf(interpreter_requires_environment(),
@@ -1162,7 +1168,7 @@ def test_parsing_error(self):
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               text=True)
-        err_msg = "Unknown option: --unknown-option\nusage: "
+        err_msg = "Invalid option '--unknown-option'\nusage: "
         self.assertStartsWith(proc.stderr, err_msg)
         self.assertNotEqual(proc.returncode, 0)
 
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2026-09-21-12-44-38.gh-issue-132414.uwxmd5.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-21-12-44-38.gh-issue-132414.uwxmd5.rst
new file mode 100644
index 00000000000000..5f795e987650af
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-21-12-44-38.gh-issue-132414.uwxmd5.rst
@@ -0,0 +1,4 @@
+Quote the invalid option in the error message for an unknown command-line
+option: ``Invalid option '-z'`` instead of ``Unknown option: -z``. A stray
+space, as passed by a shebang line like ``#!/usr/bin/python3 -q -i``, is now
+reported as ``Invalid option '- '``.
diff --git a/Python/getopt.c b/Python/getopt.c
index 2dcabc9962d25f..f6a3ef960a4021 100644
--- a/Python/getopt.c
+++ b/Python/getopt.c
@@ -137,7 +137,7 @@ _PyOS_GetOpt(struct _PyOS_GetOpt *getopt)
 
         if (!opt->name) {
             if (error) {
-                fprintf(stderr, "Unknown option: %ls\n", argv[getopt->index - 
1]);
+                fprintf(stderr, "Invalid option '%ls'\n", argv[getopt->index - 
1]);
             }
             return '_';
         }
@@ -160,7 +160,7 @@ _PyOS_GetOpt(struct _PyOS_GetOpt *getopt)
     wchar_t *ptr = wcschr(SHORT_OPTS, option);
     if (ptr == NULL) {
         if (error) {
-            fprintf(stderr, "Unknown option: -%lc\n", option);
+            fprintf(stderr, "Invalid option '-%lc'\n", option);
         }
         return '_';
     }

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to