bpo-31900: Fix localeconv() encoding for LC_NUMERIC (#4174)

* Add _Py_GetLocaleconvNumeric() function: decode decimal_point and
  thousands_sep fields of localeconv() from the LC_NUMERIC encoding,
  rather than decoding from the LC_CTYPE encoding.
* Modify locale.localeconv() and "n" formatter of str.format() (for
  int, float and complex to use _Py_GetLocaleconvNumeric()
  internally.
This commit is contained in:
Victor Stinner 2018-01-15 15:58:02 +01:00 committed by GitHub
parent 7ed7aead95
commit cb064fc232
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 151 additions and 19 deletions

View file

@ -139,8 +139,9 @@ PyLocale_localeconv(PyObject* self)
PyObject *x;
result = PyDict_New();
if (!result)
if (!result) {
return NULL;
}
/* if LC_NUMERIC is different in the C library, use saved value */
l = localeconv();
@ -171,12 +172,6 @@ PyLocale_localeconv(PyObject* self)
RESULT(#i, x); \
} while (0)
/* Numeric information */
RESULT_STRING(decimal_point);
RESULT_STRING(thousands_sep);
x = copy_grouping(l->grouping);
RESULT("grouping", x);
/* Monetary information */
RESULT_STRING(int_curr_symbol);
RESULT_STRING(currency_symbol);
@ -195,10 +190,36 @@ PyLocale_localeconv(PyObject* self)
RESULT_INT(n_sep_by_space);
RESULT_INT(p_sign_posn);
RESULT_INT(n_sign_posn);
/* Numeric information */
PyObject *decimal_point, *thousands_sep;
const char *grouping;
if (_Py_GetLocaleconvNumeric(&decimal_point,
&thousands_sep,
&grouping) < 0) {
goto failed;
}
if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) {
Py_DECREF(decimal_point);
Py_DECREF(thousands_sep);
goto failed;
}
Py_DECREF(decimal_point);
if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) {
Py_DECREF(thousands_sep);
goto failed;
}
Py_DECREF(thousands_sep);
x = copy_grouping(grouping);
RESULT("grouping", x);
return result;
failed:
Py_XDECREF(result);
Py_DECREF(result);
return NULL;
}