From 9b7dd8a6114201295c5dce3a6cd3d48550a88056 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 2 Oct 2012 00:33:47 +0200 Subject: Issue #15609: Optimize str%args for integer argument - Use _PyLong_FormatWriter() instead of formatlong() when possible, to avoid a temporary buffer - Enable the fast path when width is smaller or equals to the length, and when the precision is bigger or equals to the length - Add unit tests! - formatlong() uses PyUnicode_Resize() instead of _PyUnicode_FromASCII() to resize the output string --- Python/formatter_unicode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/formatter_unicode.c') diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index aa62502dbe..0ce9862a20 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -757,7 +757,8 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format, goto done; } - if (format->width == -1 && format->precision == -1) { + if ((format->width == -1 || format->width <= len) + && (format->precision == -1 || format->precision >= len)) { /* Fast path */ return _PyUnicodeWriter_WriteStr(writer, value); } -- cgit v1.2.1 From 4a7596083685d526076d006536188229dd1545d1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 3 Apr 2013 02:02:33 +0200 Subject: Close #16757: Avoid calling the expensive _PyUnicode_FindMaxChar() function when possible --- Python/formatter_unicode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Python/formatter_unicode.c') diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 79fa469697..009bc5fd03 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -771,9 +771,13 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format, calc_padding(len, format->width, format->align, &lpad, &rpad, &total); - maxchar = _PyUnicode_FindMaxChar(value, 0, len); + maxchar = writer->maxchar; if (lpad != 0 || rpad != 0) maxchar = Py_MAX(maxchar, format->fill_char); + if (PyUnicode_MAX_CHAR_VALUE(value) > maxchar) { + Py_UCS4 valmaxchar = _PyUnicode_FindMaxChar(value, 0, len); + maxchar = Py_MAX(maxchar, valmaxchar); + } /* allocate the resulting string */ if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1) -- cgit v1.2.1 From 157b5b3790c1d53767468c915a12abdfcde059e3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 7 May 2013 23:50:03 +0200 Subject: Fix a compiler warning: use unsigned int type instead of enum PyUnicode_Kind to compare two Unicode kinds --- Python/formatter_unicode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/formatter_unicode.c') diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 009bc5fd03..548b49aa3e 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -556,7 +556,7 @@ fill_number(_PyUnicodeWriter *writer, const NumberFieldWidths *spec, { /* Used to keep track of digits, decimal, and remainder. */ Py_ssize_t d_pos = d_start; - const enum PyUnicode_Kind kind = writer->kind; + const unsigned int kind = writer->kind; const void *data = writer->data; Py_ssize_t r; -- cgit v1.2.1 From b603792a7d419f727c2e33663f26e3647304ac6f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 17 May 2013 00:04:56 +0200 Subject: Fix a compilater warning on Windows 64-bit --- Python/formatter_unicode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/formatter_unicode.c') diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 548b49aa3e..bb173d9bd4 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -315,7 +315,7 @@ calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align, /* Do the padding, and return a pointer to where the caller-supplied content goes. */ -static Py_ssize_t +static int fill_padding(_PyUnicodeWriter *writer, Py_ssize_t nchars, Py_UCS4 fill_char, Py_ssize_t n_lpadding, -- cgit v1.2.1 From 90358d6a3b216981ab8ef00e6531de4dad309d8a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 24 Jun 2013 23:34:15 +0200 Subject: Issue #9566: Fix a compiler warning on Windows x64 --- Python/formatter_unicode.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Python/formatter_unicode.c') diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index aac85b3392..9b5aff59ee 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -982,8 +982,7 @@ format_float_internal(PyObject *value, Py_ssize_t n_total; int has_decimal; double val; - Py_ssize_t precision; - Py_ssize_t default_precision = 6; + int precision, default_precision = 6; Py_UCS4 type = format->type; int add_pct = 0; Py_ssize_t index; @@ -1138,8 +1137,7 @@ format_complex_internal(PyObject *value, Py_ssize_t n_im_total; int re_has_decimal; int im_has_decimal; - int precision; - Py_ssize_t default_precision = 6; + int precision, default_precision = 6; Py_UCS4 type = format->type; Py_ssize_t i_re; Py_ssize_t i_im; -- cgit v1.2.1 From 4d014c8f2ccc06eb04f9963df910d9d2357fc096 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 19 Nov 2013 12:54:53 +0100 Subject: Add _PyUnicodeWriter_WriteASCIIString() function --- Python/formatter_unicode.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Python/formatter_unicode.c') diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index e68087fd5a..0a3cc593d6 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -1053,24 +1053,24 @@ format_float_internal(PyObject *value, n_digits += 1; } - /* Since there is no unicode version of PyOS_double_to_string, - just use the 8 bit version and then convert to unicode. */ - unicode_tmp = _PyUnicode_FromASCII(buf, n_digits); - PyMem_Free(buf); - if (unicode_tmp == NULL) - goto done; - if (format->sign != '+' && format->sign != ' ' && format->width == -1 && format->type != 'n' && !format->thousands_separators) { /* Fast path */ - result = _PyUnicodeWriter_WriteStr(writer, unicode_tmp); - Py_DECREF(unicode_tmp); + result = _PyUnicodeWriter_WriteASCIIString(writer, buf, n_digits); + PyMem_Free(buf); return result; } + /* Since there is no unicode version of PyOS_double_to_string, + just use the 8 bit version and then convert to unicode. */ + unicode_tmp = _PyUnicode_FromASCII(buf, n_digits); + PyMem_Free(buf); + if (unicode_tmp == NULL) + goto done; + /* Is a sign character present in the output? If so, remember it and skip it */ index = 0; -- cgit v1.2.1 From 83881efa0f330099287633847c9547afa05f1a6b Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Mon, 14 Apr 2014 11:55:10 -0400 Subject: Issue #12546: Allow \x00 as a fill character for builtin type __format__ methods. --- Python/formatter_unicode.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'Python/formatter_unicode.c') diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 0a3cc593d6..e3a8149841 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -156,8 +156,9 @@ parse_internal_render_format_spec(PyObject *format_spec, Py_ssize_t consumed; int align_specified = 0; + int fill_char_specified = 0; - format->fill_char = '\0'; + format->fill_char = ' '; format->align = default_align; format->alternate = 0; format->sign = '\0'; @@ -171,6 +172,7 @@ parse_internal_render_format_spec(PyObject *format_spec, if (end-pos >= 2 && is_alignment_token(READ_spec(pos+1))) { format->align = READ_spec(pos+1); format->fill_char = READ_spec(pos); + fill_char_specified = 1; align_specified = 1; pos += 2; } @@ -194,7 +196,7 @@ parse_internal_render_format_spec(PyObject *format_spec, } /* The special case for 0-padding (backwards compat) */ - if (format->fill_char == '\0' && end-pos >= 1 && READ_spec(pos) == '0') { + if (!fill_char_specified && end-pos >= 1 && READ_spec(pos) == '0') { format->fill_char = '0'; if (!align_specified) { format->align = '='; @@ -784,9 +786,7 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format, goto done; /* Write into that space. First the padding. */ - result = fill_padding(writer, len, - format->fill_char=='\0'?' ':format->fill_char, - lpad, rpad); + result = fill_padding(writer, len, format->fill_char, lpad, rpad); if (result == -1) goto done; @@ -956,8 +956,7 @@ format_long_internal(PyObject *value, const InternalFormatSpec *format, /* Populate the memory. */ result = fill_number(writer, &spec, tmp, inumeric_chars, inumeric_chars + n_digits, - tmp, prefix, - format->fill_char == '\0' ? ' ' : format->fill_char, + tmp, prefix, format->fill_char, &locale, format->type == 'X'); done: @@ -1104,8 +1103,7 @@ format_float_internal(PyObject *value, /* Populate the memory. */ result = fill_number(writer, &spec, unicode_tmp, index, index + n_digits, - NULL, 0, - format->fill_char == '\0' ? ' ' : format->fill_char, + NULL, 0, format->fill_char, &locale, 0); done: @@ -1311,8 +1309,7 @@ format_complex_internal(PyObject *value, /* Populate the memory. First, the padding. */ result = fill_padding(writer, n_re_total + n_im_total + 1 + add_parens * 2, - format->fill_char=='\0' ? ' ' : format->fill_char, - lpad, rpad); + format->fill_char, lpad, rpad); if (result == -1) goto done; -- cgit v1.2.1 From 10bf64ae21980e08eb3845e5afed33876ebd71d7 Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Tue, 15 Apr 2014 03:05:02 -0400 Subject: Closed issue #8931: Make alternate formatting for 'c' raise an exception. Patch by Torsten Landschoff. --- Python/formatter_unicode.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Python/formatter_unicode.c') diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index e3a8149841..056bb76902 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -846,6 +846,13 @@ format_long_internal(PyObject *value, const InternalFormatSpec *format, " format specifier 'c'"); goto done; } + /* error to request alternate format */ + if (format->alternate) { + PyErr_SetString(PyExc_ValueError, + "Alternate form (#) not allowed with integer" + " format specifier 'c'"); + goto done; + } /* taken from unicodeobject.c formatchar() */ /* Integer input truncated to a character */ -- cgit v1.2.1 From f004a07cfcd9b73d8770804bd8600ffc79e0163d Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Tue, 15 Apr 2014 13:52:21 +0100 Subject: Reverted 16efa8d27e4c after discussion with Eric. --- Python/formatter_unicode.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'Python/formatter_unicode.c') diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 056bb76902..e3a8149841 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -846,13 +846,6 @@ format_long_internal(PyObject *value, const InternalFormatSpec *format, " format specifier 'c'"); goto done; } - /* error to request alternate format */ - if (format->alternate) { - PyErr_SetString(PyExc_ValueError, - "Alternate form (#) not allowed with integer" - " format specifier 'c'"); - goto done; - } /* taken from unicodeobject.c formatchar() */ /* Integer input truncated to a character */ -- cgit v1.2.1