Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions Lib/test/test_cmd_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -677,23 +677,29 @@ 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)

# 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(),
Expand Down Expand Up @@ -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)

Expand Down
Original file line number Diff line number Diff line change
@@ -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 '- '``.
4 changes: 2 additions & 2 deletions Python/getopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 '_';
}
Expand All @@ -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 '_';
}
Expand Down
Loading