mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Issue #13706: Support non-ASCII fill characters
This commit is contained in:
		
							parent
							
								
									a2a9071754
								
							
						
					
					
						commit
						a4ac600d6f
					
				
					 2 changed files with 39 additions and 15 deletions
				
			
		|  | @ -263,6 +263,26 @@ def test_exc(formatstr, args, exception, excmsg): | ||||||
|             else: |             else: | ||||||
|                 raise TestFailed('"%*d"%(maxsize, -127) should fail') |                 raise TestFailed('"%*d"%(maxsize, -127) should fail') | ||||||
| 
 | 
 | ||||||
|  |     def test_non_ascii(self): | ||||||
|  |         self.assertEqual(format("abc", "\u2007<5"), "abc\u2007\u2007") | ||||||
|  |         self.assertEqual(format(123, "\u2007<5"), "123\u2007\u2007") | ||||||
|  |         self.assertEqual(format(12.3, "\u2007<6"), "12.3\u2007\u2007") | ||||||
|  |         self.assertEqual(format(0j, "\u2007<4"), "0j\u2007\u2007") | ||||||
|  |         self.assertEqual(format(1+2j, "\u2007<8"), "(1+2j)\u2007\u2007") | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(format("abc", "\u2007>5"), "\u2007\u2007abc") | ||||||
|  |         self.assertEqual(format(123, "\u2007>5"), "\u2007\u2007123") | ||||||
|  |         self.assertEqual(format(12.3, "\u2007>6"), "\u2007\u200712.3") | ||||||
|  |         self.assertEqual(format(1+2j, "\u2007>8"), "\u2007\u2007(1+2j)") | ||||||
|  |         self.assertEqual(format(0j, "\u2007>4"), "\u2007\u20070j") | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(format("abc", "\u2007^5"), "\u2007abc\u2007") | ||||||
|  |         self.assertEqual(format(123, "\u2007^5"), "\u2007123\u2007") | ||||||
|  |         self.assertEqual(format(12.3, "\u2007^6"), "\u200712.3\u2007") | ||||||
|  |         self.assertEqual(format(1+2j, "\u2007^8"), "\u2007(1+2j)\u2007") | ||||||
|  |         self.assertEqual(format(0j, "\u2007^4"), "\u20070j\u2007") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def test_main(): | def test_main(): | ||||||
|     support.run_unittest(FormatTest) |     support.run_unittest(FormatTest) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -274,12 +274,8 @@ parse_internal_render_format_spec(PyObject *format_spec, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (format->fill_char > 127 || format->align > 127 || |     assert (format->align <= 127); | ||||||
|         format->sign > 127) { |     assert (format->sign <= 127); | ||||||
|         PyErr_SetString(PyExc_ValueError, "fill character too large"); |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return 1; |     return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -563,10 +559,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec, | ||||||
|             Py_ssize_t t; |             Py_ssize_t t; | ||||||
|             for (t = 0; t < spec->n_prefix; t++) { |             for (t = 0; t < spec->n_prefix; t++) { | ||||||
|                 Py_UCS4 c = PyUnicode_READ(kind, data, pos + t); |                 Py_UCS4 c = PyUnicode_READ(kind, data, pos + t); | ||||||
|                 if (c > 127) { |                 assert (c <= 127); | ||||||
|                     PyErr_SetString(PyExc_SystemError, "prefix not ASCII"); |  | ||||||
|                     return -1; |  | ||||||
|                 } |  | ||||||
|                 PyUnicode_WRITE(kind, data, pos + t, Py_TOUPPER(c)); |                 PyUnicode_WRITE(kind, data, pos + t, Py_TOUPPER(c)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -722,6 +715,9 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format) | ||||||
| 
 | 
 | ||||||
|     calc_padding(len, format->width, format->align, &lpad, &rpad, &total); |     calc_padding(len, format->width, format->align, &lpad, &rpad, &total); | ||||||
| 
 | 
 | ||||||
|  |     if (lpad != 0 || rpad != 0) | ||||||
|  |         maxchar = Py_MAX(maxchar, format->fill_char); | ||||||
|  | 
 | ||||||
|     /* allocate the resulting string */ |     /* allocate the resulting string */ | ||||||
|     result = PyUnicode_New(total, maxchar); |     result = PyUnicode_New(total, maxchar); | ||||||
|     if (result == NULL) |     if (result == NULL) | ||||||
|  | @ -791,21 +787,18 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, | ||||||
| 
 | 
 | ||||||
|         /* taken from unicodeobject.c formatchar() */ |         /* taken from unicodeobject.c formatchar() */ | ||||||
|         /* Integer input truncated to a character */ |         /* Integer input truncated to a character */ | ||||||
| /* XXX: won't work for int */ |  | ||||||
|         x = PyLong_AsLong(value); |         x = PyLong_AsLong(value); | ||||||
|         if (x == -1 && PyErr_Occurred()) |         if (x == -1 && PyErr_Occurred()) | ||||||
|             goto done; |             goto done; | ||||||
|         if (x < 0 || x > 0x10ffff) { |         if (x < 0 || x > 0x10ffff) { | ||||||
|             PyErr_SetString(PyExc_OverflowError, |             PyErr_SetString(PyExc_OverflowError, | ||||||
|                             "%c arg not in range(0x110000) " |                             "%c arg not in range(0x110000)"); | ||||||
|                             "(wide Python build)"); |  | ||||||
|             goto done; |             goto done; | ||||||
|         } |         } | ||||||
|         tmp = PyUnicode_FromOrdinal(x); |         tmp = PyUnicode_FromOrdinal(x); | ||||||
|         inumeric_chars = 0; |         inumeric_chars = 0; | ||||||
|         n_digits = 1; |         n_digits = 1; | ||||||
|         if (x > maxchar) |         maxchar = Py_MAX(maxchar, x); | ||||||
|             maxchar = x; |  | ||||||
| 
 | 
 | ||||||
|         /* As a sort-of hack, we tell calc_number_widths that we only
 |         /* As a sort-of hack, we tell calc_number_widths that we only
 | ||||||
|            have "remainder" characters. calc_number_widths thinks |            have "remainder" characters. calc_number_widths thinks | ||||||
|  | @ -882,6 +875,9 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, | ||||||
|     n_total = calc_number_widths(&spec, n_prefix, sign_char, tmp, inumeric_chars, |     n_total = calc_number_widths(&spec, n_prefix, sign_char, tmp, inumeric_chars, | ||||||
|                                  inumeric_chars + n_digits, n_remainder, 0, &locale, format); |                                  inumeric_chars + n_digits, n_remainder, 0, &locale, format); | ||||||
| 
 | 
 | ||||||
|  |     if (spec.n_lpadding || spec.n_spadding || spec.n_rpadding) | ||||||
|  |         maxchar = Py_MAX(maxchar, format->fill_char); | ||||||
|  | 
 | ||||||
|     /* Allocate the memory. */ |     /* Allocate the memory. */ | ||||||
|     result = PyUnicode_New(n_total, maxchar); |     result = PyUnicode_New(n_total, maxchar); | ||||||
|     if (!result) |     if (!result) | ||||||
|  | @ -1020,6 +1016,9 @@ format_float_internal(PyObject *value, | ||||||
|                                  index + n_digits, n_remainder, has_decimal, |                                  index + n_digits, n_remainder, has_decimal, | ||||||
|                                  &locale, format); |                                  &locale, format); | ||||||
| 
 | 
 | ||||||
|  |     if (spec.n_lpadding || spec.n_spadding || spec.n_rpadding) | ||||||
|  |         maxchar = Py_MAX(maxchar, format->fill_char); | ||||||
|  | 
 | ||||||
|     /* Allocate the memory. */ |     /* Allocate the memory. */ | ||||||
|     result = PyUnicode_New(n_total, maxchar); |     result = PyUnicode_New(n_total, maxchar); | ||||||
|     if (result == NULL) |     if (result == NULL) | ||||||
|  | @ -1219,6 +1218,11 @@ format_complex_internal(PyObject *value, | ||||||
|     calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, |     calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, | ||||||
|                  format->width, format->align, &lpad, &rpad, &total); |                  format->width, format->align, &lpad, &rpad, &total); | ||||||
| 
 | 
 | ||||||
|  |     if (re_spec.n_lpadding || re_spec.n_spadding || re_spec.n_rpadding | ||||||
|  |         || im_spec.n_lpadding || im_spec.n_spadding || im_spec.n_rpadding | ||||||
|  |         || lpad || rpad) | ||||||
|  |         maxchar = Py_MAX(maxchar, format->fill_char); | ||||||
|  | 
 | ||||||
|     result = PyUnicode_New(total, maxchar); |     result = PyUnicode_New(total, maxchar); | ||||||
|     if (result == NULL) |     if (result == NULL) | ||||||
|         goto done; |         goto done; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner