Mercurial > cpython-lru_cache-weakref
annotate Python/formatter_unicode.c @ 87690:66c1c9f32567 default tip
Add use_weakref option to functools.lru_cache
The use_weakref option makes lru_cache create weak references to the function
arguments when creating the cache key, which prevents them from staying in the
memory forever even after all other references to them are gone.
This is a proof of concept for http://bugs.python.org/issue19859
| author | Radomir Dopieralski <devel@sheep.art.pl> |
|---|---|
| date | Tue, 03 Dec 2013 16:02:48 +0100 |
| parents | d1ca05428c38 |
| children |
| rev | line source |
|---|---|
|
42817
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
diff
changeset
|
1 /* implements the unicode (as opposed to string) version of the |
|
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
diff
changeset
|
2 built-in formatters for string, int, float. that is, the versions |
|
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
diff
changeset
|
3 of int.__float__, etc., that take and return unicode objects */ |
|
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
diff
changeset
|
4 |
|
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
diff
changeset
|
5 #include "Python.h" |
| 72475 | 6 #include <locale.h> |
| 7 | |
| 8 /* Raises an exception about an unknown presentation type for this | |
| 9 * type. */ | |
| 10 | |
| 11 static void | |
| 12 unknown_presentation_type(Py_UCS4 presentation_type, | |
| 13 const char* type_name) | |
| 14 { | |
| 15 /* %c might be out-of-range, hence the two cases. */ | |
| 16 if (presentation_type > 32 && presentation_type < 128) | |
| 17 PyErr_Format(PyExc_ValueError, | |
| 18 "Unknown format code '%c' " | |
| 19 "for object of type '%.200s'", | |
| 20 (char)presentation_type, | |
| 21 type_name); | |
| 22 else | |
| 23 PyErr_Format(PyExc_ValueError, | |
| 24 "Unknown format code '\\x%x' " | |
| 25 "for object of type '%.200s'", | |
| 26 (unsigned int)presentation_type, | |
| 27 type_name); | |
| 28 } | |
| 29 | |
| 30 static void | |
| 31 invalid_comma_type(Py_UCS4 presentation_type) | |
| 32 { | |
| 33 if (presentation_type > 32 && presentation_type < 128) | |
| 34 PyErr_Format(PyExc_ValueError, | |
| 35 "Cannot specify ',' with '%c'.", | |
| 36 (char)presentation_type); | |
| 37 else | |
| 38 PyErr_Format(PyExc_ValueError, | |
| 39 "Cannot specify ',' with '\\x%x'.", | |
| 40 (unsigned int)presentation_type); | |
| 41 } | |
| 42 | |
| 43 /* | |
| 44 get_integer consumes 0 or more decimal digit characters from an | |
| 45 input string, updates *result with the corresponding positive | |
| 46 integer, and returns the number of digits consumed. | |
| 47 | |
| 48 returns -1 on error. | |
| 49 */ | |
| 50 static int | |
| 51 get_integer(PyObject *str, Py_ssize_t *pos, Py_ssize_t end, | |
| 52 Py_ssize_t *result) | |
| 53 { | |
|
73805
7e37598a25a6
Issue #9530: Fix undefined behaviour due to signed overflow in Python/formatter_unicode.c.
Mark Dickinson <mdickinson@enthought.com>
parents:
72863
diff
changeset
|
54 Py_ssize_t accumulator, digitval; |
| 72475 | 55 int numdigits; |
| 56 accumulator = numdigits = 0; | |
| 57 for (;;(*pos)++, numdigits++) { | |
| 58 if (*pos >= end) | |
| 59 break; | |
| 60 digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ_CHAR(str, *pos)); | |
| 61 if (digitval < 0) | |
| 62 break; | |
| 63 /* | |
|
73805
7e37598a25a6
Issue #9530: Fix undefined behaviour due to signed overflow in Python/formatter_unicode.c.
Mark Dickinson <mdickinson@enthought.com>
parents:
72863
diff
changeset
|
64 Detect possible overflow before it happens: |
|
7e37598a25a6
Issue #9530: Fix undefined behaviour due to signed overflow in Python/formatter_unicode.c.
Mark Dickinson <mdickinson@enthought.com>
parents:
72863
diff
changeset
|
65 |
|
7e37598a25a6
Issue #9530: Fix undefined behaviour due to signed overflow in Python/formatter_unicode.c.
Mark Dickinson <mdickinson@enthought.com>
parents:
72863
diff
changeset
|
66 accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if |
|
7e37598a25a6
Issue #9530: Fix undefined behaviour due to signed overflow in Python/formatter_unicode.c.
Mark Dickinson <mdickinson@enthought.com>
parents:
72863
diff
changeset
|
67 accumulator > (PY_SSIZE_T_MAX - digitval) / 10. |
| 72475 | 68 */ |
|
73805
7e37598a25a6
Issue #9530: Fix undefined behaviour due to signed overflow in Python/formatter_unicode.c.
Mark Dickinson <mdickinson@enthought.com>
parents:
72863
diff
changeset
|
69 if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) { |
| 72475 | 70 PyErr_Format(PyExc_ValueError, |
| 71 "Too many decimal digits in format string"); | |
| 72 return -1; | |
| 73 } | |
|
73805
7e37598a25a6
Issue #9530: Fix undefined behaviour due to signed overflow in Python/formatter_unicode.c.
Mark Dickinson <mdickinson@enthought.com>
parents:
72863
diff
changeset
|
74 accumulator = accumulator * 10 + digitval; |
| 72475 | 75 } |
| 76 *result = accumulator; | |
| 77 return numdigits; | |
| 78 } | |
| 79 | |
| 80 /************************************************************************/ | |
| 81 /*********** standard format specifier parsing **************************/ | |
| 82 /************************************************************************/ | |
| 83 | |
| 84 /* returns true if this character is a specifier alignment token */ | |
| 85 Py_LOCAL_INLINE(int) | |
| 86 is_alignment_token(Py_UCS4 c) | |
| 87 { | |
| 88 switch (c) { | |
| 89 case '<': case '>': case '=': case '^': | |
| 90 return 1; | |
| 91 default: | |
| 92 return 0; | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 /* returns true if this character is a sign element */ | |
| 97 Py_LOCAL_INLINE(int) | |
| 98 is_sign_element(Py_UCS4 c) | |
| 99 { | |
| 100 switch (c) { | |
| 101 case ' ': case '+': case '-': | |
| 102 return 1; | |
| 103 default: | |
| 104 return 0; | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 | |
| 109 typedef struct { | |
| 110 Py_UCS4 fill_char; | |
| 111 Py_UCS4 align; | |
| 112 int alternate; | |
| 113 Py_UCS4 sign; | |
| 114 Py_ssize_t width; | |
| 115 int thousands_separators; | |
| 116 Py_ssize_t precision; | |
| 117 Py_UCS4 type; | |
| 118 } InternalFormatSpec; | |
| 119 | |
| 120 #if 0 | |
| 121 /* Occassionally useful for debugging. Should normally be commented out. */ | |
| 122 static void | |
| 123 DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format) | |
| 124 { | |
| 125 printf("internal format spec: fill_char %d\n", format->fill_char); | |
| 126 printf("internal format spec: align %d\n", format->align); | |
| 127 printf("internal format spec: alternate %d\n", format->alternate); | |
| 128 printf("internal format spec: sign %d\n", format->sign); | |
| 129 printf("internal format spec: width %zd\n", format->width); | |
| 130 printf("internal format spec: thousands_separators %d\n", | |
| 131 format->thousands_separators); | |
| 132 printf("internal format spec: precision %zd\n", format->precision); | |
| 133 printf("internal format spec: type %c\n", format->type); | |
| 134 printf("\n"); | |
| 135 } | |
| 136 #endif | |
| 137 | |
| 138 | |
| 139 /* | |
| 140 ptr points to the start of the format_spec, end points just past its end. | |
| 141 fills in format with the parsed information. | |
| 142 returns 1 on success, 0 on failure. | |
| 143 if failure, sets the exception | |
| 144 */ | |
| 145 static int | |
| 146 parse_internal_render_format_spec(PyObject *format_spec, | |
| 147 Py_ssize_t start, Py_ssize_t end, | |
| 148 InternalFormatSpec *format, | |
| 149 char default_type, | |
| 150 char default_align) | |
| 151 { | |
| 152 Py_ssize_t pos = start; | |
| 153 /* end-pos is used throughout this code to specify the length of | |
| 154 the input string */ | |
| 155 #define READ_spec(index) PyUnicode_READ_CHAR(format_spec, index) | |
| 156 | |
| 157 Py_ssize_t consumed; | |
| 158 int align_specified = 0; | |
| 159 | |
| 160 format->fill_char = '\0'; | |
| 161 format->align = default_align; | |
| 162 format->alternate = 0; | |
| 163 format->sign = '\0'; | |
| 164 format->width = -1; | |
| 165 format->thousands_separators = 0; | |
| 166 format->precision = -1; | |
| 167 format->type = default_type; | |
| 168 | |
| 169 /* If the second char is an alignment token, | |
| 170 then parse the fill char */ | |
| 171 if (end-pos >= 2 && is_alignment_token(READ_spec(pos+1))) { | |
| 172 format->align = READ_spec(pos+1); | |
| 173 format->fill_char = READ_spec(pos); | |
| 174 align_specified = 1; | |
| 175 pos += 2; | |
| 176 } | |
| 177 else if (end-pos >= 1 && is_alignment_token(READ_spec(pos))) { | |
| 178 format->align = READ_spec(pos); | |
| 179 align_specified = 1; | |
| 180 ++pos; | |
| 181 } | |
| 182 | |
| 183 /* Parse the various sign options */ | |
| 184 if (end-pos >= 1 && is_sign_element(READ_spec(pos))) { | |
| 185 format->sign = READ_spec(pos); | |
| 186 ++pos; | |
| 187 } | |
| 188 | |
| 189 /* If the next character is #, we're in alternate mode. This only | |
| 190 applies to integers. */ | |
| 191 if (end-pos >= 1 && READ_spec(pos) == '#') { | |
| 192 format->alternate = 1; | |
| 193 ++pos; | |
| 194 } | |
| 195 | |
| 196 /* The special case for 0-padding (backwards compat) */ | |
| 197 if (format->fill_char == '\0' && end-pos >= 1 && READ_spec(pos) == '0') { | |
| 198 format->fill_char = '0'; | |
| 199 if (!align_specified) { | |
| 200 format->align = '='; | |
| 201 } | |
| 202 ++pos; | |
| 203 } | |
| 204 | |
| 205 consumed = get_integer(format_spec, &pos, end, &format->width); | |
| 206 if (consumed == -1) | |
| 207 /* Overflow error. Exception already set. */ | |
| 208 return 0; | |
| 209 | |
| 210 /* If consumed is 0, we didn't consume any characters for the | |
| 211 width. In that case, reset the width to -1, because | |
| 212 get_integer() will have set it to zero. -1 is how we record | |
| 213 that the width wasn't specified. */ | |
| 214 if (consumed == 0) | |
| 215 format->width = -1; | |
| 216 | |
| 217 /* Comma signifies add thousands separators */ | |
| 218 if (end-pos && READ_spec(pos) == ',') { | |
| 219 format->thousands_separators = 1; | |
| 220 ++pos; | |
| 221 } | |
| 222 | |
| 223 /* Parse field precision */ | |
| 224 if (end-pos && READ_spec(pos) == '.') { | |
| 225 ++pos; | |
| 226 | |
| 227 consumed = get_integer(format_spec, &pos, end, &format->precision); | |
| 228 if (consumed == -1) | |
| 229 /* Overflow error. Exception already set. */ | |
| 230 return 0; | |
| 231 | |
| 232 /* Not having a precision after a dot is an error. */ | |
| 233 if (consumed == 0) { | |
| 234 PyErr_Format(PyExc_ValueError, | |
| 235 "Format specifier missing precision"); | |
| 236 return 0; | |
| 237 } | |
| 238 | |
| 239 } | |
| 240 | |
| 241 /* Finally, parse the type field. */ | |
| 242 | |
| 243 if (end-pos > 1) { | |
|
74533
5c33ebb50702
Improve exception text. Closes issue 13811.
Eric V. Smith <eric@trueblade.com>
parents:
74341
diff
changeset
|
244 /* More than one char remain, invalid format specifier. */ |
|
5c33ebb50702
Improve exception text. Closes issue 13811.
Eric V. Smith <eric@trueblade.com>
parents:
74341
diff
changeset
|
245 PyErr_Format(PyExc_ValueError, "Invalid format specifier"); |
| 72475 | 246 return 0; |
| 247 } | |
| 248 | |
| 249 if (end-pos == 1) { | |
| 250 format->type = READ_spec(pos); | |
| 251 ++pos; | |
| 252 } | |
| 253 | |
| 254 /* Do as much validating as we can, just by looking at the format | |
| 255 specifier. Do not take into account what type of formatting | |
| 256 we're doing (int, float, string). */ | |
| 257 | |
| 258 if (format->thousands_separators) { | |
| 259 switch (format->type) { | |
| 260 case 'd': | |
| 261 case 'e': | |
| 262 case 'f': | |
| 263 case 'g': | |
| 264 case 'E': | |
| 265 case 'G': | |
| 266 case '%': | |
| 267 case 'F': | |
| 268 case '\0': | |
| 269 /* These are allowed. See PEP 378.*/ | |
| 270 break; | |
| 271 default: | |
| 272 invalid_comma_type(format->type); | |
| 273 return 0; | |
| 274 } | |
| 275 } | |
| 276 | |
|
74557
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
277 assert (format->align <= 127); |
|
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
278 assert (format->sign <= 127); |
| 72475 | 279 return 1; |
| 280 } | |
| 281 | |
| 282 /* Calculate the padding needed. */ | |
| 283 static void | |
| 284 calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align, | |
| 285 Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding, | |
| 286 Py_ssize_t *n_total) | |
| 287 { | |
| 288 if (width >= 0) { | |
| 289 if (nchars > width) | |
| 290 *n_total = nchars; | |
| 291 else | |
| 292 *n_total = width; | |
| 293 } | |
| 294 else { | |
| 295 /* not specified, use all of the chars and no more */ | |
| 296 *n_total = nchars; | |
| 297 } | |
| 298 | |
| 299 /* Figure out how much leading space we need, based on the | |
| 300 aligning */ | |
| 301 if (align == '>') | |
| 302 *n_lpadding = *n_total - nchars; | |
| 303 else if (align == '^') | |
| 304 *n_lpadding = (*n_total - nchars) / 2; | |
| 305 else if (align == '<' || align == '=') | |
| 306 *n_lpadding = 0; | |
| 307 else { | |
| 308 /* We should never have an unspecified alignment. */ | |
| 309 *n_lpadding = 0; | |
| 310 assert(0); | |
| 311 } | |
| 312 | |
| 313 *n_rpadding = *n_total - nchars - *n_lpadding; | |
| 314 } | |
| 315 | |
| 316 /* Do the padding, and return a pointer to where the caller-supplied | |
| 317 content goes. */ | |
|
83801
16a00dd78cd0
Fix a compilater warning on Windows 64-bit
Victor Stinner <victor.stinner@gmail.com>
parents:
83675
diff
changeset
|
318 static int |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
319 fill_padding(_PyUnicodeWriter *writer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
320 Py_ssize_t nchars, |
| 72475 | 321 Py_UCS4 fill_char, Py_ssize_t n_lpadding, |
| 322 Py_ssize_t n_rpadding) | |
| 323 { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
324 Py_ssize_t pos; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
325 |
| 72475 | 326 /* Pad on left. */ |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
327 if (n_lpadding) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
328 pos = writer->pos; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
329 _PyUnicode_FastFill(writer->buffer, pos, n_lpadding, fill_char); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
330 } |
| 72475 | 331 |
| 332 /* Pad on right. */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
333 if (n_rpadding) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
334 pos = writer->pos + nchars + n_lpadding; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
335 _PyUnicode_FastFill(writer->buffer, pos, n_rpadding, fill_char); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
336 } |
| 72475 | 337 |
| 338 /* Pointer to the user content. */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
339 writer->pos += n_lpadding; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
340 return 0; |
| 72475 | 341 } |
| 342 | |
| 343 /************************************************************************/ | |
| 344 /*********** common routines for numeric formatting *********************/ | |
| 345 /************************************************************************/ | |
| 346 | |
| 347 /* Locale type codes. */ | |
| 348 #define LT_CURRENT_LOCALE 0 | |
| 349 #define LT_DEFAULT_LOCALE 1 | |
| 350 #define LT_NO_LOCALE 2 | |
| 351 | |
| 352 /* Locale info needed for formatting integers and the part of floats | |
| 353 before and including the decimal. Note that locales only support | |
| 354 8-bit chars, not unicode. */ | |
| 355 typedef struct { | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
356 PyObject *decimal_point; |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
357 PyObject *thousands_sep; |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
358 const char *grouping; |
| 72475 | 359 } LocaleInfo; |
| 360 | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
361 #define STATIC_LOCALE_INFO_INIT {0, 0, 0} |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
362 |
| 72475 | 363 /* describes the layout for an integer, see the comment in |
| 364 calc_number_widths() for details */ | |
| 365 typedef struct { | |
| 366 Py_ssize_t n_lpadding; | |
| 367 Py_ssize_t n_prefix; | |
| 368 Py_ssize_t n_spadding; | |
| 369 Py_ssize_t n_rpadding; | |
| 370 char sign; | |
| 371 Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */ | |
| 372 Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including | |
| 373 any grouping chars. */ | |
| 374 Py_ssize_t n_decimal; /* 0 if only an integer */ | |
| 375 Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part, | |
| 376 excluding the decimal itself, if | |
| 377 present. */ | |
| 378 | |
| 379 /* These 2 are not the widths of fields, but are needed by | |
| 380 STRINGLIB_GROUPING. */ | |
| 381 Py_ssize_t n_digits; /* The number of digits before a decimal | |
| 382 or exponent. */ | |
| 383 Py_ssize_t n_min_width; /* The min_width we used when we computed | |
| 384 the n_grouped_digits width. */ | |
| 385 } NumberFieldWidths; | |
|
42817
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
diff
changeset
|
386 |
|
47393
0da27fdf0192
Refactor and clean up str.format() code (and helpers) in advance of optimizations.
Eric Smith <eric@trueblade.com>
parents:
42817
diff
changeset
|
387 |
| 72475 | 388 /* Given a number of the form: |
| 389 digits[remainder] | |
| 390 where ptr points to the start and end points to the end, find where | |
| 391 the integer part ends. This could be a decimal, an exponent, both, | |
| 392 or neither. | |
| 393 If a decimal point is present, set *has_decimal and increment | |
| 394 remainder beyond it. | |
| 395 Results are undefined (but shouldn't crash) for improperly | |
| 396 formatted strings. | |
| 397 */ | |
| 398 static void | |
| 399 parse_number(PyObject *s, Py_ssize_t pos, Py_ssize_t end, | |
| 400 Py_ssize_t *n_remainder, int *has_decimal) | |
| 401 { | |
| 402 Py_ssize_t remainder; | |
| 403 | |
|
82111
c08bcf5302ec
Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.) in the interpreter.
Antoine Pitrou <solipsis@pitrou.net>
parents:
78860
diff
changeset
|
404 while (pos<end && Py_ISDIGIT(PyUnicode_READ_CHAR(s, pos))) |
| 72475 | 405 ++pos; |
| 406 remainder = pos; | |
| 407 | |
| 408 /* Does remainder start with a decimal point? */ | |
| 409 *has_decimal = pos<end && PyUnicode_READ_CHAR(s, remainder) == '.'; | |
| 410 | |
| 411 /* Skip the decimal point. */ | |
| 412 if (*has_decimal) | |
| 413 remainder++; | |
| 414 | |
| 415 *n_remainder = end - remainder; | |
| 416 } | |
| 417 | |
| 418 /* not all fields of format are used. for example, precision is | |
| 419 unused. should this take discrete params in order to be more clear | |
| 420 about what it does? or is passing a single format parameter easier | |
| 421 and more efficient enough to justify a little obfuscation? */ | |
| 422 static Py_ssize_t | |
| 423 calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, | |
| 424 Py_UCS4 sign_char, PyObject *number, Py_ssize_t n_start, | |
| 425 Py_ssize_t n_end, Py_ssize_t n_remainder, | |
| 426 int has_decimal, const LocaleInfo *locale, | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
427 const InternalFormatSpec *format, Py_UCS4 *maxchar) |
| 72475 | 428 { |
| 429 Py_ssize_t n_non_digit_non_padding; | |
| 430 Py_ssize_t n_padding; | |
| 431 | |
| 432 spec->n_digits = n_end - n_start - n_remainder - (has_decimal?1:0); | |
| 433 spec->n_lpadding = 0; | |
| 434 spec->n_prefix = n_prefix; | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
435 spec->n_decimal = has_decimal ? PyUnicode_GET_LENGTH(locale->decimal_point) : 0; |
| 72475 | 436 spec->n_remainder = n_remainder; |
| 437 spec->n_spadding = 0; | |
| 438 spec->n_rpadding = 0; | |
| 439 spec->sign = '\0'; | |
| 440 spec->n_sign = 0; | |
| 441 | |
| 442 /* the output will look like: | |
| 443 | | | |
| 444 | <lpadding> <sign> <prefix> <spadding> <grouped_digits> <decimal> <remainder> <rpadding> | | |
| 445 | | | |
| 446 | |
| 447 sign is computed from format->sign and the actual | |
| 448 sign of the number | |
| 449 | |
| 450 prefix is given (it's for the '0x' prefix) | |
| 451 | |
| 452 digits is already known | |
| 453 | |
| 454 the total width is either given, or computed from the | |
| 455 actual digits | |
| 456 | |
| 457 only one of lpadding, spadding, and rpadding can be non-zero, | |
| 458 and it's calculated from the width and other fields | |
| 459 */ | |
| 460 | |
| 461 /* compute the various parts we're going to write */ | |
| 462 switch (format->sign) { | |
| 463 case '+': | |
| 464 /* always put a + or - */ | |
| 465 spec->n_sign = 1; | |
| 466 spec->sign = (sign_char == '-' ? '-' : '+'); | |
| 467 break; | |
| 468 case ' ': | |
| 469 spec->n_sign = 1; | |
| 470 spec->sign = (sign_char == '-' ? '-' : ' '); | |
| 471 break; | |
| 472 default: | |
| 473 /* Not specified, or the default (-) */ | |
| 474 if (sign_char == '-') { | |
| 475 spec->n_sign = 1; | |
| 476 spec->sign = '-'; | |
| 477 } | |
| 478 } | |
| 479 | |
| 480 /* The number of chars used for non-digits and non-padding. */ | |
| 481 n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal + | |
| 482 spec->n_remainder; | |
| 483 | |
| 484 /* min_width can go negative, that's okay. format->width == -1 means | |
| 485 we don't care. */ | |
| 486 if (format->fill_char == '0' && format->align == '=') | |
| 487 spec->n_min_width = format->width - n_non_digit_non_padding; | |
| 488 else | |
| 489 spec->n_min_width = 0; | |
| 490 | |
| 491 if (spec->n_digits == 0) | |
| 492 /* This case only occurs when using 'c' formatting, we need | |
| 493 to special case it because the grouping code always wants | |
| 494 to have at least one character. */ | |
| 495 spec->n_grouped_digits = 0; | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
496 else { |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
497 Py_UCS4 grouping_maxchar; |
| 72475 | 498 spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping( |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
499 NULL, 0, |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
500 0, NULL, |
| 72475 | 501 spec->n_digits, spec->n_min_width, |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
502 locale->grouping, locale->thousands_sep, &grouping_maxchar); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
503 *maxchar = Py_MAX(*maxchar, grouping_maxchar); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
504 } |
| 72475 | 505 |
| 506 /* Given the desired width and the total of digit and non-digit | |
| 507 space we consume, see if we need any padding. format->width can | |
| 508 be negative (meaning no padding), but this code still works in | |
| 509 that case. */ | |
| 510 n_padding = format->width - | |
| 511 (n_non_digit_non_padding + spec->n_grouped_digits); | |
| 512 if (n_padding > 0) { | |
| 513 /* Some padding is needed. Determine if it's left, space, or right. */ | |
| 514 switch (format->align) { | |
| 515 case '<': | |
| 516 spec->n_rpadding = n_padding; | |
| 517 break; | |
| 518 case '^': | |
| 519 spec->n_lpadding = n_padding / 2; | |
| 520 spec->n_rpadding = n_padding - spec->n_lpadding; | |
| 521 break; | |
| 522 case '=': | |
| 523 spec->n_spadding = n_padding; | |
| 524 break; | |
| 525 case '>': | |
| 526 spec->n_lpadding = n_padding; | |
| 527 break; | |
| 528 default: | |
| 529 /* Shouldn't get here, but treat it as '>' */ | |
| 530 spec->n_lpadding = n_padding; | |
| 531 assert(0); | |
| 532 break; | |
| 533 } | |
| 534 } | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
535 |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
536 if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding) |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
537 *maxchar = Py_MAX(*maxchar, format->fill_char); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
538 |
|
75234
a29d20fa85b4
Issue #13706: Fix format(float, "n") for locale with non-ASCII decimal point (e.g. ps_aF)
Victor Stinner <victor.stinner@haypocalc.com>
parents:
75231
diff
changeset
|
539 if (spec->n_decimal) |
|
a29d20fa85b4
Issue #13706: Fix format(float, "n") for locale with non-ASCII decimal point (e.g. ps_aF)
Victor Stinner <victor.stinner@haypocalc.com>
parents:
75231
diff
changeset
|
540 *maxchar = Py_MAX(*maxchar, PyUnicode_MAX_CHAR_VALUE(locale->decimal_point)); |
|
a29d20fa85b4
Issue #13706: Fix format(float, "n") for locale with non-ASCII decimal point (e.g. ps_aF)
Victor Stinner <victor.stinner@haypocalc.com>
parents:
75231
diff
changeset
|
541 |
| 72475 | 542 return spec->n_lpadding + spec->n_sign + spec->n_prefix + |
| 543 spec->n_spadding + spec->n_grouped_digits + spec->n_decimal + | |
| 544 spec->n_remainder + spec->n_rpadding; | |
| 545 } | |
| 546 | |
| 547 /* Fill in the digit parts of a numbers's string representation, | |
| 548 as determined in calc_number_widths(). | |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
549 Return -1 on error, or 0 on success. */ |
|
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
550 static int |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
551 fill_number(_PyUnicodeWriter *writer, const NumberFieldWidths *spec, |
| 72475 | 552 PyObject *digits, Py_ssize_t d_start, Py_ssize_t d_end, |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
553 PyObject *prefix, Py_ssize_t p_start, |
|
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
554 Py_UCS4 fill_char, |
| 72475 | 555 LocaleInfo *locale, int toupper) |
| 556 { | |
| 557 /* Used to keep track of digits, decimal, and remainder. */ | |
| 558 Py_ssize_t d_pos = d_start; | |
|
83675
4ce2a4e75ad3
Fix a compiler warning: use unsigned int type instead of enum PyUnicode_Kind to
Victor Stinner <victor.stinner@gmail.com>
parents:
83067
diff
changeset
|
559 const unsigned int kind = writer->kind; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
560 const void *data = writer->data; |
| 72475 | 561 Py_ssize_t r; |
| 562 | |
| 563 if (spec->n_lpadding) { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
564 _PyUnicode_FastFill(writer->buffer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
565 writer->pos, spec->n_lpadding, fill_char); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
566 writer->pos += spec->n_lpadding; |
| 72475 | 567 } |
| 568 if (spec->n_sign == 1) { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
569 PyUnicode_WRITE(kind, data, writer->pos, spec->sign); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
570 writer->pos++; |
| 72475 | 571 } |
| 572 if (spec->n_prefix) { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
573 _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
574 prefix, p_start, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
575 spec->n_prefix); |
| 72475 | 576 if (toupper) { |
| 577 Py_ssize_t t; | |
|
74341
c2153ce1b5dd
remove some usage of Py_UNICODE_TOUPPER/LOWER
Benjamin Peterson <benjamin@python.org>
parents:
74261
diff
changeset
|
578 for (t = 0; t < spec->n_prefix; t++) { |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
579 Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t); |
|
74702
056f5cc8885d
Issue #13706: Add assertions to detect bugs earlier
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74586
diff
changeset
|
580 c = Py_TOUPPER(c); |
|
74557
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
581 assert (c <= 127); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
582 PyUnicode_WRITE(kind, data, writer->pos + t, c); |
|
74341
c2153ce1b5dd
remove some usage of Py_UNICODE_TOUPPER/LOWER
Benjamin Peterson <benjamin@python.org>
parents:
74261
diff
changeset
|
583 } |
| 72475 | 584 } |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
585 writer->pos += spec->n_prefix; |
| 72475 | 586 } |
| 587 if (spec->n_spadding) { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
588 _PyUnicode_FastFill(writer->buffer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
589 writer->pos, spec->n_spadding, fill_char); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
590 writer->pos += spec->n_spadding; |
| 72475 | 591 } |
| 592 | |
| 593 /* Only for type 'c' special case, it has no digits. */ | |
| 594 if (spec->n_digits != 0) { | |
| 595 /* Fill the digits with InsertThousandsGrouping. */ | |
|
72496
ad337be523bf
fill_number() ensures that the 'digits' string is ready
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72495
diff
changeset
|
596 char *pdigits; |
|
ad337be523bf
fill_number() ensures that the 'digits' string is ready
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72495
diff
changeset
|
597 if (PyUnicode_READY(digits)) |
|
ad337be523bf
fill_number() ensures that the 'digits' string is ready
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72495
diff
changeset
|
598 return -1; |
|
ad337be523bf
fill_number() ensures that the 'digits' string is ready
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72495
diff
changeset
|
599 pdigits = PyUnicode_DATA(digits); |
| 72475 | 600 if (PyUnicode_KIND(digits) < kind) { |
| 601 pdigits = _PyUnicode_AsKind(digits, kind); | |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
602 if (pdigits == NULL) |
|
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
603 return -1; |
| 72475 | 604 } |
|
75234
a29d20fa85b4
Issue #13706: Fix format(float, "n") for locale with non-ASCII decimal point (e.g. ps_aF)
Victor Stinner <victor.stinner@haypocalc.com>
parents:
75231
diff
changeset
|
605 r = _PyUnicode_InsertThousandsGrouping( |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
606 writer->buffer, writer->pos, |
| 72475 | 607 spec->n_grouped_digits, |
|
72796
c25262e97304
Change PyUnicode_KIND to 1,2,4. Drop _KIND_SIZE and _CHARACTER_SIZE.
Martin v. Löwis <martin@v.loewis.de>
parents:
72714
diff
changeset
|
608 pdigits + kind * d_pos, |
| 72475 | 609 spec->n_digits, spec->n_min_width, |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
610 locale->grouping, locale->thousands_sep, NULL); |
|
75234
a29d20fa85b4
Issue #13706: Fix format(float, "n") for locale with non-ASCII decimal point (e.g. ps_aF)
Victor Stinner <victor.stinner@haypocalc.com>
parents:
75231
diff
changeset
|
611 if (r == -1) |
|
a29d20fa85b4
Issue #13706: Fix format(float, "n") for locale with non-ASCII decimal point (e.g. ps_aF)
Victor Stinner <victor.stinner@haypocalc.com>
parents:
75231
diff
changeset
|
612 return -1; |
| 72475 | 613 assert(r == spec->n_grouped_digits); |
| 614 if (PyUnicode_KIND(digits) < kind) | |
| 615 PyMem_Free(pdigits); | |
| 616 d_pos += spec->n_digits; | |
| 617 } | |
| 618 if (toupper) { | |
| 619 Py_ssize_t t; | |
|
74341
c2153ce1b5dd
remove some usage of Py_UNICODE_TOUPPER/LOWER
Benjamin Peterson <benjamin@python.org>
parents:
74261
diff
changeset
|
620 for (t = 0; t < spec->n_grouped_digits; t++) { |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
621 Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t); |
|
74702
056f5cc8885d
Issue #13706: Add assertions to detect bugs earlier
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74586
diff
changeset
|
622 c = Py_TOUPPER(c); |
|
74341
c2153ce1b5dd
remove some usage of Py_UNICODE_TOUPPER/LOWER
Benjamin Peterson <benjamin@python.org>
parents:
74261
diff
changeset
|
623 if (c > 127) { |
|
c2153ce1b5dd
remove some usage of Py_UNICODE_TOUPPER/LOWER
Benjamin Peterson <benjamin@python.org>
parents:
74261
diff
changeset
|
624 PyErr_SetString(PyExc_SystemError, "non-ascii grouped digit"); |
|
c2153ce1b5dd
remove some usage of Py_UNICODE_TOUPPER/LOWER
Benjamin Peterson <benjamin@python.org>
parents:
74261
diff
changeset
|
625 return -1; |
|
c2153ce1b5dd
remove some usage of Py_UNICODE_TOUPPER/LOWER
Benjamin Peterson <benjamin@python.org>
parents:
74261
diff
changeset
|
626 } |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
627 PyUnicode_WRITE(kind, data, writer->pos + t, c); |
|
74341
c2153ce1b5dd
remove some usage of Py_UNICODE_TOUPPER/LOWER
Benjamin Peterson <benjamin@python.org>
parents:
74261
diff
changeset
|
628 } |
| 72475 | 629 } |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
630 writer->pos += spec->n_grouped_digits; |
| 72475 | 631 |
| 632 if (spec->n_decimal) { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
633 _PyUnicode_FastCopyCharacters( |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
634 writer->buffer, writer->pos, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
635 locale->decimal_point, 0, spec->n_decimal); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
636 writer->pos += spec->n_decimal; |
| 72475 | 637 d_pos += 1; |
| 638 } | |
| 639 | |
| 640 if (spec->n_remainder) { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
641 _PyUnicode_FastCopyCharacters( |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
642 writer->buffer, writer->pos, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
643 digits, d_pos, spec->n_remainder); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
644 writer->pos += spec->n_remainder; |
|
77781
85e8d2f9b33e
Comment out a dead increment.
Brett Cannon <brett@python.org>
parents:
77530
diff
changeset
|
645 /* d_pos += spec->n_remainder; */ |
| 72475 | 646 } |
| 647 | |
| 648 if (spec->n_rpadding) { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
649 _PyUnicode_FastFill(writer->buffer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
650 writer->pos, spec->n_rpadding, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
651 fill_char); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
652 writer->pos += spec->n_rpadding; |
| 72475 | 653 } |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
654 return 0; |
| 72475 | 655 } |
| 656 | |
| 657 static char no_grouping[1] = {CHAR_MAX}; | |
| 658 | |
| 659 /* Find the decimal point character(s?), thousands_separator(s?), and | |
| 660 grouping description, either for the current locale if type is | |
| 661 LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or | |
| 662 none if LT_NO_LOCALE. */ | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
663 static int |
| 72475 | 664 get_locale_info(int type, LocaleInfo *locale_info) |
| 665 { | |
| 666 switch (type) { | |
| 667 case LT_CURRENT_LOCALE: { | |
| 668 struct lconv *locale_data = localeconv(); | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
669 locale_info->decimal_point = PyUnicode_DecodeLocale( |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
670 locale_data->decimal_point, |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
671 NULL); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
672 if (locale_info->decimal_point == NULL) |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
673 return -1; |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
674 locale_info->thousands_sep = PyUnicode_DecodeLocale( |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
675 locale_data->thousands_sep, |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
676 NULL); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
677 if (locale_info->thousands_sep == NULL) { |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
678 Py_DECREF(locale_info->decimal_point); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
679 return -1; |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
680 } |
| 72475 | 681 locale_info->grouping = locale_data->grouping; |
| 682 break; | |
| 683 } | |
| 684 case LT_DEFAULT_LOCALE: | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
685 locale_info->decimal_point = PyUnicode_FromOrdinal('.'); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
686 locale_info->thousands_sep = PyUnicode_FromOrdinal(','); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
687 if (!locale_info->decimal_point || !locale_info->thousands_sep) { |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
688 Py_XDECREF(locale_info->decimal_point); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
689 Py_XDECREF(locale_info->thousands_sep); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
690 return -1; |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
691 } |
| 72475 | 692 locale_info->grouping = "\3"; /* Group every 3 characters. The |
| 693 (implicit) trailing 0 means repeat | |
| 694 infinitely. */ | |
| 695 break; | |
| 696 case LT_NO_LOCALE: | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
697 locale_info->decimal_point = PyUnicode_FromOrdinal('.'); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
698 locale_info->thousands_sep = PyUnicode_New(0, 0); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
699 if (!locale_info->decimal_point || !locale_info->thousands_sep) { |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
700 Py_XDECREF(locale_info->decimal_point); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
701 Py_XDECREF(locale_info->thousands_sep); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
702 return -1; |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
703 } |
| 72475 | 704 locale_info->grouping = no_grouping; |
| 705 break; | |
| 706 default: | |
| 707 assert(0); | |
| 708 } | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
709 return 0; |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
710 } |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
711 |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
712 static void |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
713 free_locale_info(LocaleInfo *locale_info) |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
714 { |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
715 Py_XDECREF(locale_info->decimal_point); |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
716 Py_XDECREF(locale_info->thousands_sep); |
| 72475 | 717 } |
| 718 | |
| 719 /************************************************************************/ | |
| 720 /*********** string formatting ******************************************/ | |
| 721 /************************************************************************/ | |
| 722 | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
723 static int |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
724 format_string_internal(PyObject *value, const InternalFormatSpec *format, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
725 _PyUnicodeWriter *writer) |
| 72475 | 726 { |
| 727 Py_ssize_t lpad; | |
| 728 Py_ssize_t rpad; | |
| 729 Py_ssize_t total; | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
730 Py_ssize_t len; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
731 int result = -1; |
|
76509
139c3ae84772
Close #14648: Compute correctly maxchar in str.format() for substrin
Victor Stinner <victor.stinner@gmail.com>
parents:
76484
diff
changeset
|
732 Py_UCS4 maxchar; |
| 72475 | 733 |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
734 assert(PyUnicode_IS_READY(value)); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
735 len = PyUnicode_GET_LENGTH(value); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
736 |
| 72475 | 737 /* sign is not allowed on strings */ |
| 738 if (format->sign != '\0') { | |
| 739 PyErr_SetString(PyExc_ValueError, | |
| 740 "Sign not allowed in string format specifier"); | |
| 741 goto done; | |
| 742 } | |
| 743 | |
| 744 /* alternate is not allowed on strings */ | |
| 745 if (format->alternate) { | |
| 746 PyErr_SetString(PyExc_ValueError, | |
| 747 "Alternate form (#) not allowed in string format " | |
| 748 "specifier"); | |
| 749 goto done; | |
| 750 } | |
| 751 | |
| 752 /* '=' alignment not allowed on strings */ | |
| 753 if (format->align == '=') { | |
| 754 PyErr_SetString(PyExc_ValueError, | |
| 755 "'=' alignment not allowed " | |
| 756 "in string format specifier"); | |
| 757 goto done; | |
| 758 } | |
| 759 | |
|
79390
559a430e563c
Issue #15609: Optimize str%args for integer argument
Victor Stinner <victor.stinner@gmail.com>
parents:
78860
diff
changeset
|
760 if ((format->width == -1 || format->width <= len) |
|
559a430e563c
Issue #15609: Optimize str%args for integer argument
Victor Stinner <victor.stinner@gmail.com>
parents:
78860
diff
changeset
|
761 && (format->precision == -1 || format->precision >= len)) { |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
762 /* Fast path */ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
763 return _PyUnicodeWriter_WriteStr(writer, value); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
764 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
765 |
| 72475 | 766 /* if precision is specified, output no more that format.precision |
| 767 characters */ | |
| 768 if (format->precision >= 0 && len >= format->precision) { | |
| 769 len = format->precision; | |
| 770 } | |
| 771 | |
| 772 calc_padding(len, format->width, format->align, &lpad, &rpad, &total); | |
| 773 | |
|
83067
7132bca093ad
Close #16757: Avoid calling the expensive _PyUnicode_FindMaxChar() function
Victor Stinner <victor.stinner@gmail.com>
parents:
82112
diff
changeset
|
774 maxchar = writer->maxchar; |
|
74557
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
775 if (lpad != 0 || rpad != 0) |
|
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
776 maxchar = Py_MAX(maxchar, format->fill_char); |
|
83067
7132bca093ad
Close #16757: Avoid calling the expensive _PyUnicode_FindMaxChar() function
Victor Stinner <victor.stinner@gmail.com>
parents:
82112
diff
changeset
|
777 if (PyUnicode_MAX_CHAR_VALUE(value) > maxchar) { |
|
7132bca093ad
Close #16757: Avoid calling the expensive _PyUnicode_FindMaxChar() function
Victor Stinner <victor.stinner@gmail.com>
parents:
82112
diff
changeset
|
778 Py_UCS4 valmaxchar = _PyUnicode_FindMaxChar(value, 0, len); |
|
7132bca093ad
Close #16757: Avoid calling the expensive _PyUnicode_FindMaxChar() function
Victor Stinner <victor.stinner@gmail.com>
parents:
82112
diff
changeset
|
779 maxchar = Py_MAX(maxchar, valmaxchar); |
|
7132bca093ad
Close #16757: Avoid calling the expensive _PyUnicode_FindMaxChar() function
Victor Stinner <victor.stinner@gmail.com>
parents:
82112
diff
changeset
|
780 } |
|
74557
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
781 |
| 72475 | 782 /* allocate the resulting string */ |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
783 if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1) |
| 72475 | 784 goto done; |
| 785 | |
| 786 /* Write into that space. First the padding. */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
787 result = fill_padding(writer, len, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
788 format->fill_char=='\0'?' ':format->fill_char, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
789 lpad, rpad); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
790 if (result == -1) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
791 goto done; |
| 72475 | 792 |
| 793 /* Then the source string. */ | |
|
77460
00b4451bf94c
Optimize _PyUnicode_FastCopyCharacters() when maxchar(from) > maxchar(to)
Victor Stinner <victor.stinner@gmail.com>
parents:
77223
diff
changeset
|
794 if (len) { |
|
00b4451bf94c
Optimize _PyUnicode_FastCopyCharacters() when maxchar(from) > maxchar(to)
Victor Stinner <victor.stinner@gmail.com>
parents:
77223
diff
changeset
|
795 _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, |
|
00b4451bf94c
Optimize _PyUnicode_FastCopyCharacters() when maxchar(from) > maxchar(to)
Victor Stinner <victor.stinner@gmail.com>
parents:
77223
diff
changeset
|
796 value, 0, len); |
|
00b4451bf94c
Optimize _PyUnicode_FastCopyCharacters() when maxchar(from) > maxchar(to)
Victor Stinner <victor.stinner@gmail.com>
parents:
77223
diff
changeset
|
797 } |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
798 writer->pos += (len + rpad); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
799 result = 0; |
| 72475 | 800 |
| 801 done: | |
| 802 return result; | |
| 803 } | |
| 804 | |
| 805 | |
| 806 /************************************************************************/ | |
| 807 /*********** long formatting ********************************************/ | |
| 808 /************************************************************************/ | |
| 809 | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
810 static int |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
811 format_long_internal(PyObject *value, const InternalFormatSpec *format, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
812 _PyUnicodeWriter *writer) |
| 72475 | 813 { |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
814 int result = -1; |
|
74585
04b565d912c2
Fix compilation warnings (seen on win32 buildbot)
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents:
74557
diff
changeset
|
815 Py_UCS4 maxchar = 127; |
| 72475 | 816 PyObject *tmp = NULL; |
| 817 Py_ssize_t inumeric_chars; | |
| 818 Py_UCS4 sign_char = '\0'; | |
| 819 Py_ssize_t n_digits; /* count of digits need from the computed | |
| 820 string */ | |
| 821 Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which | |
| 822 produces non-digits */ | |
| 823 Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */ | |
| 824 Py_ssize_t n_total; | |
|
74702
056f5cc8885d
Issue #13706: Add assertions to detect bugs earlier
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74586
diff
changeset
|
825 Py_ssize_t prefix = 0; |
| 72475 | 826 NumberFieldWidths spec; |
| 827 long x; | |
| 828 | |
| 829 /* Locale settings, either from the actual locale or | |
| 830 from a hard-code pseudo-locale */ | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
831 LocaleInfo locale = STATIC_LOCALE_INFO_INIT; |
| 72475 | 832 |
| 833 /* no precision allowed on integers */ | |
| 834 if (format->precision != -1) { | |
| 835 PyErr_SetString(PyExc_ValueError, | |
| 836 "Precision not allowed in integer format specifier"); | |
| 837 goto done; | |
| 838 } | |
| 839 | |
| 840 /* special case for character formatting */ | |
| 841 if (format->type == 'c') { | |
| 842 /* error to specify a sign */ | |
| 843 if (format->sign != '\0') { | |
| 844 PyErr_SetString(PyExc_ValueError, | |
| 845 "Sign not allowed with integer" | |
| 846 " format specifier 'c'"); | |
| 847 goto done; | |
| 848 } | |
| 849 | |
| 850 /* taken from unicodeobject.c formatchar() */ | |
| 851 /* Integer input truncated to a character */ | |
| 852 x = PyLong_AsLong(value); | |
| 853 if (x == -1 && PyErr_Occurred()) | |
| 854 goto done; | |
| 855 if (x < 0 || x > 0x10ffff) { | |
| 856 PyErr_SetString(PyExc_OverflowError, | |
|
74557
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
857 "%c arg not in range(0x110000)"); |
| 72475 | 858 goto done; |
| 859 } | |
| 860 tmp = PyUnicode_FromOrdinal(x); | |
| 861 inumeric_chars = 0; | |
| 862 n_digits = 1; | |
|
74586
728cfc671d15
Silence last compilation warning.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents:
74585
diff
changeset
|
863 maxchar = Py_MAX(maxchar, (Py_UCS4)x); |
| 72475 | 864 |
| 865 /* As a sort-of hack, we tell calc_number_widths that we only | |
| 866 have "remainder" characters. calc_number_widths thinks | |
| 867 these are characters that don't get formatted, only copied | |
| 868 into the output string. We do this for 'c' formatting, | |
| 869 because the characters are likely to be non-digits. */ | |
| 870 n_remainder = 1; | |
| 871 } | |
| 872 else { | |
| 873 int base; | |
| 874 int leading_chars_to_skip = 0; /* Number of characters added by | |
| 875 PyNumber_ToBase that we want to | |
| 876 skip over. */ | |
| 877 | |
| 878 /* Compute the base and how many characters will be added by | |
| 879 PyNumber_ToBase */ | |
| 880 switch (format->type) { | |
| 881 case 'b': | |
| 882 base = 2; | |
| 883 leading_chars_to_skip = 2; /* 0b */ | |
| 884 break; | |
| 885 case 'o': | |
| 886 base = 8; | |
| 887 leading_chars_to_skip = 2; /* 0o */ | |
| 888 break; | |
| 889 case 'x': | |
| 890 case 'X': | |
| 891 base = 16; | |
| 892 leading_chars_to_skip = 2; /* 0x */ | |
| 893 break; | |
| 894 default: /* shouldn't be needed, but stops a compiler warning */ | |
| 895 case 'd': | |
| 896 case 'n': | |
| 897 base = 10; | |
| 898 break; | |
| 899 } | |
| 900 | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
901 if (format->sign != '+' && format->sign != ' ' |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
902 && format->width == -1 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
903 && format->type != 'X' && format->type != 'n' |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
904 && !format->thousands_separators |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
905 && PyLong_CheckExact(value)) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
906 { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
907 /* Fast path */ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
908 return _PyLong_FormatWriter(writer, value, base, format->alternate); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
909 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
910 |
| 72475 | 911 /* The number of prefix chars is the same as the leading |
| 912 chars to skip */ | |
| 913 if (format->alternate) | |
| 914 n_prefix = leading_chars_to_skip; | |
| 915 | |
| 916 /* Do the hard part, converting to a string in a given base */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
917 tmp = _PyLong_Format(value, base); |
| 72475 | 918 if (tmp == NULL || PyUnicode_READY(tmp) == -1) |
| 919 goto done; | |
| 920 | |
| 921 inumeric_chars = 0; | |
| 922 n_digits = PyUnicode_GET_LENGTH(tmp); | |
| 923 | |
| 924 prefix = inumeric_chars; | |
| 925 | |
| 926 /* Is a sign character present in the output? If so, remember it | |
| 927 and skip it */ | |
| 928 if (PyUnicode_READ_CHAR(tmp, inumeric_chars) == '-') { | |
| 929 sign_char = '-'; | |
| 930 ++prefix; | |
| 931 ++leading_chars_to_skip; | |
| 932 } | |
| 933 | |
| 934 /* Skip over the leading chars (0x, 0b, etc.) */ | |
| 935 n_digits -= leading_chars_to_skip; | |
| 936 inumeric_chars += leading_chars_to_skip; | |
| 937 } | |
| 938 | |
| 939 /* Determine the grouping, separator, and decimal point, if any. */ | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
940 if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
941 (format->thousands_separators ? |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
942 LT_DEFAULT_LOCALE : |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
943 LT_NO_LOCALE), |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
944 &locale) == -1) |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
945 goto done; |
| 72475 | 946 |
| 947 /* Calculate how much memory we'll need. */ | |
| 948 n_total = calc_number_widths(&spec, n_prefix, sign_char, tmp, inumeric_chars, | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
949 inumeric_chars + n_digits, n_remainder, 0, |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
950 &locale, format, &maxchar); |
|
74557
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
951 |
| 72475 | 952 /* Allocate the memory. */ |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
953 if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1) |
| 72475 | 954 goto done; |
| 955 | |
| 956 /* Populate the memory. */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
957 result = fill_number(writer, &spec, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
958 tmp, inumeric_chars, inumeric_chars + n_digits, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
959 tmp, prefix, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
960 format->fill_char == '\0' ? ' ' : format->fill_char, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
961 &locale, format->type == 'X'); |
| 72475 | 962 |
| 963 done: | |
| 964 Py_XDECREF(tmp); | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
965 free_locale_info(&locale); |
| 72475 | 966 return result; |
| 967 } | |
| 968 | |
| 969 /************************************************************************/ | |
| 970 /*********** float formatting *******************************************/ | |
| 971 /************************************************************************/ | |
| 972 | |
| 973 /* much of this is taken from unicodeobject.c */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
974 static int |
| 72475 | 975 format_float_internal(PyObject *value, |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
976 const InternalFormatSpec *format, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
977 _PyUnicodeWriter *writer) |
| 72475 | 978 { |
| 979 char *buf = NULL; /* buffer returned from PyOS_double_to_string */ | |
| 980 Py_ssize_t n_digits; | |
| 981 Py_ssize_t n_remainder; | |
| 982 Py_ssize_t n_total; | |
| 983 int has_decimal; | |
| 984 double val; | |
|
84326
72087ebf83f0
Issue #9566: Fix a compiler warning on Windows x64
Victor Stinner <victor.stinner@gmail.com>
parents:
84267
diff
changeset
|
985 int precision, default_precision = 6; |
| 72475 | 986 Py_UCS4 type = format->type; |
| 987 int add_pct = 0; | |
| 988 Py_ssize_t index; | |
| 989 NumberFieldWidths spec; | |
| 990 int flags = 0; | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
991 int result = -1; |
|
74585
04b565d912c2
Fix compilation warnings (seen on win32 buildbot)
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents:
74557
diff
changeset
|
992 Py_UCS4 maxchar = 127; |
| 72475 | 993 Py_UCS4 sign_char = '\0'; |
| 994 int float_type; /* Used to see if we have a nan, inf, or regular float. */ | |
| 995 PyObject *unicode_tmp = NULL; | |
| 996 | |
| 997 /* Locale settings, either from the actual locale or | |
| 998 from a hard-code pseudo-locale */ | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
999 LocaleInfo locale = STATIC_LOCALE_INFO_INIT; |
| 72475 | 1000 |
|
84266
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1001 if (format->precision > INT_MAX) { |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1002 PyErr_SetString(PyExc_ValueError, "precision too big"); |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1003 goto done; |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1004 } |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1005 precision = (int)format->precision; |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1006 |
| 72475 | 1007 if (format->alternate) |
| 1008 flags |= Py_DTSF_ALT; | |
| 1009 | |
| 1010 if (type == '\0') { | |
| 1011 /* Omitted type specifier. Behaves in the same way as repr(x) | |
| 1012 and str(x) if no precision is given, else like 'g', but with | |
| 1013 at least one digit after the decimal point. */ | |
| 1014 flags |= Py_DTSF_ADD_DOT_0; | |
| 1015 type = 'r'; | |
| 1016 default_precision = 0; | |
| 1017 } | |
| 1018 | |
| 1019 if (type == 'n') | |
| 1020 /* 'n' is the same as 'g', except for the locale used to | |
| 1021 format the result. We take care of that later. */ | |
| 1022 type = 'g'; | |
| 1023 | |
| 1024 val = PyFloat_AsDouble(value); | |
| 1025 if (val == -1.0 && PyErr_Occurred()) | |
| 1026 goto done; | |
| 1027 | |
| 1028 if (type == '%') { | |
| 1029 type = 'f'; | |
| 1030 val *= 100; | |
| 1031 add_pct = 1; | |
| 1032 } | |
| 1033 | |
| 1034 if (precision < 0) | |
| 1035 precision = default_precision; | |
| 1036 else if (type == 'r') | |
| 1037 type = 'g'; | |
| 1038 | |
| 1039 /* Cast "type", because if we're in unicode we need to pass a | |
| 1040 8-bit char. This is safe, because we've restricted what "type" | |
| 1041 can be. */ | |
| 1042 buf = PyOS_double_to_string(val, (char)type, precision, flags, | |
| 1043 &float_type); | |
| 1044 if (buf == NULL) | |
| 1045 goto done; | |
| 1046 n_digits = strlen(buf); | |
| 1047 | |
| 1048 if (add_pct) { | |
| 1049 /* We know that buf has a trailing zero (since we just called | |
| 1050 strlen() on it), and we don't use that fact any more. So we | |
| 1051 can just write over the trailing zero. */ | |
| 1052 buf[n_digits] = '%'; | |
| 1053 n_digits += 1; | |
| 1054 } | |
| 1055 | |
|
87263
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1056 if (format->sign != '+' && format->sign != ' ' |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1057 && format->width == -1 |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1058 && format->type != 'n' |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1059 && !format->thousands_separators) |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1060 { |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1061 /* Fast path */ |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1062 result = _PyUnicodeWriter_WriteASCIIString(writer, buf, n_digits); |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1063 PyMem_Free(buf); |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1064 return result; |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1065 } |
|
d1ca05428c38
Add _PyUnicodeWriter_WriteASCIIString() function
Victor Stinner <victor.stinner@gmail.com>
parents:
85419
diff
changeset
|
1066 |
| 72475 | 1067 /* Since there is no unicode version of PyOS_double_to_string, |
| 1068 just use the 8 bit version and then convert to unicode. */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1069 unicode_tmp = _PyUnicode_FromASCII(buf, n_digits); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1070 PyMem_Free(buf); |
| 72475 | 1071 if (unicode_tmp == NULL) |
| 1072 goto done; | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1073 |
| 72475 | 1074 /* Is a sign character present in the output? If so, remember it |
| 1075 and skip it */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1076 index = 0; |
| 72475 | 1077 if (PyUnicode_READ_CHAR(unicode_tmp, index) == '-') { |
| 1078 sign_char = '-'; | |
| 1079 ++index; | |
| 1080 --n_digits; | |
| 1081 } | |
| 1082 | |
| 1083 /* Determine if we have any "remainder" (after the digits, might include | |
| 1084 decimal or exponent or both (or neither)) */ | |
| 1085 parse_number(unicode_tmp, index, index + n_digits, &n_remainder, &has_decimal); | |
| 1086 | |
| 1087 /* Determine the grouping, separator, and decimal point, if any. */ | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1088 if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1089 (format->thousands_separators ? |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1090 LT_DEFAULT_LOCALE : |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1091 LT_NO_LOCALE), |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1092 &locale) == -1) |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1093 goto done; |
| 72475 | 1094 |
| 1095 /* Calculate how much memory we'll need. */ | |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
1096 n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index, |
| 72475 | 1097 index + n_digits, n_remainder, has_decimal, |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1098 &locale, format, &maxchar); |
|
74557
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
1099 |
| 72475 | 1100 /* Allocate the memory. */ |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1101 if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1) |
| 72475 | 1102 goto done; |
| 1103 | |
| 1104 /* Populate the memory. */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1105 result = fill_number(writer, &spec, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1106 unicode_tmp, index, index + n_digits, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1107 NULL, 0, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1108 format->fill_char == '\0' ? ' ' : format->fill_char, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1109 &locale, 0); |
| 72475 | 1110 |
| 1111 done: | |
|
78860
dc2909a62262
After the jump in line 1051 unicode_tmp is NULL. Found by Coverity.
Stefan Krah <skrah@bytereef.org>
parents:
78483
diff
changeset
|
1112 Py_XDECREF(unicode_tmp); |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1113 free_locale_info(&locale); |
| 72475 | 1114 return result; |
| 1115 } | |
| 1116 | |
| 1117 /************************************************************************/ | |
| 1118 /*********** complex formatting *****************************************/ | |
| 1119 /************************************************************************/ | |
| 1120 | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1121 static int |
| 72475 | 1122 format_complex_internal(PyObject *value, |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1123 const InternalFormatSpec *format, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1124 _PyUnicodeWriter *writer) |
| 72475 | 1125 { |
| 1126 double re; | |
| 1127 double im; | |
| 1128 char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */ | |
| 1129 char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */ | |
| 1130 | |
| 1131 InternalFormatSpec tmp_format = *format; | |
| 1132 Py_ssize_t n_re_digits; | |
| 1133 Py_ssize_t n_im_digits; | |
| 1134 Py_ssize_t n_re_remainder; | |
| 1135 Py_ssize_t n_im_remainder; | |
| 1136 Py_ssize_t n_re_total; | |
| 1137 Py_ssize_t n_im_total; | |
| 1138 int re_has_decimal; | |
| 1139 int im_has_decimal; | |
|
84326
72087ebf83f0
Issue #9566: Fix a compiler warning on Windows x64
Victor Stinner <victor.stinner@gmail.com>
parents:
84267
diff
changeset
|
1140 int precision, default_precision = 6; |
| 72475 | 1141 Py_UCS4 type = format->type; |
| 1142 Py_ssize_t i_re; | |
| 1143 Py_ssize_t i_im; | |
| 1144 NumberFieldWidths re_spec; | |
| 1145 NumberFieldWidths im_spec; | |
| 1146 int flags = 0; | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1147 int result = -1; |
|
74585
04b565d912c2
Fix compilation warnings (seen on win32 buildbot)
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents:
74557
diff
changeset
|
1148 Py_UCS4 maxchar = 127; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1149 enum PyUnicode_Kind rkind; |
| 72475 | 1150 void *rdata; |
| 1151 Py_UCS4 re_sign_char = '\0'; | |
| 1152 Py_UCS4 im_sign_char = '\0'; | |
| 1153 int re_float_type; /* Used to see if we have a nan, inf, or regular float. */ | |
| 1154 int im_float_type; | |
| 1155 int add_parens = 0; | |
| 1156 int skip_re = 0; | |
| 1157 Py_ssize_t lpad; | |
| 1158 Py_ssize_t rpad; | |
| 1159 Py_ssize_t total; | |
| 1160 PyObject *re_unicode_tmp = NULL; | |
| 1161 PyObject *im_unicode_tmp = NULL; | |
| 1162 | |
| 1163 /* Locale settings, either from the actual locale or | |
| 1164 from a hard-code pseudo-locale */ | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1165 LocaleInfo locale = STATIC_LOCALE_INFO_INIT; |
| 72475 | 1166 |
|
84266
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1167 if (format->precision > INT_MAX) { |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1168 PyErr_SetString(PyExc_ValueError, "precision too big"); |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1169 goto done; |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1170 } |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1171 precision = (int)format->precision; |
|
ef5175d08e7e
Issue #18137: Detect integer overflow on precision in float.__format__() and
Victor Stinner <victor.stinner@gmail.com>
parents:
82111
diff
changeset
|
1172 |
| 72475 | 1173 /* Zero padding is not allowed. */ |
| 1174 if (format->fill_char == '0') { | |
| 1175 PyErr_SetString(PyExc_ValueError, | |
| 1176 "Zero padding is not allowed in complex format " | |
| 1177 "specifier"); | |
| 1178 goto done; | |
| 1179 } | |
| 1180 | |
| 1181 /* Neither is '=' alignment . */ | |
| 1182 if (format->align == '=') { | |
| 1183 PyErr_SetString(PyExc_ValueError, | |
| 1184 "'=' alignment flag is not allowed in complex format " | |
| 1185 "specifier"); | |
| 1186 goto done; | |
| 1187 } | |
| 1188 | |
| 1189 re = PyComplex_RealAsDouble(value); | |
| 1190 if (re == -1.0 && PyErr_Occurred()) | |
| 1191 goto done; | |
| 1192 im = PyComplex_ImagAsDouble(value); | |
| 1193 if (im == -1.0 && PyErr_Occurred()) | |
| 1194 goto done; | |
| 1195 | |
| 1196 if (format->alternate) | |
| 1197 flags |= Py_DTSF_ALT; | |
| 1198 | |
| 1199 if (type == '\0') { | |
| 1200 /* Omitted type specifier. Should be like str(self). */ | |
| 1201 type = 'r'; | |
| 1202 default_precision = 0; | |
| 1203 if (re == 0.0 && copysign(1.0, re) == 1.0) | |
| 1204 skip_re = 1; | |
| 1205 else | |
| 1206 add_parens = 1; | |
| 1207 } | |
| 1208 | |
| 1209 if (type == 'n') | |
| 1210 /* 'n' is the same as 'g', except for the locale used to | |
| 1211 format the result. We take care of that later. */ | |
| 1212 type = 'g'; | |
| 1213 | |
| 1214 if (precision < 0) | |
| 1215 precision = default_precision; | |
| 1216 else if (type == 'r') | |
| 1217 type = 'g'; | |
| 1218 | |
| 1219 /* Cast "type", because if we're in unicode we need to pass a | |
| 1220 8-bit char. This is safe, because we've restricted what "type" | |
| 1221 can be. */ | |
| 1222 re_buf = PyOS_double_to_string(re, (char)type, precision, flags, | |
| 1223 &re_float_type); | |
| 1224 if (re_buf == NULL) | |
| 1225 goto done; | |
| 1226 im_buf = PyOS_double_to_string(im, (char)type, precision, flags, | |
| 1227 &im_float_type); | |
| 1228 if (im_buf == NULL) | |
| 1229 goto done; | |
| 1230 | |
| 1231 n_re_digits = strlen(re_buf); | |
| 1232 n_im_digits = strlen(im_buf); | |
| 1233 | |
| 1234 /* Since there is no unicode version of PyOS_double_to_string, | |
| 1235 just use the 8 bit version and then convert to unicode. */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1236 re_unicode_tmp = _PyUnicode_FromASCII(re_buf, n_re_digits); |
| 72475 | 1237 if (re_unicode_tmp == NULL) |
| 1238 goto done; | |
| 1239 i_re = 0; | |
| 1240 | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1241 im_unicode_tmp = _PyUnicode_FromASCII(im_buf, n_im_digits); |
| 72475 | 1242 if (im_unicode_tmp == NULL) |
| 1243 goto done; | |
| 1244 i_im = 0; | |
| 1245 | |
| 1246 /* Is a sign character present in the output? If so, remember it | |
| 1247 and skip it */ | |
| 1248 if (PyUnicode_READ_CHAR(re_unicode_tmp, i_re) == '-') { | |
| 1249 re_sign_char = '-'; | |
| 1250 ++i_re; | |
| 1251 --n_re_digits; | |
| 1252 } | |
| 1253 if (PyUnicode_READ_CHAR(im_unicode_tmp, i_im) == '-') { | |
| 1254 im_sign_char = '-'; | |
| 1255 ++i_im; | |
| 1256 --n_im_digits; | |
| 1257 } | |
| 1258 | |
| 1259 /* Determine if we have any "remainder" (after the digits, might include | |
| 1260 decimal or exponent or both (or neither)) */ | |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
1261 parse_number(re_unicode_tmp, i_re, i_re + n_re_digits, |
| 72475 | 1262 &n_re_remainder, &re_has_decimal); |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
1263 parse_number(im_unicode_tmp, i_im, i_im + n_im_digits, |
| 72475 | 1264 &n_im_remainder, &im_has_decimal); |
| 1265 | |
| 1266 /* Determine the grouping, separator, and decimal point, if any. */ | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1267 if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1268 (format->thousands_separators ? |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1269 LT_DEFAULT_LOCALE : |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1270 LT_NO_LOCALE), |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1271 &locale) == -1) |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1272 goto done; |
| 72475 | 1273 |
| 1274 /* Turn off any padding. We'll do it later after we've composed | |
| 1275 the numbers without padding. */ | |
| 1276 tmp_format.fill_char = '\0'; | |
| 1277 tmp_format.align = '<'; | |
| 1278 tmp_format.width = -1; | |
| 1279 | |
| 1280 /* Calculate how much memory we'll need. */ | |
| 1281 n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, re_unicode_tmp, | |
| 1282 i_re, i_re + n_re_digits, n_re_remainder, | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1283 re_has_decimal, &locale, &tmp_format, |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1284 &maxchar); |
| 72475 | 1285 |
| 1286 /* Same formatting, but always include a sign, unless the real part is | |
| 1287 * going to be omitted, in which case we use whatever sign convention was | |
| 1288 * requested by the original format. */ | |
| 1289 if (!skip_re) | |
| 1290 tmp_format.sign = '+'; | |
| 1291 n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, im_unicode_tmp, | |
| 1292 i_im, i_im + n_im_digits, n_im_remainder, | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1293 im_has_decimal, &locale, &tmp_format, |
|
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1294 &maxchar); |
| 72475 | 1295 |
| 1296 if (skip_re) | |
| 1297 n_re_total = 0; | |
| 1298 | |
| 1299 /* Add 1 for the 'j', and optionally 2 for parens. */ | |
| 1300 calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, | |
| 1301 format->width, format->align, &lpad, &rpad, &total); | |
| 1302 | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1303 if (lpad || rpad) |
|
74557
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
1304 maxchar = Py_MAX(maxchar, format->fill_char); |
|
231c6042c40c
Issue #13706: Support non-ASCII fill characters
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74533
diff
changeset
|
1305 |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1306 if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1) |
| 72475 | 1307 goto done; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1308 rkind = writer->kind; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1309 rdata = writer->data; |
| 72475 | 1310 |
| 1311 /* Populate the memory. First, the padding. */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1312 result = fill_padding(writer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1313 n_re_total + n_im_total + 1 + add_parens * 2, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1314 format->fill_char=='\0' ? ' ' : format->fill_char, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1315 lpad, rpad); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1316 if (result == -1) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1317 goto done; |
| 72475 | 1318 |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1319 if (add_parens) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1320 PyUnicode_WRITE(rkind, rdata, writer->pos, '('); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1321 writer->pos++; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1322 } |
| 72475 | 1323 |
| 1324 if (!skip_re) { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1325 result = fill_number(writer, &re_spec, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1326 re_unicode_tmp, i_re, i_re + n_re_digits, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1327 NULL, 0, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1328 0, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1329 &locale, 0); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1330 if (result == -1) |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
1331 goto done; |
| 72475 | 1332 } |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1333 result = fill_number(writer, &im_spec, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1334 im_unicode_tmp, i_im, i_im + n_im_digits, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1335 NULL, 0, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1336 0, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1337 &locale, 0); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1338 if (result == -1) |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
1339 goto done; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1340 PyUnicode_WRITE(rkind, rdata, writer->pos, 'j'); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1341 writer->pos++; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1342 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1343 if (add_parens) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1344 PyUnicode_WRITE(rkind, rdata, writer->pos, ')'); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1345 writer->pos++; |
|
72495
cf3557b65ae1
fill_char() can now propagate an error
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
1346 } |
| 72475 | 1347 |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1348 writer->pos += rpad; |
| 72475 | 1349 |
| 1350 done: | |
| 1351 PyMem_Free(re_buf); | |
| 1352 PyMem_Free(im_buf); | |
| 1353 Py_XDECREF(re_unicode_tmp); | |
| 1354 Py_XDECREF(im_unicode_tmp); | |
|
75231
f89e2f4cda88
Issue #13706: Fix format(int, "n") for locale with non-ASCII thousands separator
Victor Stinner <victor.stinner@haypocalc.com>
parents:
74702
diff
changeset
|
1355 free_locale_info(&locale); |
| 72475 | 1356 return result; |
| 1357 } | |
| 1358 | |
| 1359 /************************************************************************/ | |
| 1360 /*********** built in formatters ****************************************/ | |
| 1361 /************************************************************************/ | |
| 77530 | 1362 static int |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1363 format_obj(PyObject *obj, _PyUnicodeWriter *writer) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1364 { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1365 PyObject *str; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1366 int err; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1367 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1368 str = PyObject_Str(obj); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1369 if (str == NULL) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1370 return -1; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1371 err = _PyUnicodeWriter_WriteStr(writer, str); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1372 Py_DECREF(str); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1373 return err; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1374 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1375 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1376 int |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1377 _PyUnicode_FormatAdvancedWriter(_PyUnicodeWriter *writer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1378 PyObject *obj, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1379 PyObject *format_spec, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1380 Py_ssize_t start, Py_ssize_t end) |
| 72475 | 1381 { |
| 1382 InternalFormatSpec format; | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1383 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1384 assert(PyUnicode_Check(obj)); |
| 72475 | 1385 |
| 1386 /* check for the special case of zero length format spec, make | |
| 1387 it equivalent to str(obj) */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1388 if (start == end) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1389 if (PyUnicode_CheckExact(obj)) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1390 return _PyUnicodeWriter_WriteStr(writer, obj); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1391 else |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1392 return format_obj(obj, writer); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1393 } |
| 72475 | 1394 |
| 1395 /* parse the format_spec */ | |
| 1396 if (!parse_internal_render_format_spec(format_spec, start, end, | |
| 1397 &format, 's', '<')) | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1398 return -1; |
| 72475 | 1399 |
| 1400 /* type conversion? */ | |
| 1401 switch (format.type) { | |
| 1402 case 's': | |
| 1403 /* no type conversion needed, already a string. do the formatting */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1404 return format_string_internal(obj, &format, writer); |
| 72475 | 1405 default: |
| 1406 /* unknown */ | |
| 1407 unknown_presentation_type(format.type, obj->ob_type->tp_name); | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1408 return -1; |
| 72475 | 1409 } |
| 1410 } | |
| 1411 | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1412 int |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1413 _PyLong_FormatAdvancedWriter(_PyUnicodeWriter *writer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1414 PyObject *obj, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1415 PyObject *format_spec, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1416 Py_ssize_t start, Py_ssize_t end) |
| 72475 | 1417 { |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1418 PyObject *tmp = NULL, *str = NULL; |
| 72475 | 1419 InternalFormatSpec format; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1420 int result = -1; |
| 72475 | 1421 |
| 1422 /* check for the special case of zero length format spec, make | |
| 1423 it equivalent to str(obj) */ | |
| 1424 if (start == end) { | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1425 if (PyLong_CheckExact(obj)) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1426 return _PyLong_FormatWriter(writer, obj, 10, 0); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1427 else |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1428 return format_obj(obj, writer); |
| 72475 | 1429 } |
| 1430 | |
| 1431 /* parse the format_spec */ | |
| 1432 if (!parse_internal_render_format_spec(format_spec, start, end, | |
| 1433 &format, 'd', '>')) | |
| 1434 goto done; | |
| 1435 | |
| 1436 /* type conversion? */ | |
| 1437 switch (format.type) { | |
| 1438 case 'b': | |
| 1439 case 'c': | |
| 1440 case 'd': | |
| 1441 case 'o': | |
| 1442 case 'x': | |
| 1443 case 'X': | |
| 1444 case 'n': | |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84266
diff
changeset
|
1445 /* no type conversion needed, already an int. do the formatting */ |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1446 result = format_long_internal(obj, &format, writer); |
| 72475 | 1447 break; |
| 1448 | |
| 1449 case 'e': | |
| 1450 case 'E': | |
| 1451 case 'f': | |
| 1452 case 'F': | |
| 1453 case 'g': | |
| 1454 case 'G': | |
| 1455 case '%': | |
| 1456 /* convert to float */ | |
| 1457 tmp = PyNumber_Float(obj); | |
| 1458 if (tmp == NULL) | |
| 1459 goto done; | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1460 result = format_float_internal(tmp, &format, writer); |
| 72475 | 1461 break; |
| 1462 | |
| 1463 default: | |
| 1464 /* unknown */ | |
| 1465 unknown_presentation_type(format.type, obj->ob_type->tp_name); | |
| 1466 goto done; | |
| 1467 } | |
| 1468 | |
| 1469 done: | |
| 1470 Py_XDECREF(tmp); | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1471 Py_XDECREF(str); |
| 72475 | 1472 return result; |
| 1473 } | |
| 1474 | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1475 int |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1476 _PyFloat_FormatAdvancedWriter(_PyUnicodeWriter *writer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1477 PyObject *obj, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1478 PyObject *format_spec, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1479 Py_ssize_t start, Py_ssize_t end) |
| 72475 | 1480 { |
| 1481 InternalFormatSpec format; | |
| 1482 | |
| 1483 /* check for the special case of zero length format spec, make | |
| 1484 it equivalent to str(obj) */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1485 if (start == end) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1486 return format_obj(obj, writer); |
| 72475 | 1487 |
| 1488 /* parse the format_spec */ | |
| 1489 if (!parse_internal_render_format_spec(format_spec, start, end, | |
| 1490 &format, '\0', '>')) | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1491 return -1; |
| 72475 | 1492 |
| 1493 /* type conversion? */ | |
| 1494 switch (format.type) { | |
| 1495 case '\0': /* No format code: like 'g', but with at least one decimal. */ | |
| 1496 case 'e': | |
| 1497 case 'E': | |
| 1498 case 'f': | |
| 1499 case 'F': | |
| 1500 case 'g': | |
| 1501 case 'G': | |
| 1502 case 'n': | |
| 1503 case '%': | |
| 1504 /* no conversion, already a float. do the formatting */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1505 return format_float_internal(obj, &format, writer); |
| 72475 | 1506 |
| 1507 default: | |
| 1508 /* unknown */ | |
| 1509 unknown_presentation_type(format.type, obj->ob_type->tp_name); | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1510 return -1; |
| 72475 | 1511 } |
| 1512 } | |
| 1513 | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1514 int |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1515 _PyComplex_FormatAdvancedWriter(_PyUnicodeWriter *writer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1516 PyObject *obj, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1517 PyObject *format_spec, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1518 Py_ssize_t start, Py_ssize_t end) |
| 72475 | 1519 { |
| 1520 InternalFormatSpec format; | |
| 1521 | |
| 1522 /* check for the special case of zero length format spec, make | |
| 1523 it equivalent to str(obj) */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1524 if (start == end) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1525 return format_obj(obj, writer); |
| 72475 | 1526 |
| 1527 /* parse the format_spec */ | |
| 1528 if (!parse_internal_render_format_spec(format_spec, start, end, | |
| 1529 &format, '\0', '>')) | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1530 return -1; |
| 72475 | 1531 |
| 1532 /* type conversion? */ | |
| 1533 switch (format.type) { | |
| 1534 case '\0': /* No format code: like 'g', but with at least one decimal. */ | |
| 1535 case 'e': | |
| 1536 case 'E': | |
| 1537 case 'f': | |
| 1538 case 'F': | |
| 1539 case 'g': | |
| 1540 case 'G': | |
| 1541 case 'n': | |
| 1542 /* no conversion, already a complex. do the formatting */ | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1543 return format_complex_internal(obj, &format, writer); |
| 72475 | 1544 |
| 1545 default: | |
| 1546 /* unknown */ | |
| 1547 unknown_presentation_type(format.type, obj->ob_type->tp_name); | |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76509
diff
changeset
|
1548 return -1; |
| 72475 | 1549 } |
| 1550 } |
