From 90f50d4df9e21093f006427fd7ed11a0d704f792 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 Feb 2012 01:44:47 +0100 Subject: Issue #13706: Fix format(float, "n") for locale with non-ASCII decimal point (e.g. ps_aF) --- Lib/test/test_format.py | 10 +++++++++- Objects/unicodeobject.c | 21 ++++++++++++++++----- Python/formatter_unicode.c | 15 ++++++--------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index 70e748f..dc324af 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -289,10 +289,18 @@ class FormatTest(unittest.TestCase): except locale.Error as err: self.skipTest("Cannot set locale: {}".format(err)) try: - sep = locale.localeconv()['thousands_sep'] + localeconv = locale.localeconv() + sep = localeconv['thousands_sep'] + point = localeconv['decimal_point'] + text = format(123456789, "n") self.assertIn(sep, text) self.assertEqual(text.replace(sep, ''), '123456789') + + text = format(1234.5, "n") + self.assertIn(sep, text) + self.assertIn(point, text) + self.assertEqual(text.replace(sep, ''), '1234' + point + '5') finally: locale.setlocale(locale.LC_ALL, oldloc) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 2841b07..7753c32 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9176,9 +9176,16 @@ _PyUnicode_InsertThousandsGrouping( thousands_sep_data = PyUnicode_DATA(thousands_sep); thousands_sep_len = PyUnicode_GET_LENGTH(thousands_sep); if (unicode != NULL && thousands_sep_kind != kind) { - thousands_sep_data = _PyUnicode_AsKind(thousands_sep, kind); - if (!thousands_sep_data) - return -1; + if (thousands_sep_kind < kind) { + thousands_sep_data = _PyUnicode_AsKind(thousands_sep, kind); + if (!thousands_sep_data) + return -1; + } + else { + data = _PyUnicode_AsKind(unicode, thousands_sep_kind); + if (!data) + return -1; + } } switch (kind) { @@ -9210,8 +9217,12 @@ _PyUnicode_InsertThousandsGrouping( assert(0); return -1; } - if (unicode != NULL && thousands_sep_kind != kind) - PyMem_Free(thousands_sep_data); + if (unicode != NULL && thousands_sep_kind != kind) { + if (thousands_sep_kind < kind) + PyMem_Free(thousands_sep_data); + else + PyMem_Free(data); + } if (unicode == NULL) { *maxchar = 127; if (len != n_digits) { diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 94f8047..58e66e0 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -529,6 +529,9 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding) *maxchar = Py_MAX(*maxchar, format->fill_char); + if (spec->n_decimal) + *maxchar = Py_MAX(*maxchar, PyUnicode_MAX_CHAR_VALUE(locale->decimal_point)); + return spec->n_lpadding + spec->n_sign + spec->n_prefix + spec->n_spadding + spec->n_grouped_digits + spec->n_decimal + spec->n_remainder + spec->n_rpadding; @@ -548,10 +551,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec, Py_ssize_t d_pos = d_start; unsigned int kind = PyUnicode_KIND(out); void *data = PyUnicode_DATA(out); - -#ifndef NDEBUG Py_ssize_t r; -#endif if (spec->n_lpadding) { PyUnicode_Fill(out, pos, pos + spec->n_lpadding, fill_char); @@ -593,18 +593,15 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec, if (pdigits == NULL) return -1; } -#ifndef NDEBUG - r = -#endif - _PyUnicode_InsertThousandsGrouping( + r = _PyUnicode_InsertThousandsGrouping( out, pos, spec->n_grouped_digits, pdigits + kind * d_pos, spec->n_digits, spec->n_min_width, locale->grouping, locale->thousands_sep, NULL); -#ifndef NDEBUG + if (r == -1) + return -1; assert(r == spec->n_grouped_digits); -#endif if (PyUnicode_KIND(digits) < kind) PyMem_Free(pdigits); d_pos += spec->n_digits; -- cgit v0.12