Skip to content

Commit

Permalink
Issue #13706: Fix format(float, "n") for locale with non-ASCII decima…
Browse files Browse the repository at this point in the history
…l point (e.g. ps_aF)
  • Loading branch information
Victor Stinner committed Feb 24, 2012
1 parent 6858cab commit 90f50d4
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 15 deletions.
10 changes: 9 additions & 1 deletion Lib/test/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,18 @@ def test_locale(self):
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)

Expand Down
21 changes: 16 additions & 5 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
15 changes: 6 additions & 9 deletions Python/formatter_unicode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 90f50d4

Please sign in to comment.