cpython: f89e2f4cda88 (original) (raw)
Mercurial > cpython
changeset 75231:f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator * Decode thousands separator and decimal point using PyUnicode_DecodeLocale() (from the locale encoding), instead of decoding them implicitly from latin1 * Remove _PyUnicode_InsertThousandsGroupingLocale(), it was not used * Change _PyUnicode_InsertThousandsGrouping() API to return the maximum character if unicode is NULL * Replace MIN/MAX macros by Py_MIN/Py_MAX * stringlib/undef.h undefines STRINGLIB_IS_UNICODE * stringlib/localeutil.h only supports Unicode [#13706]
Victor Stinner victor.stinner@haypocalc.com | |
---|---|
date | Fri, 24 Feb 2012 00:37:51 +0100 |
parents | 548a023c8230 |
children | e394e62473ee |
files | Include/unicodeobject.h Lib/test/test_format.py Objects/stringlib/asciilib.h Objects/stringlib/localeutil.h Objects/stringlib/stringdefs.h Objects/stringlib/ucs1lib.h Objects/stringlib/ucs2lib.h Objects/stringlib/ucs4lib.h Objects/stringlib/undef.h Objects/stringlib/unicodedefs.h Objects/unicodeobject.c Python/formatter_unicode.c |
diffstat | 12 files changed, 189 insertions(+), 152 deletions(-)[+] [-] Include/unicodeobject.h 18 Lib/test/test_format.py 15 Objects/stringlib/asciilib.h 3 Objects/stringlib/localeutil.h 71 Objects/stringlib/stringdefs.h 2 Objects/stringlib/ucs1lib.h 3 Objects/stringlib/ucs2lib.h 3 Objects/stringlib/ucs4lib.h 3 Objects/stringlib/undef.h 2 Objects/stringlib/unicodedefs.h 2 Objects/unicodeobject.c 77 Python/formatter_unicode.c 142 |
line wrap: on
line diff
--- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -1936,32 +1936,20 @@ PyAPI_FUNC(PyObject ) _PyUnicode_XStrip ); #endif -/ Using the current locale, insert the thousands grouping
- into the string pointed to by buffer. For the argument descriptions,
- see Objects/stringlib/localeutil.h */ -
-#ifndef Py_LIMITED_API -PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGroupingLocale(Py_UNICODE *buffer,
Py_ssize_t n_buffer,[](#l1.13)
Py_UNICODE *digits,[](#l1.14)
Py_ssize_t n_digits,[](#l1.15)
Py_ssize_t min_width);[](#l1.16)
-#endif - /* Using explicit passed-in values, insert the thousands grouping into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ #ifndef Py_LIMITED_API PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping( PyObject *unicode,
- Py_ssize_t index, Py_ssize_t n_buffer, void *digits, Py_ssize_t n_digits, Py_ssize_t min_width, const char *grouping,
#endif /* === Characters Type APIs =============================================== */
--- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -1,4 +1,5 @@ from test.support import verbose, TestFailed +import locale import sys import test.support as support import unittest @@ -282,6 +283,20 @@ class FormatTest(unittest.TestCase): self.assertEqual(format(1+2j, "\u2007^8"), "\u2007(1+2j)\u2007") self.assertEqual(format(0j, "\u2007^4"), "\u20070j\u2007")
- def test_locale(self):
try:[](#l2.14)
oldloc = locale.setlocale(locale.LC_ALL, '')[](#l2.15)
except locale.Error as err:[](#l2.16)
self.skipTest("Cannot set locale: {}".format(err))[](#l2.17)
try:[](#l2.18)
sep = locale.localeconv()['thousands_sep'][](#l2.19)
text = format(123456789, "n")[](#l2.20)
self.assertIn(sep, text)[](#l2.21)
self.assertEqual(text.replace(sep, ''), '123456789')[](#l2.22)
finally:[](#l2.23)
locale.setlocale(locale.LC_ALL, oldloc)[](#l2.24)
+ + def test_main(): support.run_unittest(FormatTest)
--- a/Objects/stringlib/asciilib.h +++ b/Objects/stringlib/asciilib.h @@ -21,12 +21,9 @@ #define STRINGLIB_RESIZE not_supported #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact -#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping -#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII #define _Py_InsertThousandsGrouping _PyUnicode_ascii_InsertThousandsGrouping -#define _Py_InsertThousandsGroupingLocale _PyUnicode_ascii_InsertThousandsGroupingLocale
--- a/Objects/stringlib/localeutil.h +++ b/Objects/stringlib/localeutil.h @@ -2,8 +2,9 @@ #include <locale.h> -#define MAX(x, y) ((x) < (y) ? (y) : (x)) -#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#ifndef STRINGLIB_IS_UNICODE +# error "localeutil is specific to Unicode" +#endif typedef struct { const char *grouping; @@ -46,7 +47,7 @@ STRINGLIB(GroupGenerator_next)(STRINGLIB are optional, depending on when we're called. */ static void STRINGLIB(fill)(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end,
Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep,[](#l4.19)
Py_ssize_t n_chars, Py_ssize_t n_zeros, STRINGLIB_CHAR* thousands_sep,[](#l4.20) Py_ssize_t thousands_sep_len)[](#l4.21)
{ Py_ssize_t i; @@ -55,15 +56,8 @@ STRINGLIB(fill)(STRINGLIB_CHAR **digits_ buffer_end -= thousands_sep_len; / Copy the thousands_sep chars into the buffer. */ -#if STRINGLIB_IS_UNICODE
/* Convert from the char's of the thousands_sep from[](#l4.29)
the locale into unicode. */[](#l4.30)
for (i = 0; i < thousands_sep_len; ++i)[](#l4.31)
(*buffer_end)[i] = thousands_sep[i];[](#l4.32)
/* No conversion, just memcpy the thousands_sep. */[](#l4.34)
memcpy(*buffer_end, thousands_sep, thousands_sep_len);[](#l4.35)
memcpy(*buffer_end, thousands_sep,[](#l4.37)
} *buffer_end -= n_chars; @@ -76,7 +70,7 @@ STRINGLIB(fill)(STRINGLIB_CHAR digits_ } /thousands_sep_len * STRINGLIB_SIZEOF_CHAR);[](#l4.38)
- InsertThousandsGrouping:
- @buffer: A pointer to the start of a string.
- @n_buffer: Number of characters in @buffer.
- @digits: A pointer to the digits we're reading from. If count @@ -106,13 +100,15 @@ STRINGLIB(fill)(STRINGLIB_CHAR **digits_ _insert_thousands_sep(). **/ Py_ssize_t -_Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
Py_ssize_t n_buffer,[](#l4.56)
STRINGLIB_CHAR *digits,[](#l4.57)
Py_ssize_t n_digits,[](#l4.58)
Py_ssize_t min_width,[](#l4.59)
const char *grouping,[](#l4.60)
const char *thousands_sep)[](#l4.61)
+STRINGLIB(InsertThousandsGrouping)(
- STRINGLIB_CHAR *buffer,
- Py_ssize_t n_buffer,
- STRINGLIB_CHAR *digits,
- Py_ssize_t n_digits,
- Py_ssize_t min_width,
- const char *grouping,
- STRINGLIB_CHAR *thousands_sep,
- Py_ssize_t thousands_sep_len)
{ Py_ssize_t count = 0; Py_ssize_t n_zeros; @@ -124,7 +120,6 @@ Py_ssize_t STRINGLIB_CHAR *digits_end = NULL; Py_ssize_t l; Py_ssize_t n_chars;
- Py_ssize_t thousands_sep_len = strlen(thousands_sep); Py_ssize_t remaining = n_digits; /* Number of chars remaining to be looked at / / A generator that returns all of the grouping widths, until it @@ -138,9 +133,9 @@ Py_ssize_t } while ((l = STRINGLIB(GroupGenerator_next)(&groupgen)) > 0) {
l = MIN(l, MAX(MAX(remaining, min_width), 1));[](#l4.86)
n_zeros = MAX(0, l - remaining);[](#l4.87)
n_chars = MAX(0, MIN(remaining, l));[](#l4.88)
l = Py_MIN(l, Py_MAX(Py_MAX(remaining, min_width), 1));[](#l4.89)
n_zeros = Py_MAX(0, l - remaining);[](#l4.90)
n_chars = Py_MAX(0, Py_MIN(remaining, l));[](#l4.91)
/* Use n_zero zero's and n_chars chars / @@ -168,9 +163,9 @@ Py_ssize_t if (!loop_broken) { / We left the loop without using a break statement. */
l = MAX(MAX(remaining, min_width), 1);[](#l4.99)
n_zeros = MAX(0, l - remaining);[](#l4.100)
n_chars = MAX(0, MIN(remaining, l));[](#l4.101)
l = Py_MAX(Py_MAX(remaining, min_width), 1);[](#l4.102)
n_zeros = Py_MAX(0, l - remaining);[](#l4.103)
n_chars = Py_MAX(0, Py_MIN(remaining, l));[](#l4.104)
/* Use n_zero zero's and n_chars chars */ count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; @@ -183,25 +178,3 @@ Py_ssize_t return count; } -/**
to put the grouping chars.[](#l4.116)
- *
- **/ -Py_ssize_t -_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer,
Py_ssize_t n_buffer,[](#l4.122)
STRINGLIB_CHAR *digits,[](#l4.123)
Py_ssize_t n_digits,[](#l4.124)
Py_ssize_t min_width)[](#l4.125)
struct lconv *locale_data = localeconv();[](#l4.127)
const char *grouping = locale_data->grouping;[](#l4.128)
const char *thousands_sep = locale_data->thousands_sep;[](#l4.129)
return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits,[](#l4.131)
min_width, grouping, thousands_sep);[](#l4.132)
--- a/Objects/stringlib/stringdefs.h +++ b/Objects/stringlib/stringdefs.h @@ -25,7 +25,5 @@ #define STRINGLIB_CHECK PyBytes_Check #define STRINGLIB_CHECK_EXACT PyBytes_CheckExact #define STRINGLIB_TOSTR PyObject_Str -#define STRINGLIB_GROUPING _PyBytes_InsertThousandsGrouping -#define STRINGLIB_GROUPING_LOCALE _PyBytes_InsertThousandsGroupingLocale #define STRINGLIB_TOASCII PyObject_Repr #endif /* !STRINGLIB_STRINGDEFS_H */
--- a/Objects/stringlib/ucs1lib.h +++ b/Objects/stringlib/ucs1lib.h @@ -21,13 +21,10 @@ #define STRINGLIB_RESIZE not_supported #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact -#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping -#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII #define _Py_InsertThousandsGrouping _PyUnicode_ucs1_InsertThousandsGrouping -#define _Py_InsertThousandsGroupingLocale _PyUnicode_ucs1_InsertThousandsGroupingLocale
--- a/Objects/stringlib/ucs2lib.h +++ b/Objects/stringlib/ucs2lib.h @@ -21,12 +21,9 @@ #define STRINGLIB_RESIZE not_supported #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact -#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping -#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII #define _Py_InsertThousandsGrouping _PyUnicode_ucs2_InsertThousandsGrouping -#define _Py_InsertThousandsGroupingLocale _PyUnicode_ucs2_InsertThousandsGroupingLocale
--- a/Objects/stringlib/ucs4lib.h +++ b/Objects/stringlib/ucs4lib.h @@ -21,12 +21,9 @@ #define STRINGLIB_RESIZE not_supported #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact -#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping -#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII #define _Py_InsertThousandsGrouping _PyUnicode_ucs4_InsertThousandsGrouping -#define _Py_InsertThousandsGroupingLocale _PyUnicode_ucs4_InsertThousandsGroupingLocale
--- a/Objects/stringlib/undef.h +++ b/Objects/stringlib/undef.h @@ -7,5 +7,5 @@ #undef STRINGLIB_NEW #undef STRINGLIB_RESIZE #undef _Py_InsertThousandsGrouping -#undef _Py_InsertThousandsGroupingLocale +#undef STRINGLIB_IS_UNICODE
--- a/Objects/stringlib/unicodedefs.h +++ b/Objects/stringlib/unicodedefs.h @@ -24,8 +24,6 @@ #define STRINGLIB_RESIZE PyUnicode_Resize #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact -#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping -#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale #if PY_VERSION_HEX < 0x03000000 #define STRINGLIB_TOSTR PyObject_Unicode
--- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9151,34 +9151,75 @@ any_find_slice(int direction, PyObject* } Py_ssize_t -_PyUnicode_InsertThousandsGrouping(PyObject *unicode, int kind, void *data,
Py_ssize_t n_buffer,[](#l11.8)
void *digits, Py_ssize_t n_digits,[](#l11.9)
Py_ssize_t min_width,[](#l11.10)
const char *grouping,[](#l11.11)
const char *thousands_sep)[](#l11.12)
-{ +_PyUnicode_InsertThousandsGrouping(
- PyObject *unicode, Py_ssize_t index,
- Py_ssize_t n_buffer,
- void *digits, Py_ssize_t n_digits,
- Py_ssize_t min_width,
- const char *grouping, PyObject *thousands_sep,
- Py_UCS4 *maxchar)
- unsigned int kind, thousands_sep_kind;
- void *data, *thousands_sep_data;
- Py_ssize_t thousands_sep_len;
- Py_ssize_t len;
- if (unicode != NULL) {
kind = PyUnicode_KIND(unicode);[](#l11.28)
data = PyUnicode_DATA(unicode) + index * kind;[](#l11.29)
- }
- else {
kind = PyUnicode_1BYTE_KIND;[](#l11.32)
data = NULL;[](#l11.33)
- }
- thousands_sep_kind = PyUnicode_KIND(thousands_sep);
- 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);[](#l11.39)
if (!thousands_sep_data)[](#l11.40)
return -1;[](#l11.41)
- }
+ switch (kind) { case PyUnicode_1BYTE_KIND: if (unicode != NULL && PyUnicode_IS_ASCII(unicode))
return _PyUnicode_ascii_InsertThousandsGrouping([](#l11.47)
len = asciilib_InsertThousandsGrouping([](#l11.48) (Py_UCS1*)data, n_buffer, (Py_UCS1*)digits, n_digits,[](#l11.49)
min_width, grouping, thousands_sep);[](#l11.50)
min_width, grouping,[](#l11.51)
thousands_sep_data, thousands_sep_len);[](#l11.52) else[](#l11.53)
return _PyUnicode_ucs1_InsertThousandsGrouping([](#l11.54)
len = ucs1lib_InsertThousandsGrouping([](#l11.55) (Py_UCS1*)data, n_buffer, (Py_UCS1*)digits, n_digits,[](#l11.56)
min_width, grouping, thousands_sep);[](#l11.57)
min_width, grouping,[](#l11.58)
thousands_sep_data, thousands_sep_len);[](#l11.59)
case PyUnicode_2BYTE_KIND:break;[](#l11.60)
return _PyUnicode_ucs2_InsertThousandsGrouping([](#l11.62)
len = ucs2lib_InsertThousandsGrouping([](#l11.63) (Py_UCS2*)data, n_buffer, (Py_UCS2*)digits, n_digits,[](#l11.64)
min_width, grouping, thousands_sep);[](#l11.65)
min_width, grouping,[](#l11.66)
thousands_sep_data, thousands_sep_len);[](#l11.67)
case PyUnicode_4BYTE_KIND:break;[](#l11.68)
return _PyUnicode_ucs4_InsertThousandsGrouping([](#l11.70)
len = ucs4lib_InsertThousandsGrouping([](#l11.71) (Py_UCS4*)data, n_buffer, (Py_UCS4*)digits, n_digits,[](#l11.72)
min_width, grouping,[](#l11.77)
thousands_sep_data, thousands_sep_len);[](#l11.78)
break;[](#l11.79)
- default:
assert(0);[](#l11.81)
return -1;[](#l11.82)
- }
- if (unicode != NULL && thousands_sep_kind != kind)
PyMem_Free(thousands_sep_data);[](#l11.85)
- if (unicode == NULL) {
*maxchar = 127;[](#l11.87)
if (len != n_digits) {[](#l11.88)
*maxchar = Py_MAX(*maxchar,[](#l11.89)
PyUnicode_MAX_CHAR_VALUE(thousands_sep));[](#l11.90)
}[](#l11.91)
- }
- return len;
--- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -346,11 +346,13 @@ fill_padding(PyObject *s, Py_ssize_t sta before and including the decimal. Note that locales only support 8-bit chars, not unicode. */ typedef struct {
} LocaleInfo; +#define STATIC_LOCALE_INFO_INIT {0, 0, 0} + /* describes the layout for an integer, see the comment in calc_number_widths() for details */ typedef struct { @@ -415,7 +417,7 @@ calc_number_widths(NumberFieldWidths *sp Py_UCS4 sign_char, PyObject *number, Py_ssize_t n_start, Py_ssize_t n_end, Py_ssize_t n_remainder, int has_decimal, const LocaleInfo *locale,
const InternalFormatSpec *format)[](#l12.24)
const InternalFormatSpec *format, Py_UCS4 *maxchar)[](#l12.25)
{ Py_ssize_t n_non_digit_non_padding; Py_ssize_t n_padding; @@ -423,7 +425,7 @@ calc_number_widths(NumberFieldWidths *sp spec->n_digits = n_end - n_start - n_remainder - (has_decimal?1:0); spec->n_lpadding = 0; spec->n_prefix = n_prefix;
- spec->n_decimal = has_decimal ? PyUnicode_GET_LENGTH(locale->decimal_point) : 0; spec->n_remainder = n_remainder; spec->n_spadding = 0; spec->n_rpadding = 0; @@ -484,11 +486,15 @@ calc_number_widths(NumberFieldWidths *sp to special case it because the grouping code always wants to have at least one character. */ spec->n_grouped_digits = 0;
- else {
Py_UCS4 grouping_maxchar;[](#l12.44) spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping([](#l12.45)
NULL, PyUnicode_1BYTE_KIND, NULL, 0, NULL,[](#l12.46)
NULL, 0,[](#l12.47)
0, NULL,[](#l12.48) spec->n_digits, spec->n_min_width,[](#l12.49)
locale->grouping, locale->thousands_sep);[](#l12.50)
locale->grouping, locale->thousands_sep, &grouping_maxchar);[](#l12.51)
*maxchar = Py_MAX(*maxchar, grouping_maxchar);[](#l12.52)
- }
/* Given the desired width and the total of digit and non-digit space we consume, see if we need any padding. format->width can @@ -519,6 +525,10 @@ calc_number_widths(NumberFieldWidths *sp break; } } +
- if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding)
*maxchar = Py_MAX(*maxchar, format->fill_char);[](#l12.63)
+ 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; @@ -587,12 +597,11 @@ fill_number(PyObject *out, Py_ssize_t po r = #endif _PyUnicode_InsertThousandsGrouping(
out, kind,[](#l12.72)
(char*)data + kind * pos,[](#l12.73)
out, pos,[](#l12.74) spec->n_grouped_digits,[](#l12.75) pdigits + kind * d_pos,[](#l12.76) spec->n_digits, spec->n_min_width,[](#l12.77)
locale->grouping, locale->thousands_sep);[](#l12.78)
locale->grouping, locale->thousands_sep, NULL);[](#l12.79)
#ifndef NDEBUG assert(r == spec->n_grouped_digits); #endif @@ -615,10 +624,8 @@ fill_number(PyObject *out, Py_ssize_t po pos += spec->n_grouped_digits; if (spec->n_decimal) {
Py_ssize_t t;[](#l12.87)
for (t = 0; t < spec->n_decimal; ++t)[](#l12.88)
PyUnicode_WRITE(kind, data, pos + t,[](#l12.89)
locale->decimal_point[t]);[](#l12.90)
if (PyUnicode_CopyCharacters(out, pos, locale->decimal_point, 0, spec->n_decimal) < 0)[](#l12.91)
} @@ -643,32 +650,60 @@ static char no_grouping[1] = {CHAR_MAX}; grouping description, either for the current locale if type is LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or none if LT_NO_LOCALE. */ -static void +static int get_locale_info(int type, LocaleInfo *locale_info) { switch (type) { case LT_CURRENT_LOCALE: { struct lconv *locale_data = localeconv();return -1;[](#l12.92) pos += spec->n_decimal;[](#l12.93) d_pos += 1;[](#l12.94)
locale_info->decimal_point = locale_data->decimal_point;[](#l12.107)
locale_info->thousands_sep = locale_data->thousands_sep;[](#l12.108)
locale_info->decimal_point = PyUnicode_DecodeLocale([](#l12.109)
locale_data->decimal_point,[](#l12.110)
NULL);[](#l12.111)
if (locale_info->decimal_point == NULL)[](#l12.112)
return -1;[](#l12.113)
locale_info->thousands_sep = PyUnicode_DecodeLocale([](#l12.114)
locale_data->thousands_sep,[](#l12.115)
NULL);[](#l12.116)
if (locale_info->thousands_sep == NULL) {[](#l12.117)
Py_DECREF(locale_info->decimal_point);[](#l12.118)
return -1;[](#l12.119)
} case LT_DEFAULT_LOCALE:}[](#l12.120) locale_info->grouping = locale_data->grouping;[](#l12.121) break;[](#l12.122)
locale_info->decimal_point = ".";[](#l12.125)
locale_info->thousands_sep = ",";[](#l12.126)
locale_info->decimal_point = PyUnicode_FromOrdinal('.');[](#l12.127)
locale_info->thousands_sep = PyUnicode_FromOrdinal(',');[](#l12.128)
if (!locale_info->decimal_point || !locale_info->thousands_sep) {[](#l12.129)
Py_XDECREF(locale_info->decimal_point);[](#l12.130)
Py_XDECREF(locale_info->thousands_sep);[](#l12.131)
return -1;[](#l12.132)
case LT_NO_LOCALE:}[](#l12.133) locale_info->grouping = "\3"; /* Group every 3 characters. The[](#l12.134) (implicit) trailing 0 means repeat[](#l12.135) infinitely. */[](#l12.136) break;[](#l12.137)
locale_info->decimal_point = ".";[](#l12.139)
locale_info->thousands_sep = "";[](#l12.140)
locale_info->decimal_point = PyUnicode_FromOrdinal('.');[](#l12.141)
locale_info->thousands_sep = PyUnicode_New(0, 0);[](#l12.142)
if (!locale_info->decimal_point || !locale_info->thousands_sep) {[](#l12.143)
Py_XDECREF(locale_info->decimal_point);[](#l12.144)
Py_XDECREF(locale_info->thousands_sep);[](#l12.145)
return -1;[](#l12.146)
default: assert(0); }}[](#l12.147) locale_info->grouping = no_grouping;[](#l12.148) break;[](#l12.149)
- return 0;
+} + +static void +free_locale_info(LocaleInfo *locale_info) +{
} /************************************************************************/ @@ -769,7 +804,7 @@ format_int_or_long_internal(PyObject va / Locale settings, either from the actual locale or from a hard-code pseudo-locale */
/* no precision allowed on integers */ if (format->precision != -1) { @@ -868,18 +903,17 @@ format_int_or_long_internal(PyObject va } / Determine the grouping, separator, and decimal point, if any. */
- get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
(format->thousands_separators ?[](#l12.178)
LT_DEFAULT_LOCALE :[](#l12.179)
LT_NO_LOCALE),[](#l12.180)
&locale);[](#l12.181)
- if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
(format->thousands_separators ?[](#l12.183)
LT_DEFAULT_LOCALE :[](#l12.184)
LT_NO_LOCALE),[](#l12.185)
&locale) == -1)[](#l12.186)
goto done;[](#l12.187)
/* Calculate how much memory we'll need. */ n_total = calc_number_widths(&spec, n_prefix, sign_char, tmp, inumeric_chars,
inumeric_chars + n_digits, n_remainder, 0, &locale, format);[](#l12.191)
- if (spec.n_lpadding || spec.n_spadding || spec.n_rpadding)
maxchar = Py_MAX(maxchar, format->fill_char);[](#l12.194)
inumeric_chars + n_digits, n_remainder, 0,[](#l12.195)
&locale, format, &maxchar);[](#l12.196)
/* Allocate the memory. */ result = PyUnicode_New(n_total, maxchar); @@ -897,6 +931,7 @@ format_int_or_long_internal(PyObject *va done: Py_XDECREF(tmp);
- free_locale_info(&locale); assert(!result || _PyUnicode_CheckConsistency(result, 1)); return result; }
@@ -938,7 +973,7 @@ format_float_internal(PyObject value, / Locale settings, either from the actual locale or from a hard-code pseudo-locale */
if (format->alternate) flags |= Py_DTSF_ALT; @@ -1009,19 +1044,17 @@ format_float_internal(PyObject value, parse_number(unicode_tmp, index, index + n_digits, &n_remainder, &has_decimal); / Determine the grouping, separator, and decimal point, if any. */
- get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
(format->thousands_separators ?[](#l12.222)
LT_DEFAULT_LOCALE :[](#l12.223)
LT_NO_LOCALE),[](#l12.224)
&locale);[](#l12.225)
- if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
(format->thousands_separators ?[](#l12.227)
LT_DEFAULT_LOCALE :[](#l12.228)
LT_NO_LOCALE),[](#l12.229)
&locale) == -1)[](#l12.230)
goto done;[](#l12.231)
/* Calculate how much memory we'll need. */ n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index, index + n_digits, n_remainder, has_decimal,
&locale, format);[](#l12.236)
- if (spec.n_lpadding || spec.n_spadding || spec.n_rpadding)
maxchar = Py_MAX(maxchar, format->fill_char);[](#l12.239)
&locale, format, &maxchar);[](#l12.240)
/* Allocate the memory. */ result = PyUnicode_New(n_total, maxchar); @@ -1040,6 +1073,7 @@ format_float_internal(PyObject *value, done: PyMem_Free(buf); Py_DECREF(unicode_tmp);
- free_locale_info(&locale); assert(!result || _PyUnicode_CheckConsistency(result, 1)); return result; }
@@ -1094,7 +1128,7 @@ format_complex_internal(PyObject value, / Locale settings, either from the actual locale or from a hard-code pseudo-locale */
/* Zero padding is not allowed. */ if (format->fill_char == '0') { @@ -1190,11 +1224,12 @@ format_complex_internal(PyObject value, &n_im_remainder, &im_has_decimal); / Determine the grouping, separator, and decimal point, if any. */
- get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
(format->thousands_separators ?[](#l12.266)
LT_DEFAULT_LOCALE :[](#l12.267)
LT_NO_LOCALE),[](#l12.268)
&locale);[](#l12.269)
- if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
(format->thousands_separators ?[](#l12.271)
LT_DEFAULT_LOCALE :[](#l12.272)
LT_NO_LOCALE),[](#l12.273)
&locale) == -1)[](#l12.274)
goto done;[](#l12.275)
/* Turn off any padding. We'll do it later after we've composed the numbers without padding. */ @@ -1205,7 +1240,8 @@ format_complex_internal(PyObject value, / Calculate how much memory we'll need. */ n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, re_unicode_tmp, i_re, i_re + n_re_digits, n_re_remainder,
re_has_decimal, &locale, &tmp_format);[](#l12.283)
re_has_decimal, &locale, &tmp_format,[](#l12.284)
&maxchar);[](#l12.285)
/* Same formatting, but always include a sign, unless the real part is * going to be omitted, in which case we use whatever sign convention was @@ -1214,7 +1250,8 @@ format_complex_internal(PyObject *value, tmp_format.sign = '+'; n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, im_unicode_tmp, i_im, i_im + n_im_digits, n_im_remainder,
im_has_decimal, &locale, &tmp_format);[](#l12.293)
im_has_decimal, &locale, &tmp_format,[](#l12.294)
&maxchar);[](#l12.295)
if (skip_re) n_re_total = 0; @@ -1223,9 +1260,7 @@ format_complex_internal(PyObject *value, calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, 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[](#l12.304)
|| lpad || rpad)[](#l12.305)
result = PyUnicode_New(total, maxchar); @@ -1275,6 +1310,7 @@ done: PyMem_Free(im_buf); Py_XDECREF(re_unicode_tmp); Py_XDECREF(im_unicode_tmp);