mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Issue #13598: Add auto-numbering of replacement fields to string.Formatter.
This commit is contained in:
		
							parent
							
								
									efeb9da4ae
								
							
						
					
					
						commit
						7ce90743a1
					
				
					 3 changed files with 42 additions and 2 deletions
				
			
		|  | @ -169,7 +169,8 @@ def vformat(self, format_string, args, kwargs): | |||
|         self.check_unused_args(used_args, args, kwargs) | ||||
|         return result | ||||
| 
 | ||||
|     def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): | ||||
|     def _vformat(self, format_string, args, kwargs, used_args, recursion_depth, | ||||
|                  auto_arg_index=0): | ||||
|         if recursion_depth < 0: | ||||
|             raise ValueError('Max string recursion exceeded') | ||||
|         result = [] | ||||
|  | @ -185,6 +186,23 @@ def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): | |||
|                 # this is some markup, find the object and do | ||||
|                 #  the formatting | ||||
| 
 | ||||
|                 # handle arg indexing when empty field_names are given. | ||||
|                 if field_name == '': | ||||
|                     if auto_arg_index is False: | ||||
|                         raise ValueError('cannot switch from manual field ' | ||||
|                                          'specification to automatic field ' | ||||
|                                          'numbering') | ||||
|                     field_name = str(auto_arg_index) | ||||
|                     auto_arg_index += 1 | ||||
|                 elif field_name.isdigit(): | ||||
|                     if auto_arg_index: | ||||
|                         raise ValueError('cannot switch from manual field ' | ||||
|                                          'specification to automatic field ' | ||||
|                                          'numbering') | ||||
|                     # disable auto arg incrementing, if it gets | ||||
|                     # used later on, then an exception will be raised | ||||
|                     auto_arg_index = False | ||||
| 
 | ||||
|                 # given the field_name, find the object it references | ||||
|                 #  and the argument it came from | ||||
|                 obj, arg_used = self.get_field(field_name, args, kwargs) | ||||
|  | @ -195,7 +213,8 @@ def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): | |||
| 
 | ||||
|                 # expand the format spec, if needed | ||||
|                 format_spec = self._vformat(format_spec, args, kwargs, | ||||
|                                             used_args, recursion_depth-1) | ||||
|                                             used_args, recursion_depth-1, | ||||
|                                             auto_arg_index=auto_arg_index) | ||||
| 
 | ||||
|                 # format the object and append to the result | ||||
|                 result.append(self.format_field(obj, format_spec)) | ||||
|  |  | |||
|  | @ -32,6 +32,23 @@ def test_basic_formatter(self): | |||
|         self.assertEqual(fmt.format("foo{0}", "bar"), "foobar") | ||||
|         self.assertEqual(fmt.format("foo{1}{0}-{1}", "bar", 6), "foo6bar-6") | ||||
| 
 | ||||
|     def test_auto_numbering(self): | ||||
|         fmt = string.Formatter() | ||||
|         self.assertEqual(fmt.format('foo{}{}', 'bar', 6), | ||||
|                          'foo{}{}'.format('bar', 6)) | ||||
|         self.assertEqual(fmt.format('foo{1}{num}{1}', None, 'bar', num=6), | ||||
|                          'foo{1}{num}{1}'.format(None, 'bar', num=6)) | ||||
|         self.assertEqual(fmt.format('{:^{}}', 'bar', 6), | ||||
|                          '{:^{}}'.format('bar', 6)) | ||||
|         self.assertEqual(fmt.format('{:^{pad}}{}', 'foo', 'bar', pad=6), | ||||
|                          '{:^{pad}}{}'.format('foo', 'bar', pad=6)) | ||||
| 
 | ||||
|         with self.assertRaises(ValueError): | ||||
|             fmt.format('foo{1}{}', 'bar', 6) | ||||
| 
 | ||||
|         with self.assertRaises(ValueError): | ||||
|             fmt.format('foo{}{1}', 'bar', 6) | ||||
| 
 | ||||
|     def test_conversion_specifiers(self): | ||||
|         fmt = string.Formatter() | ||||
|         self.assertEqual(fmt.format("-{arg!r}-", arg='test'), "-'test'-") | ||||
|  |  | |||
|  | @ -30,6 +30,10 @@ Core and Builtins | |||
| - Issue #12546: Allow \x00 to be used as a fill character when using str, int, | ||||
|   float, and complex __format__ methods. | ||||
| 
 | ||||
| - Issue #13598: Modify string.Formatter to support auto-numbering of  | ||||
|   replacement fields. It now matches the behavior of str.format() in | ||||
|   this regard. | ||||
| 
 | ||||
| Library | ||||
| ------- | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Eric V. Smith
						Eric V. Smith