mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +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) |         self.check_unused_args(used_args, args, kwargs) | ||||||
|         return result |         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: |         if recursion_depth < 0: | ||||||
|             raise ValueError('Max string recursion exceeded') |             raise ValueError('Max string recursion exceeded') | ||||||
|         result = [] |         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 |                 # this is some markup, find the object and do | ||||||
|                 #  the formatting |                 #  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 |                 # given the field_name, find the object it references | ||||||
|                 #  and the argument it came from |                 #  and the argument it came from | ||||||
|                 obj, arg_used = self.get_field(field_name, args, kwargs) |                 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 |                 # expand the format spec, if needed | ||||||
|                 format_spec = self._vformat(format_spec, args, kwargs, |                 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 |                 # format the object and append to the result | ||||||
|                 result.append(self.format_field(obj, format_spec)) |                 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{0}", "bar"), "foobar") | ||||||
|         self.assertEqual(fmt.format("foo{1}{0}-{1}", "bar", 6), "foo6bar-6") |         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): |     def test_conversion_specifiers(self): | ||||||
|         fmt = string.Formatter() |         fmt = string.Formatter() | ||||||
|         self.assertEqual(fmt.format("-{arg!r}-", arg='test'), "-'test'-") |         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, | - Issue #12546: Allow \x00 to be used as a fill character when using str, int, | ||||||
|   float, and complex __format__ methods. |   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 | Library | ||||||
| ------- | ------- | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Eric V. Smith
						Eric V. Smith