mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-40527: Fix command line argument parsing (GH-19955)
This commit is contained in:
		
							parent
							
								
									eff870b618
								
							
						
					
					
						commit
						2668a9a5aa
					
				
					 3 changed files with 29 additions and 7 deletions
				
			
		|  | @ -756,6 +756,17 @@ def test_argv0_normalization(self): | ||||||
|         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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner