mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-11874: fix assertion failure in argparse metavar handling (GH-1826)
- bugfix and test for fragile metavar handling in argparse (see bpo-24089, bpo-14046, bpo-25058, bpo-11874) - also fixes some incorrect tests that did not make 1-element tuples correctly
This commit is contained in:
		
							parent
							
								
									ff6c077292
								
							
						
					
					
						commit
						66f02aa32f
					
				
					 3 changed files with 40 additions and 10 deletions
				
			
		|  | @ -327,7 +327,11 @@ def _format_usage(self, usage, actions, groups, prefix): | ||||||
|             if len(prefix) + len(usage) > text_width: |             if len(prefix) + len(usage) > text_width: | ||||||
| 
 | 
 | ||||||
|                 # break usage into wrappable parts |                 # break usage into wrappable parts | ||||||
|                 part_regexp = r'\(.*?\)+|\[.*?\]+|\S+' |                 part_regexp = ( | ||||||
|  |                     r'\(.*?\)+(?=\s|$)|' | ||||||
|  |                     r'\[.*?\]+(?=\s|$)|' | ||||||
|  |                     r'\S+' | ||||||
|  |                 ) | ||||||
|                 opt_usage = format(optionals, groups) |                 opt_usage = format(optionals, groups) | ||||||
|                 pos_usage = format(positionals, groups) |                 pos_usage = format(positionals, groups) | ||||||
|                 opt_parts = _re.findall(part_regexp, opt_usage) |                 opt_parts = _re.findall(part_regexp, opt_usage) | ||||||
|  |  | ||||||
|  | @ -4955,7 +4955,7 @@ def test_nargs_None_metavar_length0(self): | ||||||
|         self.do_test_exception(nargs=None, metavar=tuple()) |         self.do_test_exception(nargs=None, metavar=tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_None_metavar_length1(self): |     def test_nargs_None_metavar_length1(self): | ||||||
|         self.do_test_no_exception(nargs=None, metavar=("1")) |         self.do_test_no_exception(nargs=None, metavar=("1",)) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_None_metavar_length2(self): |     def test_nargs_None_metavar_length2(self): | ||||||
|         self.do_test_exception(nargs=None, metavar=("1", "2")) |         self.do_test_exception(nargs=None, metavar=("1", "2")) | ||||||
|  | @ -4972,7 +4972,7 @@ def test_nargs_optional_metavar_length0(self): | ||||||
|         self.do_test_exception(nargs="?", metavar=tuple()) |         self.do_test_exception(nargs="?", metavar=tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_optional_metavar_length1(self): |     def test_nargs_optional_metavar_length1(self): | ||||||
|         self.do_test_no_exception(nargs="?", metavar=("1")) |         self.do_test_no_exception(nargs="?", metavar=("1",)) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_optional_metavar_length2(self): |     def test_nargs_optional_metavar_length2(self): | ||||||
|         self.do_test_exception(nargs="?", metavar=("1", "2")) |         self.do_test_exception(nargs="?", metavar=("1", "2")) | ||||||
|  | @ -4989,7 +4989,7 @@ def test_nargs_zeroormore_metavar_length0(self): | ||||||
|         self.do_test_exception(nargs="*", metavar=tuple()) |         self.do_test_exception(nargs="*", metavar=tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_zeroormore_metavar_length1(self): |     def test_nargs_zeroormore_metavar_length1(self): | ||||||
|         self.do_test_no_exception(nargs="*", metavar=("1")) |         self.do_test_exception(nargs="*", metavar=("1",)) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_zeroormore_metavar_length2(self): |     def test_nargs_zeroormore_metavar_length2(self): | ||||||
|         self.do_test_no_exception(nargs="*", metavar=("1", "2")) |         self.do_test_no_exception(nargs="*", metavar=("1", "2")) | ||||||
|  | @ -5006,7 +5006,7 @@ def test_nargs_oneormore_metavar_length0(self): | ||||||
|         self.do_test_exception(nargs="+", metavar=tuple()) |         self.do_test_exception(nargs="+", metavar=tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_oneormore_metavar_length1(self): |     def test_nargs_oneormore_metavar_length1(self): | ||||||
|         self.do_test_no_exception(nargs="+", metavar=("1")) |         self.do_test_exception(nargs="+", metavar=("1",)) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_oneormore_metavar_length2(self): |     def test_nargs_oneormore_metavar_length2(self): | ||||||
|         self.do_test_no_exception(nargs="+", metavar=("1", "2")) |         self.do_test_no_exception(nargs="+", metavar=("1", "2")) | ||||||
|  | @ -5023,7 +5023,7 @@ def test_nargs_remainder_metavar_length0(self): | ||||||
|         self.do_test_no_exception(nargs="...", metavar=tuple()) |         self.do_test_no_exception(nargs="...", metavar=tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_remainder_metavar_length1(self): |     def test_nargs_remainder_metavar_length1(self): | ||||||
|         self.do_test_no_exception(nargs="...", metavar=("1")) |         self.do_test_no_exception(nargs="...", metavar=("1",)) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_remainder_metavar_length2(self): |     def test_nargs_remainder_metavar_length2(self): | ||||||
|         self.do_test_no_exception(nargs="...", metavar=("1", "2")) |         self.do_test_no_exception(nargs="...", metavar=("1", "2")) | ||||||
|  | @ -5040,7 +5040,7 @@ def test_nargs_parser_metavar_length0(self): | ||||||
|         self.do_test_exception(nargs="A...", metavar=tuple()) |         self.do_test_exception(nargs="A...", metavar=tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_parser_metavar_length1(self): |     def test_nargs_parser_metavar_length1(self): | ||||||
|         self.do_test_no_exception(nargs="A...", metavar=("1")) |         self.do_test_no_exception(nargs="A...", metavar=("1",)) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_parser_metavar_length2(self): |     def test_nargs_parser_metavar_length2(self): | ||||||
|         self.do_test_exception(nargs="A...", metavar=("1", "2")) |         self.do_test_exception(nargs="A...", metavar=("1", "2")) | ||||||
|  | @ -5057,7 +5057,7 @@ def test_nargs_1_metavar_length0(self): | ||||||
|         self.do_test_exception(nargs=1, metavar=tuple()) |         self.do_test_exception(nargs=1, metavar=tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_1_metavar_length1(self): |     def test_nargs_1_metavar_length1(self): | ||||||
|         self.do_test_no_exception(nargs=1, metavar=("1")) |         self.do_test_no_exception(nargs=1, metavar=("1",)) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_1_metavar_length2(self): |     def test_nargs_1_metavar_length2(self): | ||||||
|         self.do_test_exception(nargs=1, metavar=("1", "2")) |         self.do_test_exception(nargs=1, metavar=("1", "2")) | ||||||
|  | @ -5074,7 +5074,7 @@ def test_nargs_2_metavar_length0(self): | ||||||
|         self.do_test_exception(nargs=2, metavar=tuple()) |         self.do_test_exception(nargs=2, metavar=tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_2_metavar_length1(self): |     def test_nargs_2_metavar_length1(self): | ||||||
|         self.do_test_no_exception(nargs=2, metavar=("1")) |         self.do_test_exception(nargs=2, metavar=("1",)) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_2_metavar_length2(self): |     def test_nargs_2_metavar_length2(self): | ||||||
|         self.do_test_no_exception(nargs=2, metavar=("1", "2")) |         self.do_test_no_exception(nargs=2, metavar=("1", "2")) | ||||||
|  | @ -5091,7 +5091,7 @@ def test_nargs_3_metavar_length0(self): | ||||||
|         self.do_test_exception(nargs=3, metavar=tuple()) |         self.do_test_exception(nargs=3, metavar=tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_3_metavar_length1(self): |     def test_nargs_3_metavar_length1(self): | ||||||
|         self.do_test_no_exception(nargs=3, metavar=("1")) |         self.do_test_exception(nargs=3, metavar=("1",)) | ||||||
| 
 | 
 | ||||||
|     def test_nargs_3_metavar_length2(self): |     def test_nargs_3_metavar_length2(self): | ||||||
|         self.do_test_exception(nargs=3, metavar=("1", "2")) |         self.do_test_exception(nargs=3, metavar=("1", "2")) | ||||||
|  | @ -5118,6 +5118,30 @@ def test_all_exports_everything_but_modules(self): | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(sorted(items), sorted(argparse.__all__)) |         self.assertEqual(sorted(items), sorted(argparse.__all__)) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | class TestWrappingMetavar(TestCase): | ||||||
|  | 
 | ||||||
|  |     def setUp(self): | ||||||
|  |         self.parser = ErrorRaisingArgumentParser( | ||||||
|  |             'this_is_spammy_prog_with_a_long_name_sorry_about_the_name' | ||||||
|  |         ) | ||||||
|  |         # this metavar was triggering library assertion errors due to usage | ||||||
|  |         # message formatting incorrectly splitting on the ] chars within | ||||||
|  |         metavar = '<http[s]://example:1234>' | ||||||
|  |         self.parser.add_argument('--proxy', metavar=metavar) | ||||||
|  | 
 | ||||||
|  |     def test_help_with_metavar(self): | ||||||
|  |         help_text = self.parser.format_help() | ||||||
|  |         self.assertEqual(help_text, textwrap.dedent('''\ | ||||||
|  |             usage: this_is_spammy_prog_with_a_long_name_sorry_about_the_name | ||||||
|  |                    [-h] [--proxy <http[s]://example:1234>] | ||||||
|  | 
 | ||||||
|  |             optional arguments: | ||||||
|  |               -h, --help            show this help message and exit | ||||||
|  |               --proxy <http[s]://example:1234> | ||||||
|  |             ''')) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def test_main(): | def test_main(): | ||||||
|     support.run_unittest(__name__) |     support.run_unittest(__name__) | ||||||
|     # Remove global references to avoid looking like we have refleaks. |     # Remove global references to avoid looking like we have refleaks. | ||||||
|  |  | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | Use a better regex when breaking usage into wrappable parts. Avoids bogus | ||||||
|  | assertion errors from custom metavar strings. | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 wim glenn
						wim glenn