diff options
author | Eric Smith <eric@trueblade.com> | 2008-06-24 11:11:59 (GMT) |
---|---|---|
committer | Eric Smith <eric@trueblade.com> | 2008-06-24 11:11:59 (GMT) |
commit | 5dce7e9a83346ca24270587f7bedd59940cd948f (patch) | |
tree | 17a5a138cd17316701fa60042f69056e79b346cd | |
parent | c72b7879928156fe260e8d1511b047d0ec244f03 (diff) | |
download | cpython-5dce7e9a83346ca24270587f7bedd59940cd948f.zip cpython-5dce7e9a83346ca24270587f7bedd59940cd948f.tar.gz cpython-5dce7e9a83346ca24270587f7bedd59940cd948f.tar.bz2 |
Fixed formatting with thousands separator and padding. Resolves issue 3140.
-rw-r--r-- | Lib/test/test_types.py | 8 | ||||
-rw-r--r-- | Objects/stringlib/formatter.h | 26 |
2 files changed, 21 insertions, 13 deletions
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index aca5ff2..a10f2a6 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -497,6 +497,14 @@ class TypesTests(unittest.TestCase): # move to the next integer to test x = x // 10 + rfmt = ">20n" + lfmt = "<20n" + cfmt = "^20n" + for x in (1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890, 12345678900): + self.assertEqual(len(format(0, rfmt)), len(format(x, rfmt))) + self.assertEqual(len(format(0, lfmt)), len(format(x, lfmt))) + self.assertEqual(len(format(0, cfmt)), len(format(x, cfmt))) + def test_float__format__(self): # these should be rewritten to use both format(x, spec) and # x.__format__(spec) diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index f8f265c..018121a 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -313,8 +313,8 @@ calc_number_widths(NumberFieldWidths *r, STRINGLIB_CHAR actual_sign, as determined in _calc_integer_widths(). returns the pointer to where the digits go. */ static STRINGLIB_CHAR * -fill_number(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec, - Py_ssize_t n_digits, STRINGLIB_CHAR fill_char) +fill_non_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec, + Py_ssize_t n_digits, STRINGLIB_CHAR fill_char) { STRINGLIB_CHAR* p_digits; @@ -557,17 +557,17 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, pnumeric_chars += leading_chars_to_skip; } - /* Calculate the widths of the various leading and trailing parts */ - calc_number_widths(&spec, sign, n_digits, format); - if (format->type == 'n') /* Compute how many additional chars we need to allocate to hold the thousands grouping. */ STRINGLIB_GROUPING(NULL, n_digits, n_digits, 0, &n_grouping_chars, 0); + /* Calculate the widths of the various leading and trailing parts */ + calc_number_widths(&spec, sign, n_digits + n_grouping_chars, format); + /* Allocate a new string to hold the result */ - result = STRINGLIB_NEW(NULL, spec.n_total + n_grouping_chars); + result = STRINGLIB_NEW(NULL, spec.n_total); if (!result) goto done; p = STRINGLIB_STR(result); @@ -587,7 +587,7 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, /* Insert the grouping, if any, after the uppercasing of 'X', so we can ensure that grouping chars won't be affected. */ - if (n_grouping_chars && format->type == 'n') { + if (n_grouping_chars) { /* We know this can't fail, since we've already reserved enough space. */ STRINGLIB_CHAR *pstart = p + n_leading_chars; @@ -597,9 +597,9 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, assert(r); } - /* Fill in the non-digit parts */ - fill_number(p, &spec, n_digits, - format->fill_char == '\0' ? ' ' : format->fill_char); + /* Fill in the non-digit parts (padding, sign, etc.) */ + fill_non_digits(p, &spec, n_digits + n_grouping_chars, + format->fill_char == '\0' ? ' ' : format->fill_char); done: Py_XDECREF(tmp); @@ -737,9 +737,9 @@ format_float_internal(PyObject *value, if (result == NULL) goto done; - /* fill in the non-digit parts */ - fill_number(STRINGLIB_STR(result), &spec, n_digits, - format->fill_char == '\0' ? ' ' : format->fill_char); + /* Fill in the non-digit parts (padding, sign, etc.) */ + fill_non_digits(STRINGLIB_STR(result), &spec, n_digits, + format->fill_char == '\0' ? ' ' : format->fill_char); /* fill in the digit parts */ memmove(STRINGLIB_STR(result) + |