diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index 7fa950d9ef5..7345b30c054 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -263,6 +263,26 @@ class FormatTest(unittest.TestCase): else: 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(): support.run_unittest(FormatTest) diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index db6364f5135..609ac16899f 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -274,12 +274,8 @@ parse_internal_render_format_spec(PyObject *format_spec, } } - if (format->fill_char > 127 || format->align > 127 || - format->sign > 127) { - PyErr_SetString(PyExc_ValueError, "fill character too large"); - return 0; - } - + assert (format->align <= 127); + assert (format->sign <= 127); return 1; } @@ -563,10 +559,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec, Py_ssize_t t; for (t = 0; t < spec->n_prefix; t++) { Py_UCS4 c = PyUnicode_READ(kind, data, pos + t); - if (c > 127) { - PyErr_SetString(PyExc_SystemError, "prefix not ASCII"); - return -1; - } + assert (c <= 127); 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); + if (lpad != 0 || rpad != 0) + maxchar = Py_MAX(maxchar, format->fill_char); + /* allocate the resulting string */ result = PyUnicode_New(total, maxchar); if (result == NULL) @@ -791,21 +787,18 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, /* taken from unicodeobject.c formatchar() */ /* Integer input truncated to a character */ -/* XXX: won't work for int */ x = PyLong_AsLong(value); if (x == -1 && PyErr_Occurred()) goto done; if (x < 0 || x > 0x10ffff) { PyErr_SetString(PyExc_OverflowError, - "%c arg not in range(0x110000) " - "(wide Python build)"); + "%c arg not in range(0x110000)"); goto done; } tmp = PyUnicode_FromOrdinal(x); inumeric_chars = 0; n_digits = 1; - if (x > maxchar) - maxchar = x; + maxchar = Py_MAX(maxchar, x); /* As a sort-of hack, we tell calc_number_widths that we only 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, 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. */ result = PyUnicode_New(n_total, maxchar); if (!result) @@ -1020,6 +1016,9 @@ format_float_internal(PyObject *value, index + n_digits, n_remainder, has_decimal, &locale, format); + if (spec.n_lpadding || spec.n_spadding || spec.n_rpadding) + maxchar = Py_MAX(maxchar, format->fill_char); + /* Allocate the memory. */ result = PyUnicode_New(n_total, maxchar); if (result == NULL) @@ -1219,6 +1218,11 @@ format_complex_internal(PyObject *value, calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, 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); if (result == NULL) goto done;