Home | History | Annotate | Download | only in test
      1 import unittest
      2 import struct
      3 import sys
      4 from test import test_support, string_tests
      5 
      6 
      7 class StrSubclass(str):
      8     pass
      9 
     10 class StrTest(
     11     string_tests.CommonTest,
     12     string_tests.MixinStrUnicodeUserStringTest,
     13     string_tests.MixinStrUserStringTest,
     14     string_tests.MixinStrUnicodeTest,
     15     ):
     16 
     17     type2test = str
     18 
     19     # We don't need to propagate to str
     20     def fixtype(self, obj):
     21         return obj
     22 
     23     def test_basic_creation(self):
     24         self.assertEqual(str(''), '')
     25         self.assertEqual(str(0), '0')
     26         self.assertEqual(str(0L), '0')
     27         self.assertEqual(str(()), '()')
     28         self.assertEqual(str([]), '[]')
     29         self.assertEqual(str({}), '{}')
     30         a = []
     31         a.append(a)
     32         self.assertEqual(str(a), '[[...]]')
     33         a = {}
     34         a[0] = a
     35         self.assertEqual(str(a), '{0: {...}}')
     36 
     37     def test_formatting(self):
     38         string_tests.MixinStrUnicodeUserStringTest.test_formatting(self)
     39         self.assertRaises(OverflowError, '%c'.__mod__, 0x1234)
     40 
     41     @test_support.cpython_only
     42     def test_formatting_huge_precision(self):
     43         from _testcapi import INT_MAX
     44         format_string = "%.{}f".format(INT_MAX + 1)
     45         with self.assertRaises(ValueError):
     46             result = format_string % 2.34
     47 
     48     def test_formatting_huge_width(self):
     49         format_string = "%{}f".format(sys.maxsize + 1)
     50         with self.assertRaises(ValueError):
     51             result = format_string % 2.34
     52 
     53     def test_conversion(self):
     54         # Make sure __str__() behaves properly
     55         class Foo0:
     56             def __unicode__(self):
     57                 return u"foo"
     58 
     59         class Foo1:
     60             def __str__(self):
     61                 return "foo"
     62 
     63         class Foo2(object):
     64             def __str__(self):
     65                 return "foo"
     66 
     67         class Foo3(object):
     68             def __str__(self):
     69                 return u"foo"
     70 
     71         class Foo4(unicode):
     72             def __str__(self):
     73                 return u"foo"
     74 
     75         class Foo5(str):
     76             def __str__(self):
     77                 return u"foo"
     78 
     79         class Foo6(str):
     80             def __str__(self):
     81                 return "foos"
     82 
     83             def __unicode__(self):
     84                 return u"foou"
     85 
     86         class Foo7(unicode):
     87             def __str__(self):
     88                 return "foos"
     89             def __unicode__(self):
     90                 return u"foou"
     91 
     92         class Foo8(str):
     93             def __new__(cls, content=""):
     94                 return str.__new__(cls, 2*content)
     95             def __str__(self):
     96                 return self
     97 
     98         class Foo9(str):
     99             def __str__(self):
    100                 return "string"
    101             def __unicode__(self):
    102                 return "not unicode"
    103 
    104         self.assertTrue(str(Foo0()).startswith("<")) # this is different from __unicode__
    105         self.assertEqual(str(Foo1()), "foo")
    106         self.assertEqual(str(Foo2()), "foo")
    107         self.assertEqual(str(Foo3()), "foo")
    108         self.assertEqual(str(Foo4("bar")), "foo")
    109         self.assertEqual(str(Foo5("bar")), "foo")
    110         self.assertEqual(str(Foo6("bar")), "foos")
    111         self.assertEqual(str(Foo7("bar")), "foos")
    112         self.assertEqual(str(Foo8("foo")), "foofoo")
    113         self.assertIs(type(str(Foo8("foo"))), Foo8)
    114         self.assertEqual(StrSubclass(Foo8("foo")), "foofoo")
    115         self.assertIs(type(StrSubclass(Foo8("foo"))), StrSubclass)
    116         self.assertEqual(str(Foo9("foo")), "string")
    117         self.assertEqual(unicode(Foo9("foo")), u"not unicode")
    118 
    119     # This test only affects 32-bit platforms because expandtabs can only take
    120     # an int as the max value, not a 64-bit C long.  If expandtabs is changed
    121     # to take a 64-bit long, this test should apply to all platforms.
    122     @unittest.skipIf(sys.maxint > (1 << 32) or struct.calcsize('P') != 4,
    123                      'only applies to 32-bit platforms')
    124     def test_expandtabs_overflows_gracefully(self):
    125         self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxint)
    126 
    127     def test__format__(self):
    128         def test(value, format, expected):
    129             # test both with and without the trailing 's'
    130             self.assertEqual(value.__format__(format), expected)
    131             self.assertEqual(value.__format__(format + 's'), expected)
    132 
    133         test('', '', '')
    134         test('abc', '', 'abc')
    135         test('abc', '.3', 'abc')
    136         test('ab', '.3', 'ab')
    137         test('abcdef', '.3', 'abc')
    138         test('abcdef', '.0', '')
    139         test('abc', '3.3', 'abc')
    140         test('abc', '2.3', 'abc')
    141         test('abc', '2.2', 'ab')
    142         test('abc', '3.2', 'ab ')
    143         test('result', 'x<0', 'result')
    144         test('result', 'x<5', 'result')
    145         test('result', 'x<6', 'result')
    146         test('result', 'x<7', 'resultx')
    147         test('result', 'x<8', 'resultxx')
    148         test('result', ' <7', 'result ')
    149         test('result', '<7', 'result ')
    150         test('result', '>7', ' result')
    151         test('result', '>8', '  result')
    152         test('result', '^8', ' result ')
    153         test('result', '^9', ' result  ')
    154         test('result', '^10', '  result  ')
    155         test('a', '10000', 'a' + ' ' * 9999)
    156         test('', '10000', ' ' * 10000)
    157         test('', '10000000', ' ' * 10000000)
    158 
    159     def test_format(self):
    160         self.assertEqual(''.format(), '')
    161         self.assertEqual('a'.format(), 'a')
    162         self.assertEqual('ab'.format(), 'ab')
    163         self.assertEqual('a{{'.format(), 'a{')
    164         self.assertEqual('a}}'.format(), 'a}')
    165         self.assertEqual('{{b'.format(), '{b')
    166         self.assertEqual('}}b'.format(), '}b')
    167         self.assertEqual('a{{b'.format(), 'a{b')
    168 
    169         # examples from the PEP:
    170         import datetime
    171         self.assertEqual("My name is {0}".format('Fred'), "My name is Fred")
    172         self.assertEqual("My name is {0[name]}".format(dict(name='Fred')),
    173                          "My name is Fred")
    174         self.assertEqual("My name is {0} :-{{}}".format('Fred'),
    175                          "My name is Fred :-{}")
    176 
    177         d = datetime.date(2007, 8, 18)
    178         self.assertEqual("The year is {0.year}".format(d),
    179                          "The year is 2007")
    180 
    181         # classes we'll use for testing
    182         class C:
    183             def __init__(self, x=100):
    184                 self._x = x
    185             def __format__(self, spec):
    186                 return spec
    187 
    188         class D:
    189             def __init__(self, x):
    190                 self.x = x
    191             def __format__(self, spec):
    192                 return str(self.x)
    193 
    194         # class with __str__, but no __format__
    195         class E:
    196             def __init__(self, x):
    197                 self.x = x
    198             def __str__(self):
    199                 return 'E(' + self.x + ')'
    200 
    201         # class with __repr__, but no __format__ or __str__
    202         class F:
    203             def __init__(self, x):
    204                 self.x = x
    205             def __repr__(self):
    206                 return 'F(' + self.x + ')'
    207 
    208         # class with __format__ that forwards to string, for some format_spec's
    209         class G:
    210             def __init__(self, x):
    211                 self.x = x
    212             def __str__(self):
    213                 return "string is " + self.x
    214             def __format__(self, format_spec):
    215                 if format_spec == 'd':
    216                     return 'G(' + self.x + ')'
    217                 return object.__format__(self, format_spec)
    218 
    219         # class that returns a bad type from __format__
    220         class H:
    221             def __format__(self, format_spec):
    222                 return 1.0
    223 
    224         class I(datetime.date):
    225             def __format__(self, format_spec):
    226                 return self.strftime(format_spec)
    227 
    228         class J(int):
    229             def __format__(self, format_spec):
    230                 return int.__format__(self * 2, format_spec)
    231 
    232 
    233         self.assertEqual(''.format(), '')
    234         self.assertEqual('abc'.format(), 'abc')
    235         self.assertEqual('{0}'.format('abc'), 'abc')
    236         self.assertEqual('{0:}'.format('abc'), 'abc')
    237         self.assertEqual('X{0}'.format('abc'), 'Xabc')
    238         self.assertEqual('{0}X'.format('abc'), 'abcX')
    239         self.assertEqual('X{0}Y'.format('abc'), 'XabcY')
    240         self.assertEqual('{1}'.format(1, 'abc'), 'abc')
    241         self.assertEqual('X{1}'.format(1, 'abc'), 'Xabc')
    242         self.assertEqual('{1}X'.format(1, 'abc'), 'abcX')
    243         self.assertEqual('X{1}Y'.format(1, 'abc'), 'XabcY')
    244         self.assertEqual('{0}'.format(-15), '-15')
    245         self.assertEqual('{0}{1}'.format(-15, 'abc'), '-15abc')
    246         self.assertEqual('{0}X{1}'.format(-15, 'abc'), '-15Xabc')
    247         self.assertEqual('{{'.format(), '{')
    248         self.assertEqual('}}'.format(), '}')
    249         self.assertEqual('{{}}'.format(), '{}')
    250         self.assertEqual('{{x}}'.format(), '{x}')
    251         self.assertEqual('{{{0}}}'.format(123), '{123}')
    252         self.assertEqual('{{{{0}}}}'.format(), '{{0}}')
    253         self.assertEqual('}}{{'.format(), '}{')
    254         self.assertEqual('}}x{{'.format(), '}x{')
    255 
    256         # weird field names
    257         self.assertEqual("{0[foo-bar]}".format({'foo-bar':'baz'}), 'baz')
    258         self.assertEqual("{0[foo bar]}".format({'foo bar':'baz'}), 'baz')
    259         self.assertEqual("{0[ ]}".format({' ':3}), '3')
    260 
    261         self.assertEqual('{foo._x}'.format(foo=C(20)), '20')
    262         self.assertEqual('{1}{0}'.format(D(10), D(20)), '2010')
    263         self.assertEqual('{0._x.x}'.format(C(D('abc'))), 'abc')
    264         self.assertEqual('{0[0]}'.format(['abc', 'def']), 'abc')
    265         self.assertEqual('{0[1]}'.format(['abc', 'def']), 'def')
    266         self.assertEqual('{0[1][0]}'.format(['abc', ['def']]), 'def')
    267         self.assertEqual('{0[1][0].x}'.format(['abc', [D('def')]]), 'def')
    268 
    269         # strings
    270         self.assertEqual('{0:.3s}'.format('abc'), 'abc')
    271         self.assertEqual('{0:.3s}'.format('ab'), 'ab')
    272         self.assertEqual('{0:.3s}'.format('abcdef'), 'abc')
    273         self.assertEqual('{0:.0s}'.format('abcdef'), '')
    274         self.assertEqual('{0:3.3s}'.format('abc'), 'abc')
    275         self.assertEqual('{0:2.3s}'.format('abc'), 'abc')
    276         self.assertEqual('{0:2.2s}'.format('abc'), 'ab')
    277         self.assertEqual('{0:3.2s}'.format('abc'), 'ab ')
    278         self.assertEqual('{0:x<0s}'.format('result'), 'result')
    279         self.assertEqual('{0:x<5s}'.format('result'), 'result')
    280         self.assertEqual('{0:x<6s}'.format('result'), 'result')
    281         self.assertEqual('{0:x<7s}'.format('result'), 'resultx')
    282         self.assertEqual('{0:x<8s}'.format('result'), 'resultxx')
    283         self.assertEqual('{0: <7s}'.format('result'), 'result ')
    284         self.assertEqual('{0:<7s}'.format('result'), 'result ')
    285         self.assertEqual('{0:>7s}'.format('result'), ' result')
    286         self.assertEqual('{0:>8s}'.format('result'), '  result')
    287         self.assertEqual('{0:^8s}'.format('result'), ' result ')
    288         self.assertEqual('{0:^9s}'.format('result'), ' result  ')
    289         self.assertEqual('{0:^10s}'.format('result'), '  result  ')
    290         self.assertEqual('{0:10000}'.format('a'), 'a' + ' ' * 9999)
    291         self.assertEqual('{0:10000}'.format(''), ' ' * 10000)
    292         self.assertEqual('{0:10000000}'.format(''), ' ' * 10000000)
    293 
    294         # format specifiers for user defined type
    295         self.assertEqual('{0:abc}'.format(C()), 'abc')
    296 
    297         # !r and !s coercions
    298         self.assertEqual('{0!s}'.format('Hello'), 'Hello')
    299         self.assertEqual('{0!s:}'.format('Hello'), 'Hello')
    300         self.assertEqual('{0!s:15}'.format('Hello'), 'Hello          ')
    301         self.assertEqual('{0!s:15s}'.format('Hello'), 'Hello          ')
    302         self.assertEqual('{0!r}'.format('Hello'), "'Hello'")
    303         self.assertEqual('{0!r:}'.format('Hello'), "'Hello'")
    304         self.assertEqual('{0!r}'.format(F('Hello')), 'F(Hello)')
    305 
    306         # test fallback to object.__format__
    307         self.assertEqual('{0}'.format({}), '{}')
    308         self.assertEqual('{0}'.format([]), '[]')
    309         self.assertEqual('{0}'.format([1]), '[1]')
    310         self.assertEqual('{0}'.format(E('data')), 'E(data)')
    311         self.assertEqual('{0:d}'.format(G('data')), 'G(data)')
    312         self.assertEqual('{0!s}'.format(G('data')), 'string is data')
    313 
    314         msg = 'object.__format__ with a non-empty format string is deprecated'
    315         with test_support.check_warnings((msg, PendingDeprecationWarning)):
    316             self.assertEqual('{0:^10}'.format(E('data')), ' E(data)  ')
    317             self.assertEqual('{0:^10s}'.format(E('data')), ' E(data)  ')
    318             self.assertEqual('{0:>15s}'.format(G('data')), ' string is data')
    319 
    320         self.assertEqual("{0:date: %Y-%m-%d}".format(I(year=2007,
    321                                                        month=8,
    322                                                        day=27)),
    323                          "date: 2007-08-27")
    324 
    325         # test deriving from a builtin type and overriding __format__
    326         self.assertEqual("{0}".format(J(10)), "20")
    327 
    328 
    329         # string format specifiers
    330         self.assertEqual('{0:}'.format('a'), 'a')
    331 
    332         # computed format specifiers
    333         self.assertEqual("{0:.{1}}".format('hello world', 5), 'hello')
    334         self.assertEqual("{0:.{1}s}".format('hello world', 5), 'hello')
    335         self.assertEqual("{0:.{precision}s}".format('hello world', precision=5), 'hello')
    336         self.assertEqual("{0:{width}.{precision}s}".format('hello world', width=10, precision=5), 'hello     ')
    337         self.assertEqual("{0:{width}.{precision}s}".format('hello world', width='10', precision='5'), 'hello     ')
    338 
    339         # test various errors
    340         self.assertRaises(ValueError, '{'.format)
    341         self.assertRaises(ValueError, '}'.format)
    342         self.assertRaises(ValueError, 'a{'.format)
    343         self.assertRaises(ValueError, 'a}'.format)
    344         self.assertRaises(ValueError, '{a'.format)
    345         self.assertRaises(ValueError, '}a'.format)
    346         self.assertRaises(IndexError, '{0}'.format)
    347         self.assertRaises(IndexError, '{1}'.format, 'abc')
    348         self.assertRaises(KeyError,   '{x}'.format)
    349         self.assertRaises(ValueError, "}{".format)
    350         self.assertRaises(ValueError, "{".format)
    351         self.assertRaises(ValueError, "}".format)
    352         self.assertRaises(ValueError, "abc{0:{}".format)
    353         self.assertRaises(ValueError, "{0".format)
    354         self.assertRaises(IndexError, "{0.}".format)
    355         self.assertRaises(ValueError, "{0.}".format, 0)
    356         self.assertRaises(IndexError, "{0[}".format)
    357         self.assertRaises(ValueError, "{0[}".format, [])
    358         self.assertRaises(KeyError,   "{0]}".format)
    359         self.assertRaises(ValueError, "{0.[]}".format, 0)
    360         self.assertRaises(ValueError, "{0..foo}".format, 0)
    361         self.assertRaises(ValueError, "{0[0}".format, 0)
    362         self.assertRaises(ValueError, "{0[0:foo}".format, 0)
    363         self.assertRaises(KeyError,   "{c]}".format)
    364         self.assertRaises(ValueError, "{{ {{{0}}".format, 0)
    365         self.assertRaises(ValueError, "{0}}".format, 0)
    366         self.assertRaises(KeyError,   "{foo}".format, bar=3)
    367         self.assertRaises(ValueError, "{0!x}".format, 3)
    368         self.assertRaises(ValueError, "{0!}".format, 0)
    369         self.assertRaises(ValueError, "{0!rs}".format, 0)
    370         self.assertRaises(ValueError, "{!}".format)
    371         self.assertRaises(IndexError, "{:}".format)
    372         self.assertRaises(IndexError, "{:s}".format)
    373         self.assertRaises(IndexError, "{}".format)
    374 
    375         # issue 6089
    376         self.assertRaises(ValueError, "{0[0]x}".format, [None])
    377         self.assertRaises(ValueError, "{0[0](10)}".format, [None])
    378 
    379         # can't have a replacement on the field name portion
    380         self.assertRaises(TypeError, '{0[{1}]}'.format, 'abcdefg', 4)
    381 
    382         # exceed maximum recursion depth
    383         self.assertRaises(ValueError, "{0:{1:{2}}}".format, 'abc', 's', '')
    384         self.assertRaises(ValueError, "{0:{1:{2:{3:{4:{5:{6}}}}}}}".format,
    385                           0, 1, 2, 3, 4, 5, 6, 7)
    386 
    387         # string format spec errors
    388         self.assertRaises(ValueError, "{0:-s}".format, '')
    389         self.assertRaises(ValueError, format, "", "-")
    390         self.assertRaises(ValueError, "{0:=s}".format, '')
    391 
    392     def test_format_huge_precision(self):
    393         format_string = ".{}f".format(sys.maxsize + 1)
    394         with self.assertRaises(ValueError):
    395             result = format(2.34, format_string)
    396 
    397     def test_format_huge_width(self):
    398         format_string = "{}f".format(sys.maxsize + 1)
    399         with self.assertRaises(ValueError):
    400             result = format(2.34, format_string)
    401 
    402     def test_format_huge_item_number(self):
    403         format_string = "{{{}:.6f}}".format(sys.maxsize + 1)
    404         with self.assertRaises(ValueError):
    405             result = format_string.format(2.34)
    406 
    407     def test_format_auto_numbering(self):
    408         class C:
    409             def __init__(self, x=100):
    410                 self._x = x
    411             def __format__(self, spec):
    412                 return spec
    413 
    414         self.assertEqual('{}'.format(10), '10')
    415         self.assertEqual('{:5}'.format('s'), 's    ')
    416         self.assertEqual('{!r}'.format('s'), "'s'")
    417         self.assertEqual('{._x}'.format(C(10)), '10')
    418         self.assertEqual('{[1]}'.format([1, 2]), '2')
    419         self.assertEqual('{[a]}'.format({'a':4, 'b':2}), '4')
    420         self.assertEqual('a{}b{}c'.format(0, 1), 'a0b1c')
    421 
    422         self.assertEqual('a{:{}}b'.format('x', '^10'), 'a    x     b')
    423         self.assertEqual('a{:{}x}b'.format(20, '#'), 'a0x14b')
    424 
    425         # can't mix and match numbering and auto-numbering
    426         self.assertRaises(ValueError, '{}{1}'.format, 1, 2)
    427         self.assertRaises(ValueError, '{1}{}'.format, 1, 2)
    428         self.assertRaises(ValueError, '{:{1}}'.format, 1, 2)
    429         self.assertRaises(ValueError, '{0:{}}'.format, 1, 2)
    430 
    431         # can mix and match auto-numbering and named
    432         self.assertEqual('{f}{}'.format(4, f='test'), 'test4')
    433         self.assertEqual('{}{f}'.format(4, f='test'), '4test')
    434         self.assertEqual('{:{f}}{g}{}'.format(1, 3, g='g', f=2), ' 1g3')
    435         self.assertEqual('{f:{}}{}{g}'.format(2, 4, f=1, g='g'), ' 14g')
    436 
    437     def test_format_c_overflow(self):
    438         # issue #7267
    439         self.assertRaises(OverflowError, '{0:c}'.format, -1)
    440         self.assertRaises(OverflowError, '{0:c}'.format, 256)
    441 
    442     def test_buffer_is_readonly(self):
    443         self.assertRaises(TypeError, sys.stdin.readinto, b"")
    444 
    445     def test_encode_and_decode_kwargs(self):
    446         self.assertEqual('abcde'.encode('ascii', 'replace'),
    447                          'abcde'.encode('ascii', errors='replace'))
    448         self.assertEqual('abcde'.encode('ascii', 'ignore'),
    449                          'abcde'.encode(encoding='ascii', errors='ignore'))
    450         self.assertEqual('Andr\202 x'.decode('ascii', 'ignore'),
    451                          'Andr\202 x'.decode('ascii', errors='ignore'))
    452         self.assertEqual('Andr\202 x'.decode('ascii', 'replace'),
    453                          'Andr\202 x'.decode(encoding='ascii', errors='replace'))
    454 
    455     def test_startswith_endswith_errors(self):
    456         with self.assertRaises(UnicodeDecodeError):
    457             '\xff'.startswith(u'x')
    458         with self.assertRaises(UnicodeDecodeError):
    459             '\xff'.endswith(u'x')
    460         for meth in ('foo'.startswith, 'foo'.endswith):
    461             with self.assertRaises(TypeError) as cm:
    462                 meth(['f'])
    463             exc = str(cm.exception)
    464             self.assertIn('unicode', exc)
    465             self.assertIn('str', exc)
    466             self.assertIn('tuple', exc)
    467 
    468 def test_main():
    469     test_support.run_unittest(StrTest)
    470 
    471 if __name__ == "__main__":
    472     test_main()
    473