From 903fc0596297f9326c754008e20ec81fe6c2a786 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 22 Feb 2010 19:26:06 +0000 Subject: [PATCH] Merged revisions 78333 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ................ r78333 | eric.smith | 2010-02-22 13:54:44 -0500 (Mon, 22 Feb 2010) | 9 lines Merged revisions 78329 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78329 | eric.smith | 2010-02-22 13:33:47 -0500 (Mon, 22 Feb 2010) | 1 line Issue #7988: Fix default alignment to be right aligned for complex.__format__. Now it matches other numeric types. ........ ................ --- Lib/test/test_complex.py | 2 ++ Misc/NEWS | 3 ++ Objects/stringlib/formatter.h | 52 +++++++++++++++++++++++++++-------- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index faa7e1f6be5..a84e9495bbd 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -491,6 +491,8 @@ class ComplexTest(unittest.TestCase): self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ') self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ') + self.assertEqual(format(1.5+3j, '20.2f'), ' 1.50+3.00j') + self.assertEqual(format(1.5+3j, '>20.2f'), ' 1.50+3.00j') self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ') self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j') self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j') diff --git a/Misc/NEWS b/Misc/NEWS index 5bd32fb277d..0a997733ad9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 3.1.2? Core and Builtins ----------------- +- Issue #7988: Fix default alignment to be right aligned for + complex.__format__. Now it matches other numeric types. + - Issue #7385: Fix a crash in `MemoryView_FromObject` when `PyObject_GetBuffer` fails. Patch by Florent Xicluna. diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index 5cead660c4e..df07b11e13f 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -123,6 +123,26 @@ typedef struct { STRINGLIB_CHAR type; } InternalFormatSpec; + +#if 0 +/* Occassionally useful for debugging. Should normally be commented out. */ +static void +DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format) +{ + printf("internal format spec: fill_char %d\n", format->fill_char); + printf("internal format spec: align %d\n", format->align); + printf("internal format spec: alternate %d\n", format->alternate); + printf("internal format spec: sign %d\n", format->sign); + printf("internal format spec: width %d\n", format->width); + printf("internal format spec: thousands_separators %d\n", + format->thousands_separators); + printf("internal format spec: precision %d\n", format->precision); + printf("internal format spec: type %c\n", format->type); + printf("\n"); +} +#endif + + /* ptr points to the start of the format_spec, end points just past its end. fills in format with the parsed information. @@ -133,7 +153,8 @@ static int parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, Py_ssize_t format_spec_len, InternalFormatSpec *format, - char default_type) + char default_type, + char default_align) { STRINGLIB_CHAR *ptr = format_spec; STRINGLIB_CHAR *end = format_spec + format_spec_len; @@ -144,7 +165,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, Py_ssize_t consumed; format->fill_char = '\0'; - format->align = '\0'; + format->align = default_align; format->alternate = 0; format->sign = '\0'; format->width = -1; @@ -279,14 +300,19 @@ calc_padding(Py_ssize_t nchars, Py_ssize_t width, STRINGLIB_CHAR align, *n_total = nchars; } - /* figure out how much leading space we need, based on the + /* Figure out how much leading space we need, based on the aligning */ if (align == '>') *n_lpadding = *n_total - nchars; else if (align == '^') *n_lpadding = (*n_total - nchars) / 2; - else + else if (align == '<' || align == '=') *n_lpadding = 0; + else { + /* We should never have an unspecified alignment. */ + *n_lpadding = 0; + assert(0); + } *n_rpadding = *n_total - nchars - *n_lpadding; } @@ -488,10 +514,14 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, case '=': spec->n_spadding = n_padding; break; - default: - /* Handles '>', plus catch-all just in case. */ + case '>': spec->n_lpadding = n_padding; break; + default: + /* Shouldn't get here, but treat it as '>' */ + spec->n_lpadding = n_padding; + assert(0); + break; } } return spec->n_lpadding + spec->n_sign + spec->n_prefix + @@ -1193,7 +1223,7 @@ format_complex_internal(PyObject *value, /* Turn off any padding. We'll do it later after we've composed the numbers without padding. */ tmp_format.fill_char = '\0'; - tmp_format.align = '\0'; + tmp_format.align = '<'; tmp_format.width = -1; /* Calculate how much memory we'll need. */ @@ -1269,7 +1299,7 @@ FORMAT_STRING(PyObject *obj, /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, 's')) + &format, 's', '<')) goto done; /* type conversion? */ @@ -1309,7 +1339,7 @@ format_int_or_long(PyObject* obj, /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, 'd')) + &format, 'd', '>')) goto done; /* type conversion? */ @@ -1420,7 +1450,7 @@ FORMAT_FLOAT(PyObject *obj, /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, '\0')) + &format, '\0', '>')) goto done; /* type conversion? */ @@ -1468,7 +1498,7 @@ FORMAT_COMPLEX(PyObject *obj, /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, '\0')) + &format, '\0', '>')) goto done; /* type conversion? */