Commit 588f4583 authored by Victor Stinner's avatar Victor Stinner

Issue #13706: Support non-ASCII fill characters

parent b2904831
...@@ -263,6 +263,26 @@ class FormatTest(unittest.TestCase): ...@@ -263,6 +263,26 @@ class FormatTest(unittest.TestCase):
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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment