diff -r 4d00d0109147 Lib/test/test_format.py --- a/Lib/test/test_format.py Wed Jan 07 00:37:01 2015 +1000 +++ b/Lib/test/test_format.py Tue Jan 06 10:39:20 2015 -0800 @@ -2,21 +2,21 @@ from test.support import verbose, TestFa import locale import sys import test.support as support import unittest maxsize = support.MAX_Py_ssize_t # test string formatting operator (I am not sure if this is being tested # elsewhere but, surely, some of the given cases are *not* tested because # they crash python) -# test on unicode strings as well +# test on bytes object as well def testformat(formatstr, args, output=None, limit=None, overflowok=False): if verbose: if output: print("{!a} % {!a} =? {!a} ...".format(formatstr, args, output), end=' ') else: print("{!a} % {!a} works? ...".format(formatstr, args), end=' ') try: result = formatstr % args @@ -39,195 +39,223 @@ def testformat(formatstr, args, output=N elif output and limit is not None and ( len(result)!=len(output) or result[:limit]!=output[:limit]): if verbose: print('no') print("%s %% %s == %s != %s" % \ (repr(formatstr), repr(args), repr(result), repr(output))) else: if verbose: print('yes') +def testcommon(formatstr, args, output=None, limit=None, overflowok=False): + # if formatstr is a str, test str, bytes, and bytearray; + # otherwise, test bytes and bytearry + if isinstance(formatstr, str): + testformat(formatstr, args, output, limit, overflowok) + b_format = formatstr.encode('ascii') + else: + b_format = formatstr + ba_format = bytearray(b_format) + b_args = [] + if not isinstance(args, tuple): + args = (args, ) + b_args = tuple(args) + if output is None: + b_output = ba_output = None + else: + if isinstance(output, str): + b_output = output.encode('ascii') + else: + b_output = output + ba_output = bytearray(b_output) + testformat(b_format, b_args, b_output, limit, overflowok) + # testformat(ba_format, b_args, ba_output, limit, overflowok) + class FormatTest(unittest.TestCase): - def test_format(self): - testformat("%.1d", (1,), "1") - testformat("%.*d", (sys.maxsize,1), overflowok=True) # expect overflow - testformat("%.100d", (1,), '00000000000000000000000000000000000000' + + def test_common_format(self): + # test the format identifiers that work the same across + # str, bytes, and bytearrays (integer, float, oct, hex) + testcommon("%.1d", (1,), "1") + testcommon("%.*d", (sys.maxsize,1), overflowok=True) # expect overflow + testcommon("%.100d", (1,), '00000000000000000000000000000000000000' '000000000000000000000000000000000000000000000000000000' '00000001', overflowok=True) - testformat("%#.117x", (1,), '0x00000000000000000000000000000000000' + testcommon("%#.117x", (1,), '0x00000000000000000000000000000000000' '000000000000000000000000000000000000000000000000000000' '0000000000000000000000000001', overflowok=True) - testformat("%#.118x", (1,), '0x00000000000000000000000000000000000' + testcommon("%#.118x", (1,), '0x00000000000000000000000000000000000' '000000000000000000000000000000000000000000000000000000' '00000000000000000000000000001', overflowok=True) - testformat("%f", (1.0,), "1.000000") + testcommon("%f", (1.0,), "1.000000") # these are trying to test the limits of the internal magic-number-length # formatting buffer, if that number changes then these tests are less # effective - testformat("%#.*g", (109, -1.e+49/3.)) - testformat("%#.*g", (110, -1.e+49/3.)) - testformat("%#.*g", (110, -1.e+100/3.)) + testcommon("%#.*g", (109, -1.e+49/3.)) + testcommon("%#.*g", (110, -1.e+49/3.)) + testcommon("%#.*g", (110, -1.e+100/3.)) # test some ridiculously large precision, expect overflow - testformat('%12.*f', (123456, 1.0)) + testcommon('%12.*f', (123456, 1.0)) # check for internal overflow validation on length of precision # these tests should no longer cause overflow in Python # 2.7/3.1 and later. - testformat("%#.*g", (110, -1.e+100/3.)) - testformat("%#.*G", (110, -1.e+100/3.)) - testformat("%#.*f", (110, -1.e+100/3.)) - testformat("%#.*F", (110, -1.e+100/3.)) + testcommon("%#.*g", (110, -1.e+100/3.)) + testcommon("%#.*G", (110, -1.e+100/3.)) + testcommon("%#.*f", (110, -1.e+100/3.)) + testcommon("%#.*F", (110, -1.e+100/3.)) # Formatting of integers. Overflow is not ok - testformat("%x", 10, "a") - testformat("%x", 100000000000, "174876e800") - testformat("%o", 10, "12") - testformat("%o", 100000000000, "1351035564000") - testformat("%d", 10, "10") - testformat("%d", 100000000000, "100000000000") + testcommon("%x", 10, "a") + testcommon("%x", 100000000000, "174876e800") + testcommon("%o", 10, "12") + testcommon("%o", 100000000000, "1351035564000") + testcommon("%d", 10, "10") + testcommon("%d", 100000000000, "100000000000") big = 123456789012345678901234567890 - testformat("%d", big, "123456789012345678901234567890") - testformat("%d", -big, "-123456789012345678901234567890") - testformat("%5d", -big, "-123456789012345678901234567890") - testformat("%31d", -big, "-123456789012345678901234567890") - testformat("%32d", -big, " -123456789012345678901234567890") - testformat("%-32d", -big, "-123456789012345678901234567890 ") - testformat("%032d", -big, "-0123456789012345678901234567890") - testformat("%-032d", -big, "-123456789012345678901234567890 ") - testformat("%034d", -big, "-000123456789012345678901234567890") - testformat("%034d", big, "0000123456789012345678901234567890") - testformat("%0+34d", big, "+000123456789012345678901234567890") - testformat("%+34d", big, " +123456789012345678901234567890") - testformat("%34d", big, " 123456789012345678901234567890") - testformat("%.2d", big, "123456789012345678901234567890") - testformat("%.30d", big, "123456789012345678901234567890") - testformat("%.31d", big, "0123456789012345678901234567890") - testformat("%32.31d", big, " 0123456789012345678901234567890") - testformat("%d", float(big), "123456________________________", 6) + testcommon("%d", big, "123456789012345678901234567890") + testcommon("%d", -big, "-123456789012345678901234567890") + testcommon("%5d", -big, "-123456789012345678901234567890") + testcommon("%31d", -big, "-123456789012345678901234567890") + testcommon("%32d", -big, " -123456789012345678901234567890") + testcommon("%-32d", -big, "-123456789012345678901234567890 ") + testcommon("%032d", -big, "-0123456789012345678901234567890") + testcommon("%-032d", -big, "-123456789012345678901234567890 ") + testcommon("%034d", -big, "-000123456789012345678901234567890") + testcommon("%034d", big, "0000123456789012345678901234567890") + testcommon("%0+34d", big, "+000123456789012345678901234567890") + testcommon("%+34d", big, " +123456789012345678901234567890") + testcommon("%34d", big, " 123456789012345678901234567890") + testcommon("%.2d", big, "123456789012345678901234567890") + testcommon("%.30d", big, "123456789012345678901234567890") + testcommon("%.31d", big, "0123456789012345678901234567890") + testcommon("%32.31d", big, " 0123456789012345678901234567890") + testcommon("%d", float(big), "123456________________________", 6) big = 0x1234567890abcdef12345 # 21 hex digits - testformat("%x", big, "1234567890abcdef12345") - testformat("%x", -big, "-1234567890abcdef12345") - testformat("%5x", -big, "-1234567890abcdef12345") - testformat("%22x", -big, "-1234567890abcdef12345") - testformat("%23x", -big, " -1234567890abcdef12345") - testformat("%-23x", -big, "-1234567890abcdef12345 ") - testformat("%023x", -big, "-01234567890abcdef12345") - testformat("%-023x", -big, "-1234567890abcdef12345 ") - testformat("%025x", -big, "-0001234567890abcdef12345") - testformat("%025x", big, "00001234567890abcdef12345") - testformat("%0+25x", big, "+0001234567890abcdef12345") - testformat("%+25x", big, " +1234567890abcdef12345") - testformat("%25x", big, " 1234567890abcdef12345") - testformat("%.2x", big, "1234567890abcdef12345") - testformat("%.21x", big, "1234567890abcdef12345") - testformat("%.22x", big, "01234567890abcdef12345") - testformat("%23.22x", big, " 01234567890abcdef12345") - testformat("%-23.22x", big, "01234567890abcdef12345 ") - testformat("%X", big, "1234567890ABCDEF12345") - testformat("%#X", big, "0X1234567890ABCDEF12345") - testformat("%#x", big, "0x1234567890abcdef12345") - testformat("%#x", -big, "-0x1234567890abcdef12345") - testformat("%#.23x", -big, "-0x001234567890abcdef12345") - testformat("%#+.23x", big, "+0x001234567890abcdef12345") - testformat("%# .23x", big, " 0x001234567890abcdef12345") - testformat("%#+.23X", big, "+0X001234567890ABCDEF12345") - testformat("%#-+.23X", big, "+0X001234567890ABCDEF12345") - testformat("%#-+26.23X", big, "+0X001234567890ABCDEF12345") - testformat("%#-+27.23X", big, "+0X001234567890ABCDEF12345 ") - testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345") + testcommon("%x", big, "1234567890abcdef12345") + testcommon("%x", -big, "-1234567890abcdef12345") + testcommon("%5x", -big, "-1234567890abcdef12345") + testcommon("%22x", -big, "-1234567890abcdef12345") + testcommon("%23x", -big, " -1234567890abcdef12345") + testcommon("%-23x", -big, "-1234567890abcdef12345 ") + testcommon("%023x", -big, "-01234567890abcdef12345") + testcommon("%-023x", -big, "-1234567890abcdef12345 ") + testcommon("%025x", -big, "-0001234567890abcdef12345") + testcommon("%025x", big, "00001234567890abcdef12345") + testcommon("%0+25x", big, "+0001234567890abcdef12345") + testcommon("%+25x", big, " +1234567890abcdef12345") + testcommon("%25x", big, " 1234567890abcdef12345") + testcommon("%.2x", big, "1234567890abcdef12345") + testcommon("%.21x", big, "1234567890abcdef12345") + testcommon("%.22x", big, "01234567890abcdef12345") + testcommon("%23.22x", big, " 01234567890abcdef12345") + testcommon("%-23.22x", big, "01234567890abcdef12345 ") + testcommon("%X", big, "1234567890ABCDEF12345") + testcommon("%#X", big, "0X1234567890ABCDEF12345") + testcommon("%#x", big, "0x1234567890abcdef12345") + testcommon("%#x", -big, "-0x1234567890abcdef12345") + testcommon("%#.23x", -big, "-0x001234567890abcdef12345") + testcommon("%#+.23x", big, "+0x001234567890abcdef12345") + testcommon("%# .23x", big, " 0x001234567890abcdef12345") + testcommon("%#+.23X", big, "+0X001234567890ABCDEF12345") + testcommon("%#-+.23X", big, "+0X001234567890ABCDEF12345") + testcommon("%#-+26.23X", big, "+0X001234567890ABCDEF12345") + testcommon("%#-+27.23X", big, "+0X001234567890ABCDEF12345 ") + testcommon("%#+27.23X", big, " +0X001234567890ABCDEF12345") # next one gets two leading zeroes from precision, and another from the # 0 flag and the width - testformat("%#+027.23X", big, "+0X0001234567890ABCDEF12345") + testcommon("%#+027.23X", big, "+0X0001234567890ABCDEF12345") # same, except no 0 flag - testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345") + testcommon("%#+27.23X", big, " +0X001234567890ABCDEF12345") big = 0o12345670123456701234567012345670 # 32 octal digits - testformat("%o", big, "12345670123456701234567012345670") - testformat("%o", -big, "-12345670123456701234567012345670") - testformat("%5o", -big, "-12345670123456701234567012345670") - testformat("%33o", -big, "-12345670123456701234567012345670") - testformat("%34o", -big, " -12345670123456701234567012345670") - testformat("%-34o", -big, "-12345670123456701234567012345670 ") - testformat("%034o", -big, "-012345670123456701234567012345670") - testformat("%-034o", -big, "-12345670123456701234567012345670 ") - testformat("%036o", -big, "-00012345670123456701234567012345670") - testformat("%036o", big, "000012345670123456701234567012345670") - testformat("%0+36o", big, "+00012345670123456701234567012345670") - testformat("%+36o", big, " +12345670123456701234567012345670") - testformat("%36o", big, " 12345670123456701234567012345670") - testformat("%.2o", big, "12345670123456701234567012345670") - testformat("%.32o", big, "12345670123456701234567012345670") - testformat("%.33o", big, "012345670123456701234567012345670") - testformat("%34.33o", big, " 012345670123456701234567012345670") - testformat("%-34.33o", big, "012345670123456701234567012345670 ") - testformat("%o", big, "12345670123456701234567012345670") - testformat("%#o", big, "0o12345670123456701234567012345670") - testformat("%#o", -big, "-0o12345670123456701234567012345670") - testformat("%#.34o", -big, "-0o0012345670123456701234567012345670") - testformat("%#+.34o", big, "+0o0012345670123456701234567012345670") - testformat("%# .34o", big, " 0o0012345670123456701234567012345670") - testformat("%#+.34o", big, "+0o0012345670123456701234567012345670") - testformat("%#-+.34o", big, "+0o0012345670123456701234567012345670") - testformat("%#-+37.34o", big, "+0o0012345670123456701234567012345670") - testformat("%#+37.34o", big, "+0o0012345670123456701234567012345670") + testcommon("%o", big, "12345670123456701234567012345670") + testcommon("%o", -big, "-12345670123456701234567012345670") + testcommon("%5o", -big, "-12345670123456701234567012345670") + testcommon("%33o", -big, "-12345670123456701234567012345670") + testcommon("%34o", -big, " -12345670123456701234567012345670") + testcommon("%-34o", -big, "-12345670123456701234567012345670 ") + testcommon("%034o", -big, "-012345670123456701234567012345670") + testcommon("%-034o", -big, "-12345670123456701234567012345670 ") + testcommon("%036o", -big, "-00012345670123456701234567012345670") + testcommon("%036o", big, "000012345670123456701234567012345670") + testcommon("%0+36o", big, "+00012345670123456701234567012345670") + testcommon("%+36o", big, " +12345670123456701234567012345670") + testcommon("%36o", big, " 12345670123456701234567012345670") + testcommon("%.2o", big, "12345670123456701234567012345670") + testcommon("%.32o", big, "12345670123456701234567012345670") + testcommon("%.33o", big, "012345670123456701234567012345670") + testcommon("%34.33o", big, " 012345670123456701234567012345670") + testcommon("%-34.33o", big, "012345670123456701234567012345670 ") + testcommon("%o", big, "12345670123456701234567012345670") + testcommon("%#o", big, "0o12345670123456701234567012345670") + testcommon("%#o", -big, "-0o12345670123456701234567012345670") + testcommon("%#.34o", -big, "-0o0012345670123456701234567012345670") + testcommon("%#+.34o", big, "+0o0012345670123456701234567012345670") + testcommon("%# .34o", big, " 0o0012345670123456701234567012345670") + testcommon("%#+.34o", big, "+0o0012345670123456701234567012345670") + testcommon("%#-+.34o", big, "+0o0012345670123456701234567012345670") + testcommon("%#-+37.34o", big, "+0o0012345670123456701234567012345670") + testcommon("%#+37.34o", big, "+0o0012345670123456701234567012345670") # next one gets one leading zero from precision - testformat("%.33o", big, "012345670123456701234567012345670") + testcommon("%.33o", big, "012345670123456701234567012345670") # base marker shouldn't change that, since "0" is redundant - testformat("%#.33o", big, "0o012345670123456701234567012345670") + testcommon("%#.33o", big, "0o012345670123456701234567012345670") # but reduce precision, and base marker should add a zero - testformat("%#.32o", big, "0o12345670123456701234567012345670") + testcommon("%#.32o", big, "0o12345670123456701234567012345670") # one leading zero from precision, and another from "0" flag & width - testformat("%034.33o", big, "0012345670123456701234567012345670") + testcommon("%034.33o", big, "0012345670123456701234567012345670") # base marker shouldn't change that - testformat("%0#34.33o", big, "0o012345670123456701234567012345670") + testcommon("%0#34.33o", big, "0o012345670123456701234567012345670") # Some small ints, in both Python int and flavors). - testformat("%d", 42, "42") - testformat("%d", -42, "-42") - testformat("%d", 42, "42") - testformat("%d", -42, "-42") - testformat("%d", 42.0, "42") - testformat("%#x", 1, "0x1") - testformat("%#x", 1, "0x1") - testformat("%#X", 1, "0X1") - testformat("%#X", 1, "0X1") - testformat("%#o", 1, "0o1") - testformat("%#o", 1, "0o1") - testformat("%#o", 0, "0o0") - testformat("%#o", 0, "0o0") - testformat("%o", 0, "0") - testformat("%o", 0, "0") - testformat("%d", 0, "0") - testformat("%d", 0, "0") - testformat("%#x", 0, "0x0") - testformat("%#x", 0, "0x0") - testformat("%#X", 0, "0X0") - testformat("%#X", 0, "0X0") - testformat("%x", 0x42, "42") - testformat("%x", -0x42, "-42") - testformat("%x", 0x42, "42") - testformat("%x", -0x42, "-42") - testformat("%o", 0o42, "42") - testformat("%o", -0o42, "-42") - testformat("%o", 0o42, "42") - testformat("%o", -0o42, "-42") + testcommon("%d", 42, "42") + testcommon("%d", -42, "-42") + testcommon("%d", 42, "42") + testcommon("%d", -42, "-42") + testcommon("%d", 42.0, "42") + testcommon("%#x", 1, "0x1") + testcommon("%#x", 1, "0x1") + testcommon("%#X", 1, "0X1") + testcommon("%#X", 1, "0X1") + testcommon("%#o", 1, "0o1") + testcommon("%#o", 1, "0o1") + testcommon("%#o", 0, "0o0") + testcommon("%#o", 0, "0o0") + testcommon("%o", 0, "0") + testcommon("%o", 0, "0") + testcommon("%d", 0, "0") + testcommon("%d", 0, "0") + testcommon("%#x", 0, "0x0") + testcommon("%#x", 0, "0x0") + testcommon("%#X", 0, "0X0") + testcommon("%#X", 0, "0X0") + testcommon("%x", 0x42, "42") + testcommon("%x", -0x42, "-42") + testcommon("%x", 0x42, "42") + testcommon("%x", -0x42, "-42") + testcommon("%o", 0o42, "42") + testcommon("%o", -0o42, "-42") + testcommon("%o", 0o42, "42") + testcommon("%o", -0o42, "-42") + # alternate float formatting + testcommon('%g', 1.1, '1.1') + testcommon('%#g', 1.1, '1.10000') + + def test_str_format(self): testformat("%r", "\u0378", "'\\u0378'") # non printable testformat("%a", "\u0378", "'\\u0378'") # non printable testformat("%r", "\u0374", "'\u0374'") # printable testformat("%a", "\u0374", "'\\u0374'") # printable - # alternate float formatting - testformat('%g', 1.1, '1.1') - testformat('%#g', 1.1, '1.10000') - - # Test exception for unknown format characters + # Test exception for unknown format characters, etc. if verbose: print('Testing exceptions') def test_exc(formatstr, args, exception, excmsg): try: testformat(formatstr, args) except exception as exc: if str(exc) == excmsg: if verbose: print("yes") else: @@ -240,22 +268,97 @@ class FormatTest(unittest.TestCase): else: raise TestFailed('did not get expected exception: %s' % excmsg) test_exc('abc %b', 1, ValueError, "unsupported format character 'b' (0x62) at index 5") #test_exc(unicode('abc %\u3000','raw-unicode-escape'), 1, ValueError, # "unsupported format character '?' (0x3000) at index 5") test_exc('%d', '1', TypeError, "%d format: a number is required, not str") test_exc('%g', '1', TypeError, "a float is required") test_exc('no format', '1', TypeError, "not all arguments converted during string formatting") - test_exc('no format', '1', TypeError, - "not all arguments converted during string formatting") + + if maxsize == 2**31-1: + # crashes 2.2.1 and earlier: + try: + "%*d"%(maxsize, -127) + except MemoryError: + pass + else: + raise TestFailed('"%*d"%(maxsize, -127) should fail') + + def test_bytes_and_bytearray_format(self): + # %c will insert a single byte, either from an int in range(256), or + # from a bytes argument of length 1, not from a str. + testcommon(b"%c", 7, b"\x07") + testcommon(b"%c", b"Z", b"Z") + # testcommon(b"%c", bytearray(b"Z"), b"Z") + # %b will insert a series of bytes, either from a type that supports + # the Py_buffer protocol, or something that has a __bytes__ method + class FakeBytes(object): + def __bytes__(self): + return b'123' + fb = FakeBytes() + testcommon(b"%b", b"abc", b"abc") + # testcommon(b"%b", bytearray(b"def"), b"def") + testcommon(b"%b", fb, b"123") + # %s is an alias for %b -- should only be used for Py2/3 code + testcommon(b"%s", b"abc", b"abc") + # testcommon(b"%s", bytearray(b"def"), b"def") + testcommon(b"%s", fb, b"123") + # %a will give the equivalent of + # repr(some_obj).encode('ascii', 'backslashreplace') + testcommon(b"%a", 3.14, b"3.14") + testcommon(b"%a", b"ghi", b"b'ghi'") + testcommon(b"%a", "jkl", b"'jkl'") + testcommon(b"%a", "\u0544", b"'\\u0544'") + + # Test exception for unknown format characters, etc. + if verbose: + print('Testing exceptions') + def test_exc(formatstr, args, exception, excmsg): + try: + testformat(formatstr, args) + except exception as exc: + if str(exc) == excmsg: + if verbose: + print("yes") + else: + if verbose: print('no') + print('Unexpected ', exception, ':', repr(str(exc))) + except: + if verbose: print('no') + print('Unexpected exception') + raise + else: + raise TestFailed('did not get expected exception: %s' % excmsg) + test_exc(b'%d', '1', TypeError, + "%d format: a number is required, not str") + test_exc(b'%d', b'1', TypeError, + "%d format: a number is required, not bytes") + test_exc(b'%g', '1', TypeError, "float argument required, not str") + test_exc(b'%g', b'1', TypeError, "float argument required, not bytes") + test_exc(b'no format', 7, TypeError, + "not all arguments converted during bytes formatting") + test_exc(b'no format', b'1', TypeError, + "not all arguments converted during bytes formatting") + test_exc(b'no format', bytearray(b'1'), TypeError, + "not all arguments converted during bytes formatting") + test_exc(b"%c", 256, TypeError, + "%c requires an integer in range(256) or a single byte") + test_exc(b"%c", b"Za", TypeError, + "%c requires an integer in range(256) or a single byte") + test_exc(b"%c", "Yb", TypeError, + "%c requires an integer in range(256) or a single byte") + test_exc(b"%b", "Xc", TypeError, + "%b requires bytes, or an object that implements __bytes__, not 'str'") + test_exc(b"%s", "Wd", TypeError, + "%b requires bytes, or an object that implements __bytes__, not 'str'") if maxsize == 2**31-1: # crashes 2.2.1 and earlier: try: "%*d"%(maxsize, -127) except MemoryError: pass else: raise TestFailed('"%*d"%(maxsize, -127) should fail')