Skip to content

Commit f32d4ac

Browse files
committed
Issue #7988: Fix default alignment to be right aligned for complex.__format__. Now it matches other numeric types.
1 parent 8f48f4c commit f32d4ac

File tree

3 files changed

+45
-10
lines changed

3 files changed

+45
-10
lines changed

Lib/test/test_complex.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,8 @@ def test_format(self):
568568
self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ')
569569
self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ')
570570

571+
self.assertEqual(format(1.5+3j, '20.2f'), ' 1.50+3.00j')
572+
self.assertEqual(format(1.5+3j, '>20.2f'), ' 1.50+3.00j')
571573
self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ')
572574
self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j')
573575
self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j')

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 4?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #7988: Fix default alignment to be right aligned for
16+
complex.__format__. Now it matches other numeric types.
17+
1518
- Issue #5211: the complex type no longer uses implicit coercion in
1619
mixed-type binary arithmetic operations.
1720

Objects/stringlib/formatter.h

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,26 @@ typedef struct {
141141
STRINGLIB_CHAR type;
142142
} InternalFormatSpec;
143143

144+
145+
#if 0
146+
/* Occassionally useful for debugging. Should normally be commented out. */
147+
static void
148+
DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format)
149+
{
150+
printf("internal format spec: fill_char %d\n", format->fill_char);
151+
printf("internal format spec: align %d\n", format->align);
152+
printf("internal format spec: alternate %d\n", format->alternate);
153+
printf("internal format spec: sign %d\n", format->sign);
154+
printf("internal format spec: width %d\n", format->width);
155+
printf("internal format spec: thousands_separators %d\n",
156+
format->thousands_separators);
157+
printf("internal format spec: precision %d\n", format->precision);
158+
printf("internal format spec: type %c\n", format->type);
159+
printf("\n");
160+
}
161+
#endif
162+
163+
144164
/*
145165
ptr points to the start of the format_spec, end points just past its end.
146166
fills in format with the parsed information.
@@ -151,7 +171,8 @@ static int
151171
parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
152172
Py_ssize_t format_spec_len,
153173
InternalFormatSpec *format,
154-
char default_type)
174+
char default_type,
175+
char default_align)
155176
{
156177
STRINGLIB_CHAR *ptr = format_spec;
157178
STRINGLIB_CHAR *end = format_spec + format_spec_len;
@@ -162,7 +183,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
162183
Py_ssize_t consumed;
163184

164185
format->fill_char = '\0';
165-
format->align = '\0';
186+
format->align = default_align;
166187
format->alternate = 0;
167188
format->sign = '\0';
168189
format->width = -1;
@@ -296,14 +317,19 @@ calc_padding(Py_ssize_t nchars, Py_ssize_t width, STRINGLIB_CHAR align,
296317
*n_total = nchars;
297318
}
298319

299-
/* figure out how much leading space we need, based on the
320+
/* Figure out how much leading space we need, based on the
300321
aligning */
301322
if (align == '>')
302323
*n_lpadding = *n_total - nchars;
303324
else if (align == '^')
304325
*n_lpadding = (*n_total - nchars) / 2;
305-
else
326+
else if (align == '<' || align == '=')
327+
*n_lpadding = 0;
328+
else {
329+
/* We should never have an unspecified alignment. */
306330
*n_lpadding = 0;
331+
assert(0);
332+
}
307333

308334
*n_rpadding = *n_total - nchars - *n_lpadding;
309335
}
@@ -505,9 +531,13 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
505531
case '=':
506532
spec->n_spadding = n_padding;
507533
break;
534+
case '>':
535+
spec->n_lpadding = n_padding;
536+
break;
508537
default:
509-
/* Handles '>', plus catch-all just in case. */
538+
/* Shouldn't get here, but treat it as '>' */
510539
spec->n_lpadding = n_padding;
540+
assert(0);
511541
break;
512542
}
513543
}
@@ -1190,7 +1220,7 @@ format_complex_internal(PyObject *value,
11901220
/* Turn off any padding. We'll do it later after we've composed
11911221
the numbers without padding. */
11921222
tmp_format.fill_char = '\0';
1193-
tmp_format.align = '\0';
1223+
tmp_format.align = '<';
11941224
tmp_format.width = -1;
11951225

11961226
/* Calculate how much memory we'll need. */
@@ -1266,7 +1296,7 @@ FORMAT_STRING(PyObject *obj,
12661296

12671297
/* parse the format_spec */
12681298
if (!parse_internal_render_format_spec(format_spec, format_spec_len,
1269-
&format, 's'))
1299+
&format, 's', '<'))
12701300
goto done;
12711301

12721302
/* type conversion? */
@@ -1306,7 +1336,7 @@ format_int_or_long(PyObject* obj,
13061336
/* parse the format_spec */
13071337
if (!parse_internal_render_format_spec(format_spec,
13081338
format_spec_len,
1309-
&format, 'd'))
1339+
&format, 'd', '>'))
13101340
goto done;
13111341

13121342
/* type conversion? */
@@ -1417,7 +1447,7 @@ FORMAT_FLOAT(PyObject *obj,
14171447
/* parse the format_spec */
14181448
if (!parse_internal_render_format_spec(format_spec,
14191449
format_spec_len,
1420-
&format, '\0'))
1450+
&format, '\0', '>'))
14211451
goto done;
14221452

14231453
/* type conversion? */
@@ -1465,7 +1495,7 @@ FORMAT_COMPLEX(PyObject *obj,
14651495
/* parse the format_spec */
14661496
if (!parse_internal_render_format_spec(format_spec,
14671497
format_spec_len,
1468-
&format, '\0'))
1498+
&format, '\0', '>'))
14691499
goto done;
14701500

14711501
/* type conversion? */

0 commit comments

Comments
 (0)