bpo-40527: Fix command line argument parsing (GH-19955)
This commit is contained in:
parent
eff870b618
commit
2668a9a5aa
|
@ -756,6 +756,17 @@ class CmdLineTest(unittest.TestCase):
|
||||||
self.assertEqual(proc.returncode, 0, proc)
|
self.assertEqual(proc.returncode, 0, proc)
|
||||||
self.assertEqual(proc.stdout.strip(), b'0')
|
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(),
|
@unittest.skipIf(interpreter_requires_environment(),
|
||||||
'Cannot run -I tests when PYTHON env vars are required.')
|
'Cannot run -I tests when PYTHON env vars are required.')
|
||||||
class IgnoreEnvironmentTest(unittest.TestCase):
|
class IgnoreEnvironmentTest(unittest.TestCase):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix command line argument parsing: no longer write errors multiple times
|
||||||
|
into stderr.
|
|
@ -101,7 +101,9 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
|
||||||
if (option == L'-') {
|
if (option == L'-') {
|
||||||
// Parse long option.
|
// Parse long option.
|
||||||
if (*opt_ptr == L'\0') {
|
if (*opt_ptr == L'\0') {
|
||||||
fprintf(stderr, "expected long option\n");
|
if (_PyOS_opterr) {
|
||||||
|
fprintf(stderr, "expected long option\n");
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*longindex = 0;
|
*longindex = 0;
|
||||||
|
@ -111,7 +113,9 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!opt->name) {
|
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 '_';
|
return '_';
|
||||||
}
|
}
|
||||||
opt_ptr = L"";
|
opt_ptr = L"";
|
||||||
|
@ -119,8 +123,10 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
|
||||||
return opt->val;
|
return opt->val;
|
||||||
}
|
}
|
||||||
if (_PyOS_optind >= argc) {
|
if (_PyOS_optind >= argc) {
|
||||||
fprintf(stderr, "Argument expected for the %ls options\n",
|
if (_PyOS_opterr) {
|
||||||
argv[_PyOS_optind - 1]);
|
fprintf(stderr, "Argument expected for the %ls options\n",
|
||||||
|
argv[_PyOS_optind - 1]);
|
||||||
|
}
|
||||||
return '_';
|
return '_';
|
||||||
}
|
}
|
||||||
_PyOS_optarg = argv[_PyOS_optind++];
|
_PyOS_optarg = argv[_PyOS_optind++];
|
||||||
|
@ -128,14 +134,16 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option == 'J') {
|
if (option == 'J') {
|
||||||
if (_PyOS_opterr)
|
if (_PyOS_opterr) {
|
||||||
fprintf(stderr, "-J is reserved for Jython\n");
|
fprintf(stderr, "-J is reserved for Jython\n");
|
||||||
|
}
|
||||||
return '_';
|
return '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) {
|
if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) {
|
||||||
if (_PyOS_opterr)
|
if (_PyOS_opterr) {
|
||||||
fprintf(stderr, "Unknown option: -%c\n", (char)option);
|
fprintf(stderr, "Unknown option: -%c\n", (char)option);
|
||||||
|
}
|
||||||
return '_';
|
return '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,9 +155,10 @@ int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (_PyOS_optind >= argc) {
|
if (_PyOS_optind >= argc) {
|
||||||
if (_PyOS_opterr)
|
if (_PyOS_opterr) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Argument expected for the -%c option\n", (char)option);
|
"Argument expected for the -%c option\n", (char)option);
|
||||||
|
}
|
||||||
return '_';
|
return '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue