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