changeset: 90250:520ce42ba2b8 branch: 2.7 parent: 90234:50c07ed1743d user: Eric V. Smith date: Mon Apr 14 11:22:33 2014 -0400 files: Lib/test/test_unicode.py Misc/NEWS Objects/stringlib/formatter.h description: Issue #12546: Allow \x00 as a fill character for builtin type __format__ methods. diff -r 50c07ed1743d -r 520ce42ba2b8 Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py Sun Apr 13 22:10:38 2014 -0400 +++ b/Lib/test/test_unicode.py Mon Apr 14 11:22:33 2014 -0400 @@ -1463,6 +1463,27 @@ self.assertEqual(u'{0:10000}'.format(u''), u' ' * 10000) self.assertEqual(u'{0:10000000}'.format(u''), u' ' * 10000000) + # issue 12546: use \x00 as a fill character + self.assertEqual('{0:\x00<6s}'.format('foo'), 'foo\x00\x00\x00') + self.assertEqual('{0:\x01<6s}'.format('foo'), 'foo\x01\x01\x01') + self.assertEqual('{0:\x00^6s}'.format('foo'), '\x00foo\x00\x00') + self.assertEqual('{0:^6s}'.format('foo'), ' foo ') + + self.assertEqual('{0:\x00<6}'.format(3), '3\x00\x00\x00\x00\x00') + self.assertEqual('{0:\x01<6}'.format(3), '3\x01\x01\x01\x01\x01') + self.assertEqual('{0:\x00^6}'.format(3), '\x00\x003\x00\x00\x00') + self.assertEqual('{0:<6}'.format(3), '3 ') + + self.assertEqual('{0:\x00<6}'.format(3.14), '3.14\x00\x00') + self.assertEqual('{0:\x01<6}'.format(3.14), '3.14\x01\x01') + self.assertEqual('{0:\x00^6}'.format(3.14), '\x003.14\x00') + self.assertEqual('{0:^6}'.format(3.14), ' 3.14 ') + + self.assertEqual('{0:\x00<12}'.format(3+2.0j), '(3+2j)\x00\x00\x00\x00\x00\x00') + self.assertEqual('{0:\x01<12}'.format(3+2.0j), '(3+2j)\x01\x01\x01\x01\x01\x01') + self.assertEqual('{0:\x00^12}'.format(3+2.0j), '\x00\x00\x00(3+2j)\x00\x00\x00') + self.assertEqual('{0:^12}'.format(3+2.0j), ' (3+2j) ') + # format specifiers for user defined type self.assertEqual(u'{0:abc}'.format(C()), u'abc') diff -r 50c07ed1743d -r 520ce42ba2b8 Misc/NEWS --- a/Misc/NEWS Sun Apr 13 22:10:38 2014 -0400 +++ b/Misc/NEWS Mon Apr 14 11:22:33 2014 -0400 @@ -40,6 +40,9 @@ - Issue #19638: Fix possible crash / undefined behaviour from huge (more than 2 billion characters) input strings in _Py_dg_strtod. +- Issue #12546: Allow \x00 to be used as a fill character when using str, int, + float, and complex __format__ methods. + Library ------- diff -r 50c07ed1743d -r 520ce42ba2b8 Objects/stringlib/formatter.h --- a/Objects/stringlib/formatter.h Sun Apr 13 22:10:38 2014 -0400 +++ b/Objects/stringlib/formatter.h Mon Apr 14 11:22:33 2014 -0400 @@ -180,8 +180,9 @@ 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'; @@ -195,6 +196,7 @@ if (end-ptr >= 2 && is_alignment_token(ptr[1])) { format->align = ptr[1]; format->fill_char = ptr[0]; + fill_char_specified = 1; align_specified = 1; ptr += 2; } @@ -218,7 +220,7 @@ } /* The special case for 0-padding (backwards compat) */ - if (format->fill_char == '\0' && end-ptr >= 1 && ptr[0] == '0') { + if (!fill_char_specified && end-ptr >= 1 && ptr[0] == '0') { format->fill_char = '0'; if (!align_specified) { format->align = '='; @@ -715,8 +717,7 @@ /* Write into that space. First the padding. */ p = fill_padding(STRINGLIB_STR(result), len, - format->fill_char=='\0'?' ':format->fill_char, - lpad, rpad); + format->fill_char, lpad, rpad); /* Then the source string. */ memcpy(p, STRINGLIB_STR(value), len * sizeof(STRINGLIB_CHAR)); @@ -893,8 +894,7 @@ /* Populate the memory. */ fill_number(STRINGLIB_STR(result), &spec, pnumeric_chars, n_digits, - prefix, format->fill_char == '\0' ? ' ' : format->fill_char, - &locale, format->type == 'X'); + prefix, format->fill_char, &locale, format->type == 'X'); done: Py_XDECREF(tmp); @@ -1048,8 +1048,7 @@ /* Populate the memory. */ fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL, - format->fill_char == '\0' ? ' ' : format->fill_char, &locale, - 0); + format->fill_char, &locale, 0); done: PyMem_Free(buf); @@ -1265,8 +1264,7 @@ /* Populate the memory. First, the padding. */ p = fill_padding(STRINGLIB_STR(result), 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 (add_parens) *p++ = '(';