diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2020-05-06 13:43:09 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-06 13:43:09 (GMT) |
commit | bce4ddafdd188cc6deb1584728b67b9e149ca6a4 (patch) | |
tree | 1d8aa1504c397e86ba73b8ea7d2f410bea9ab275 | |
parent | a32587a60da5939a3932bb30432d2bdd3d6203d4 (diff) | |
download | cpython-bce4ddafdd188cc6deb1584728b67b9e149ca6a4.zip cpython-bce4ddafdd188cc6deb1584728b67b9e149ca6a4.tar.gz cpython-bce4ddafdd188cc6deb1584728b67b9e149ca6a4.tar.bz2 |
bpo-40527: Fix command line argument parsing (GH-19955)
(cherry picked from commit 2668a9a5aa506a048aef7b4881c8dcf6b81c6870)
Co-authored-by: Victor Stinner <vstinner@python.org>
-rw-r--r-- | Lib/test/test_cmd_line.py | 11 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2020-05-06-14-52-35.bpo-40527.gTNKuy.rst | 2 | ||||
-rw-r--r-- | Python/getopt.c | 23 |
3 files changed, 29 insertions, 7 deletions
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 497bfa9..5fc5bff 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -740,6 +740,17 @@ class CmdLineTest(unittest.TestCase): self.assertEqual(proc.returncode, 0, proc) self.assertEqual(proc.stdout.strip(), b'0') + def test_parsing_error(self): + args = [sys.executable, '-I', '--unknown-option'] + proc = subprocess.run(args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True) + err_msg = "unknown option --unknown-option\nusage: " + self.assertTrue(proc.stderr.startswith(err_msg), proc.stderr) + self.assertNotEqual(proc.returncode, 0) + + @unittest.skipIf(interpreter_requires_environment(), 'Cannot run -I tests when PYTHON env vars are required.') class IgnoreEnvironmentTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-06-14-52-35.bpo-40527.gTNKuy.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-06-14-52-35.bpo-40527.gTNKuy.rst new file mode 100644 index 0000000..19b8888 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-06-14-52-35.bpo-40527.gTNKuy.rst @@ -0,0 +1,2 @@ +Fix command line argument parsing: no longer write errors multiple times +into stderr. diff --git a/Python/getopt.c b/Python/getopt.c index 1a7db3f..249ad1e 100644 --- a/Python/getopt.c +++ b/Python/getopt.c @@ -105,7 +105,9 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex) if (option == L'-') { // Parse long option. if (*opt_ptr == L'\0') { - fprintf(stderr, "expected long option\n"); + if (_PyOS_opterr) { + fprintf(stderr, "expected long option\n"); + } return -1; } *longindex = 0; @@ -115,7 +117,9 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex) break; } if (!opt->name) { - fprintf(stderr, "unknown option %ls\n", argv[_PyOS_optind - 1]); + if (_PyOS_opterr) { + fprintf(stderr, "unknown option %ls\n", argv[_PyOS_optind - 1]); + } return '_'; } opt_ptr = L""; @@ -123,8 +127,10 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex) return opt->val; } if (_PyOS_optind >= argc) { - fprintf(stderr, "Argument expected for the %ls options\n", - argv[_PyOS_optind - 1]); + if (_PyOS_opterr) { + fprintf(stderr, "Argument expected for the %ls options\n", + argv[_PyOS_optind - 1]); + } return '_'; } _PyOS_optarg = argv[_PyOS_optind++]; @@ -132,14 +138,16 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex) } if (option == 'J') { - if (_PyOS_opterr) + if (_PyOS_opterr) { fprintf(stderr, "-J is reserved for Jython\n"); + } return '_'; } if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) { - if (_PyOS_opterr) + if (_PyOS_opterr) { fprintf(stderr, "Unknown option: -%c\n", (char)option); + } return '_'; } @@ -151,9 +159,10 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex) else { if (_PyOS_optind >= argc) { - if (_PyOS_opterr) + if (_PyOS_opterr) { fprintf(stderr, "Argument expected for the -%c option\n", (char)option); + } return '_'; } |