Properly add patch 273
This commit is contained in:
parent
26024771df
commit
40bb48b584
240
00273-fix-localeconv-encoding-for-LC_NUMERIC.patch
Normal file
240
00273-fix-localeconv-encoding-for-LC_NUMERIC.patch
Normal file
@ -0,0 +1,240 @@
|
||||
diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst
|
||||
index b04442bc162..9a0c570533a 100644
|
||||
--- a/Doc/library/locale.rst
|
||||
+++ b/Doc/library/locale.rst
|
||||
@@ -147,6 +147,16 @@ The :mod:`locale` module defines the following exception and functions:
|
||||
| ``CHAR_MAX`` | Nothing is specified in this locale. |
|
||||
+--------------+-----------------------------------------+
|
||||
|
||||
+ The function sets temporarily the ``LC_CTYPE`` locale to the ``LC_NUMERIC``
|
||||
+ locale to decode ``decimal_point`` and ``thousands_sep`` byte strings if
|
||||
+ they are non-ASCII or longer than 1 byte, and the ``LC_NUMERIC`` locale is
|
||||
+ different than the ``LC_CTYPE`` locale. This temporary change affects other
|
||||
+ threads.
|
||||
+
|
||||
+ .. versionchanged:: 3.6.5
|
||||
+ The function now sets temporarily the ``LC_CTYPE`` locale to the
|
||||
+ ``LC_NUMERIC`` locale in some cases.
|
||||
+
|
||||
|
||||
.. function:: nl_langinfo(option)
|
||||
|
||||
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
|
||||
index 196a4c00056..d8a1647e8b5 100644
|
||||
--- a/Doc/library/stdtypes.rst
|
||||
+++ b/Doc/library/stdtypes.rst
|
||||
@@ -1599,6 +1599,20 @@ expression support in the :mod:`re` module).
|
||||
See :ref:`formatstrings` for a description of the various formatting options
|
||||
that can be specified in format strings.
|
||||
|
||||
+ .. note::
|
||||
+ When formatting a number (:class:`int`, :class:`float`, :class:`float`
|
||||
+ and subclasses) with the ``n`` type (ex: ``'{:n}'.format(1234)``), the
|
||||
+ function sets temporarily the ``LC_CTYPE`` locale to the ``LC_NUMERIC``
|
||||
+ locale to decode ``decimal_point`` and ``thousands_sep`` fields of
|
||||
+ :c:func:`localeconv` if they are non-ASCII or longer than 1 byte, and the
|
||||
+ ``LC_NUMERIC`` locale is different than the ``LC_CTYPE`` locale. This
|
||||
+ temporary change affects other threads.
|
||||
+
|
||||
+ .. versionchanged:: 3.6.5
|
||||
+ When formatting a number with the ``n`` type, the function sets
|
||||
+ temporarily the ``LC_CTYPE`` locale to the ``LC_NUMERIC`` locale in some
|
||||
+ cases.
|
||||
+
|
||||
|
||||
.. method:: str.format_map(mapping)
|
||||
|
||||
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst
|
||||
index 847b50140a6..f83508c9250 100644
|
||||
--- a/Doc/whatsnew/3.6.rst
|
||||
+++ b/Doc/whatsnew/3.6.rst
|
||||
@@ -2346,3 +2346,11 @@ It has been replaced by the new ``make regen-all`` target.
|
||||
(Contributed by Victor Stinner in :issue:`23404`.)
|
||||
|
||||
.. versionchanged:: 3.6.2
|
||||
+
|
||||
+
|
||||
+Notable changes in Python 3.6.5
|
||||
+===============================
|
||||
+
|
||||
+The :func:`locale.localeconv` function now sets temporarily the ``LC_CTYPE``
|
||||
+locale to the ``LC_NUMERIC`` locale in some cases.
|
||||
+(Contributed by Victor Stinner in :issue:`31900`.)
|
||||
diff --git a/Include/fileutils.h b/Include/fileutils.h
|
||||
index 900c70faad7..875715df97a 100644
|
||||
--- a/Include/fileutils.h
|
||||
+++ b/Include/fileutils.h
|
||||
@@ -119,6 +119,11 @@ PyAPI_FUNC(int) _Py_get_blocking(int fd);
|
||||
PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking);
|
||||
#endif /* !MS_WINDOWS */
|
||||
|
||||
+PyAPI_FUNC(int) _Py_GetLocaleconvNumeric(
|
||||
+ PyObject **decimal_point,
|
||||
+ PyObject **thousands_sep,
|
||||
+ const char **grouping);
|
||||
+
|
||||
#endif /* Py_LIMITED_API */
|
||||
|
||||
#ifdef __cplusplus
|
||||
diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c
|
||||
index 71c9146ccb8..95b370b1ad0 100644
|
||||
--- a/Modules/_localemodule.c
|
||||
+++ b/Modules/_localemodule.c
|
||||
@@ -171,12 +171,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,6 +189,32 @@ 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:
|
||||
diff --git a/Python/fileutils.c b/Python/fileutils.c
|
||||
index 97505e5bc6d..14dd81b03f0 100644
|
||||
--- a/Python/fileutils.c
|
||||
+++ b/Python/fileutils.c
|
||||
@@ -1597,3 +1597,80 @@ _Py_set_blocking(int fd, int blocking)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
+
|
||||
+
|
||||
+int
|
||||
+_Py_GetLocaleconvNumeric(PyObject **decimal_point, PyObject **thousands_sep,
|
||||
+ const char **grouping)
|
||||
+{
|
||||
+ int res = -1;
|
||||
+
|
||||
+ struct lconv *lc = localeconv();
|
||||
+
|
||||
+ int change_locale = 0;
|
||||
+ if (decimal_point != NULL &&
|
||||
+ (strlen(lc->decimal_point) > 1 || ((unsigned char)lc->decimal_point[0]) > 127))
|
||||
+ {
|
||||
+ change_locale = 1;
|
||||
+ }
|
||||
+ if (thousands_sep != NULL &&
|
||||
+ (strlen(lc->thousands_sep) > 1 || ((unsigned char)lc->thousands_sep[0]) > 127))
|
||||
+ {
|
||||
+ change_locale = 1;
|
||||
+ }
|
||||
+
|
||||
+ /* Keep a copy of the LC_CTYPE locale */
|
||||
+ char *oldloc = NULL, *loc = NULL;
|
||||
+ if (change_locale) {
|
||||
+ oldloc = setlocale(LC_CTYPE, NULL);
|
||||
+ if (!oldloc) {
|
||||
+ PyErr_SetString(PyExc_RuntimeWarning, "faild to get LC_CTYPE locale");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ oldloc = _PyMem_Strdup(oldloc);
|
||||
+ if (!oldloc) {
|
||||
+ PyErr_NoMemory();
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ loc = setlocale(LC_NUMERIC, NULL);
|
||||
+ if (loc != NULL && strcmp(loc, oldloc) == 0) {
|
||||
+ loc = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (loc != NULL) {
|
||||
+ /* Only set the locale temporarilty the LC_CTYPE locale
|
||||
+ if LC_NUMERIC locale is different than LC_CTYPE locale and
|
||||
+ decimal_point and/or thousands_sep are non-ASCII or longer than
|
||||
+ 1 byte */
|
||||
+ setlocale(LC_CTYPE, loc);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (decimal_point != NULL) {
|
||||
+ *decimal_point = PyUnicode_DecodeLocale(lc->decimal_point, NULL);
|
||||
+ if (*decimal_point == NULL) {
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
+ if (thousands_sep != NULL) {
|
||||
+ *thousands_sep = PyUnicode_DecodeLocale(lc->thousands_sep, NULL);
|
||||
+ if (*thousands_sep == NULL) {
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (grouping != NULL) {
|
||||
+ *grouping = lc->grouping;
|
||||
+ }
|
||||
+
|
||||
+ res = 0;
|
||||
+
|
||||
+error:
|
||||
+ if (loc != NULL) {
|
||||
+ setlocale(LC_CTYPE, oldloc);
|
||||
+ }
|
||||
+ PyMem_Free(oldloc);
|
||||
+ return res;
|
||||
+}
|
||||
diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c
|
||||
index d2be76f1e1a..d3ef650e6ce 100644
|
||||
--- a/Python/formatter_unicode.c
|
||||
+++ b/Python/formatter_unicode.c
|
||||
@@ -707,18 +707,11 @@ get_locale_info(enum LocaleType type, LocaleInfo *locale_info)
|
||||
{
|
||||
switch (type) {
|
||||
case LT_CURRENT_LOCALE: {
|
||||
- struct lconv *locale_data = localeconv();
|
||||
- locale_info->decimal_point = PyUnicode_DecodeLocale(
|
||||
- locale_data->decimal_point,
|
||||
- NULL);
|
||||
- if (locale_info->decimal_point == NULL)
|
||||
+ if (_Py_GetLocaleconvNumeric(&locale_info->decimal_point,
|
||||
+ &locale_info->thousands_sep,
|
||||
+ &locale_info->grouping) < 0) {
|
||||
return -1;
|
||||
- locale_info->thousands_sep = PyUnicode_DecodeLocale(
|
||||
- locale_data->thousands_sep,
|
||||
- NULL);
|
||||
- if (locale_info->thousands_sep == NULL)
|
||||
- return -1;
|
||||
- locale_info->grouping = locale_data->grouping;
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
case LT_DEFAULT_LOCALE:
|
Loading…
Reference in New Issue
Block a user