Skip to content

Commit 2ea9712

Browse files
committed
Issue python#12546: Allow \x00 as a fill character for builtin type __format__ methods.
1 parent 70d92a9 commit 2ea9712

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

Lib/test/test_unicode.py

+21
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,27 @@ def __format__(self, format_spec):
845845
self.assertEqual('{0:10000}'.format(''), ' ' * 10000)
846846
self.assertEqual('{0:10000000}'.format(''), ' ' * 10000000)
847847

848+
# issue 12546: use \x00 as a fill character
849+
self.assertEqual('{0:\x00<6s}'.format('foo'), 'foo\x00\x00\x00')
850+
self.assertEqual('{0:\x01<6s}'.format('foo'), 'foo\x01\x01\x01')
851+
self.assertEqual('{0:\x00^6s}'.format('foo'), '\x00foo\x00\x00')
852+
self.assertEqual('{0:^6s}'.format('foo'), ' foo ')
853+
854+
self.assertEqual('{0:\x00<6}'.format(3), '3\x00\x00\x00\x00\x00')
855+
self.assertEqual('{0:\x01<6}'.format(3), '3\x01\x01\x01\x01\x01')
856+
self.assertEqual('{0:\x00^6}'.format(3), '\x00\x003\x00\x00\x00')
857+
self.assertEqual('{0:<6}'.format(3), '3 ')
858+
859+
self.assertEqual('{0:\x00<6}'.format(3.14), '3.14\x00\x00')
860+
self.assertEqual('{0:\x01<6}'.format(3.14), '3.14\x01\x01')
861+
self.assertEqual('{0:\x00^6}'.format(3.14), '\x003.14\x00')
862+
self.assertEqual('{0:^6}'.format(3.14), ' 3.14 ')
863+
864+
self.assertEqual('{0:\x00<12}'.format(3+2.0j), '(3+2j)\x00\x00\x00\x00\x00\x00')
865+
self.assertEqual('{0:\x01<12}'.format(3+2.0j), '(3+2j)\x01\x01\x01\x01\x01\x01')
866+
self.assertEqual('{0:\x00^12}'.format(3+2.0j), '\x00\x00\x00(3+2j)\x00\x00\x00')
867+
self.assertEqual('{0:^12}'.format(3+2.0j), ' (3+2j) ')
868+
848869
# format specifiers for user defined type
849870
self.assertEqual('{0:abc}'.format(C()), 'abc')
850871

Misc/NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ Core and Builtins
2727
- Issue #20637: Key-sharing now also works for instance dictionaries of
2828
subclasses. Patch by Peter Ingebretson.
2929

30+
- Issue #12546: Allow \x00 to be used as a fill character when using str, int,
31+
float, and complex __format__ methods.
32+
3033
Library
3134
-------
3235

Python/formatter_unicode.c

+8-11
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,9 @@ parse_internal_render_format_spec(PyObject *format_spec,
156156

157157
Py_ssize_t consumed;
158158
int align_specified = 0;
159+
int fill_char_specified = 0;
159160

160-
format->fill_char = '\0';
161+
format->fill_char = ' ';
161162
format->align = default_align;
162163
format->alternate = 0;
163164
format->sign = '\0';
@@ -171,6 +172,7 @@ parse_internal_render_format_spec(PyObject *format_spec,
171172
if (end-pos >= 2 && is_alignment_token(READ_spec(pos+1))) {
172173
format->align = READ_spec(pos+1);
173174
format->fill_char = READ_spec(pos);
175+
fill_char_specified = 1;
174176
align_specified = 1;
175177
pos += 2;
176178
}
@@ -194,7 +196,7 @@ parse_internal_render_format_spec(PyObject *format_spec,
194196
}
195197

196198
/* The special case for 0-padding (backwards compat) */
197-
if (format->fill_char == '\0' && end-pos >= 1 && READ_spec(pos) == '0') {
199+
if (!fill_char_specified && end-pos >= 1 && READ_spec(pos) == '0') {
198200
format->fill_char = '0';
199201
if (!align_specified) {
200202
format->align = '=';
@@ -784,9 +786,7 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format,
784786
goto done;
785787

786788
/* Write into that space. First the padding. */
787-
result = fill_padding(writer, len,
788-
format->fill_char=='\0'?' ':format->fill_char,
789-
lpad, rpad);
789+
result = fill_padding(writer, len, format->fill_char, lpad, rpad);
790790
if (result == -1)
791791
goto done;
792792

@@ -956,8 +956,7 @@ format_long_internal(PyObject *value, const InternalFormatSpec *format,
956956
/* Populate the memory. */
957957
result = fill_number(writer, &spec,
958958
tmp, inumeric_chars, inumeric_chars + n_digits,
959-
tmp, prefix,
960-
format->fill_char == '\0' ? ' ' : format->fill_char,
959+
tmp, prefix, format->fill_char,
961960
&locale, format->type == 'X');
962961

963962
done:
@@ -1104,8 +1103,7 @@ format_float_internal(PyObject *value,
11041103
/* Populate the memory. */
11051104
result = fill_number(writer, &spec,
11061105
unicode_tmp, index, index + n_digits,
1107-
NULL, 0,
1108-
format->fill_char == '\0' ? ' ' : format->fill_char,
1106+
NULL, 0, format->fill_char,
11091107
&locale, 0);
11101108

11111109
done:
@@ -1311,8 +1309,7 @@ format_complex_internal(PyObject *value,
13111309
/* Populate the memory. First, the padding. */
13121310
result = fill_padding(writer,
13131311
n_re_total + n_im_total + 1 + add_parens * 2,
1314-
format->fill_char=='\0' ? ' ' : format->fill_char,
1315-
lpad, rpad);
1312+
format->fill_char, lpad, rpad);
13161313
if (result == -1)
13171314
goto done;
13181315

0 commit comments

Comments
 (0)