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     def test_conversion(self):
     39         # Make sure __str__() behaves properly

     40         class Foo0:
     41             def __unicode__(self):
     42                 return u"foo"
     43 
     44         class Foo1:
     45             def __str__(self):
     46                 return "foo"
     47 
     48         class Foo2(object):
     49             def __str__(self):
     50                 return "foo"
     51 
     52         class Foo3(object):
     53             def __str__(self):
     54                 return u"foo"
     55 
     56         class Foo4(unicode):
     57             def __str__(self):
     58                 return u"foo"
     59 
     60         class Foo5(str):
     61             def __str__(self):
     62                 return u"foo"
     63 
     64         class Foo6(str):
     65             def __str__(self):
     66                 return "foos"
     67 
     68             def __unicode__(self):
     69                 return u"foou"
     70 
     71         class Foo7(unicode):
     72             def __str__(self):
     73                 return "foos"
     74             def __unicode__(self):
     75                 return u"foou"
     76 
     77         class Foo8(str):
     78             def __new__(cls, content=""):
     79                 return str.__new__(cls, 2*content)
     80             def __str__(self):
     81                 return self
     82 
     83         class Foo9(str):
     84             def __str__(self):
     85                 return "string"
     86             def __unicode__(self):
     87                 return "not unicode"
     88 
     89         self.assertTrue(str(Foo0()).startswith("<")) # this is different from __unicode__

     90         self.assertEqual(str(Foo1()), "foo")
     91         self.assertEqual(str(Foo2()), "foo")
     92         self.assertEqual(str(Foo3()), "foo")
     93         self.assertEqual(str(Foo4("bar")), "foo")
     94         self.assertEqual(str(Foo5("bar")), "foo")
     95         self.assertEqual(str(Foo6("bar")), "foos")
     96         self.assertEqual(str(Foo7("bar")), "foos")
     97         self.assertEqual(str(Foo8("foo")), "foofoo")
     98         self.assertEqual(str(Foo9("foo")), "string")
     99         self.assertEqual(unicode(Foo9("foo")), u"not unicode")
    100 
    101     def test_expandtabs_overflows_gracefully(self):
    102         # This test only affects 32-bit platforms because expandtabs can only take

    103         # an int as the max value, not a 64-bit C long.  If expandtabs is changed

    104         # to take a 64-bit long, this test should apply to all platforms.

    105         if sys.maxint > (1 << 32) or struct.calcsize('P') != 4:
    106             return
    107         self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxint)
    108 
    109     def test__format__(self):
    110         def test(value, format, expected):
    111             # test both with and without the trailing 's'

    112             self.assertEqual(value.__format__(format), expected)
    113             self.assertEqual(value.__format__(format + 's'), expected)
    114 
    115         test('', '', '')
    116         test('abc', '', 'abc')
    117         test('abc', '.3', 'abc')
    118         test('ab', '.3', 'ab')
    119         test('abcdef', '.3', 'abc')
    120         test('abcdef', '.0', '')
    121         test('abc', '3.3', 'abc')
    122         test('abc', '2.3', 'abc')
    123         test('abc', '2.2', 'ab')
    124         test('abc', '3.2', 'ab ')
    125         test('result', 'x<0', 'result')
    126         test('result', 'x<5', 'result')
    127         test('result', 'x<6', 'result')
    128         test('result', 'x<7', 'resultx')
    129         test('result', 'x<8', 'resultxx')
    130         test('result', ' <7', 'result ')
    131         test('result', '<7', 'result ')
    132         test('result', '>7', ' result')
    133         test('result', '>8', '  result')
    134         test('result', '^8', ' result ')
    135         test('result', '^9', ' result  ')
    136         test('result', '^10', '  result  ')
    137         test('a', '10000', 'a' + ' ' * 9999)
    138         test('', '10000', ' ' * 10000)
    139         test('', '10000000', ' ' * 10000000)
    140 
    141     def test_format(self):
    142         self.assertEqual(''.format(), '')
    143         self.assertEqual('a'.format(), 'a')
    144         self.assertEqual('ab'.format(), 'ab')
    145         self.assertEqual('a{{'.format(), 'a{')
    146         self.assertEqual('a}}'.format(), 'a}')
    147         self.assertEqual('{{b'.format(), '{b')
    148         self.assertEqual('}}b'.format(), '}b')
    149         self.assertEqual('a{{b'.format(), 'a{b')
    150 
    151         # examples from the PEP:

    152         import datetime
    153         self.assertEqual("My name is {0}".format('Fred'), "My name is Fred")
    154         self.assertEqual("My name is {0[name]}".format(dict(name='Fred')),
    155                          "My name is Fred")
    156         self.assertEqual("My name is {0} :-{{}}".format('Fred'),
    157                          "My name is Fred :-{}")
    158 
    159         d = datetime.date(2007, 8, 18)
    160         self.assertEqual("The year is {0.year}".format(d),
    161                          "The year is 2007")
    162 
    163         # classes we'll use for testing

    164         class C:
    165             def __init__(self, x=100):
    166                 self._x = x
    167             def __format__(self, spec):
    168                 return spec
    169 
    170         class D:
    171             def __init__(self, x):
    172                 self.x = x
    173             def __format__(self, spec):
    174                 return str(self.x)
    175 
    176         # class with __str__, but no __format__

    177         class E:
    178             def __init__(self, x):
    179                 self.x = x
    180             def __str__(self):
    181                 return 'E(' + self.x + ')'
    182 
    183         # class with __repr__, but no __format__ or __str__

    184         class F:
    185             def __init__(self, x):
    186                 self.x = x
    187             def __repr__(self):
    188                 return 'F(' + self.x + ')'
    189 
    190         # class with __format__ that forwards to string, for some format_spec's

    191         class G:
    192             def __init__(self, x):
    193                 self.x = x
    194             def __str__(self):
    195                 return "string is " + self.x
    196             def __format__(self, format_spec):
    197                 if format_spec == 'd':
    198                     return 'G(' + self.x + ')'
    199                 return object.__format__(self, format_spec)
    200 
    201         # class that returns a bad type from __format__

    202         class H:
    203             def __format__(self, format_spec):
    204                 return 1.0
    205 
    206         class I(datetime.date):
    207             def __format__(self, format_spec):
    208                 return self.strftime(format_spec)
    209 
    210         class J(int):
    211             def __format__(self, format_spec):
    212                 return int.__format__(self * 2, format_spec)
    213 
    214 
    215         self.assertEqual(''.format(), '')
    216         self.assertEqual('abc'.format(), 'abc')
    217         self.assertEqual('{0}'.format('abc'), 'abc')
    218         self.assertEqual('{0:}'.format('abc'), 'abc')
    219         self.assertEqual('X{0}'.format('abc'), 'Xabc')
    220         self.assertEqual('{0}X'.format('abc'), 'abcX')
    221         self.assertEqual('X{0}Y'.format('abc'), 'XabcY')
    222         self.assertEqual('{1}'.format(1, 'abc'), 'abc')
    223         self.assertEqual('X{1}'.format(1, 'abc'), 'Xabc')
    224         self.assertEqual('{1}X'.format(1, 'abc'), 'abcX')
    225         self.assertEqual('X{1}Y'.format(1, 'abc'), 'XabcY')
    226         self.assertEqual('{0}'.format(-15), '-15')
    227         self.assertEqual('{0}{1}'.format(-15, 'abc'), '-15abc')
    228         self.assertEqual('{0}X{1}'.format(-15, 'abc'), '-15Xabc')
    229         self.assertEqual('{{'.format(), '{')
    230         self.assertEqual('}}'.format(), '}')
    231         self.assertEqual('{{}}'.format(), '{}')
    232         self.assertEqual('{{x}}'.format(), '{x}')
    233         self.assertEqual('{{{0}}}'.format(123), '{123}')
    234         self.assertEqual('{{{{0}}}}'.format(), '{{0}}')
    235         self.assertEqual('}}{{'.format(), '}{')
    236         self.assertEqual('}}x{{'.format(), '}x{')
    237 
    238         # weird field names

    239         self.assertEqual("{0[foo-bar]}".format({'foo-bar':'baz'}), 'baz')
    240         self.assertEqual("{0[foo bar]}".format({'foo bar':'baz'}), 'baz')
    241         self.assertEqual("{0[ ]}".format({' ':3}), '3')
    242 
    243         self.assertEqual('{foo._x}'.format(foo=C(20)), '20')
    244         self.assertEqual('{1}{0}'.format(D(10), D(20)), '2010')
    245         self.assertEqual('{0._x.x}'.format(C(D('abc'))), 'abc')
    246         self.assertEqual('{0[0]}'.format(['abc', 'def']), 'abc')
    247         self.assertEqual('{0[1]}'.format(['abc', 'def']), 'def')
    248         self.assertEqual('{0[1][0]}'.format(['abc', ['def']]), 'def')
    249         self.assertEqual('{0[1][0].x}'.format(['abc', [D('def')]]), 'def')
    250 
    251         # strings

    252         self.assertEqual('{0:.3s}'.format('abc'), 'abc')
    253         self.assertEqual('{0:.3s}'.format('ab'), 'ab')
    254         self.assertEqual('{0:.3s}'.format('abcdef'), 'abc')
    255         self.assertEqual('{0:.0s}'.format('abcdef'), '')
    256         self.assertEqual('{0:3.3s}'.format('abc'), 'abc')
    257         self.assertEqual('{0:2.3s}'.format('abc'), 'abc')
    258         self.assertEqual('{0:2.2s}'.format('abc'), 'ab')
    259         self.assertEqual('{0:3.2s}'.format('abc'), 'ab ')
    260         self.assertEqual('{0:x<0s}'.format('result'), 'result')
    261         self.assertEqual('{0:x<5s}'.format('result'), 'result')
    262         self.assertEqual('{0:x<6s}'.format('result'), 'result')
    263         self.assertEqual('{0:x<7s}'.format('result'), 'resultx')
    264         self.assertEqual('{0:x<8s}'.format('result'), 'resultxx')
    265         self.assertEqual('{0: <7s}'.format('result'), 'result ')
    266         self.assertEqual('{0:<7s}'.format('result'), 'result ')
    267         self.assertEqual('{0:>7s}'.format('result'), ' result')
    268         self.assertEqual('{0:>8s}'.format('result'), '  result')
    269         self.assertEqual('{0:^8s}'.format('result'), ' result ')
    270         self.assertEqual('{0:^9s}'.format('result'), ' result  ')
    271         self.assertEqual('{0:^10s}'.format('result'), '  result  ')
    272         self.assertEqual('{0:10000}'.format('a'), 'a' + ' ' * 9999)
    273         self.assertEqual('{0:10000}'.format(''), ' ' * 10000)
    274         self.assertEqual('{0:10000000}'.format(''), ' ' * 10000000)
    275 
    276         # format specifiers for user defined type

    277         self.assertEqual('{0:abc}'.format(C()), 'abc')
    278 
    279         # !r and !s coercions

    280         self.assertEqual('{0!s}'.format('Hello'), 'Hello')
    281         self.assertEqual('{0!s:}'.format('Hello'), 'Hello')
    282         self.assertEqual('{0!s:15}'.format('Hello'), 'Hello          ')
    283         self.assertEqual('{0!s:15s}'.format('Hello'), 'Hello          ')
    284         self.assertEqual('{0!r}'.format('Hello'), "'Hello'")
    285         self.assertEqual('{0!r:}'.format('Hello'), "'Hello'")
    286         self.assertEqual('{0!r}'.format(F('Hello')), 'F(Hello)')
    287 
    288         # test fallback to object.__format__

    289         self.assertEqual('{0}'.format({}), '{}')
    290         self.assertEqual('{0}'.format([]), '[]')
    291         self.assertEqual('{0}'.format([1]), '[1]')
    292         self.assertEqual('{0}'.format(E('data')), 'E(data)')
    293         self.assertEqual('{0:d}'.format(G('data')), 'G(data)')
    294         self.assertEqual('{0!s}'.format(G('data')), 'string is data')
    295 
    296         msg = 'object.__format__ with a non-empty format string is deprecated'
    297         with test_support.check_warnings((msg, PendingDeprecationWarning)):
    298             self.assertEqual('{0:^10}'.format(E('data')), ' E(data)  ')
    299             self.assertEqual('{0:^10s}'.format(E('data')), ' E(data)  ')
    300             self.assertEqual('{0:>15s}'.format(G('data')), ' string is data')
    301 
    302         self.assertEqual("{0:date: %Y-%m-%d}".format(I(year=2007,
    303                                                        month=8,
    304                                                        day=27)),
    305                          "date: 2007-08-27")
    306 
    307         # test deriving from a builtin type and overriding __format__

    308         self.assertEqual("{0}".format(J(10)), "20")
    309 
    310 
    311         # string format specifiers

    312         self.assertEqual('{0:}'.format('a'), 'a')
    313 
    314         # computed format specifiers

    315         self.assertEqual("{0:.{1}}".format('hello world', 5), 'hello')
    316         self.assertEqual("{0:.{1}s}".format('hello world', 5), 'hello')
    317         self.assertEqual("{0:.{precision}s}".format('hello world', precision=5), 'hello')
    318         self.assertEqual("{0:{width}.{precision}s}".format('hello world', width=10, precision=5), 'hello     ')
    319         self.assertEqual("{0:{width}.{precision}s}".format('hello world', width='10', precision='5'), 'hello     ')
    320 
    321         # test various errors

    322         self.assertRaises(ValueError, '{'.format)
    323         self.assertRaises(ValueError, '}'.format)
    324         self.assertRaises(ValueError, 'a{'.format)
    325         self.assertRaises(ValueError, 'a}'.format)
    326         self.assertRaises(ValueError, '{a'.format)
    327         self.assertRaises(ValueError, '}a'.format)
    328         self.assertRaises(IndexError, '{0}'.format)
    329         self.assertRaises(IndexError, '{1}'.format, 'abc')
    330         self.assertRaises(KeyError,   '{x}'.format)
    331         self.assertRaises(ValueError, "}{".format)
    332         self.assertRaises(ValueError, "{".format)
    333         self.assertRaises(ValueError, "}".format)
    334         self.assertRaises(ValueError, "abc{0:{}".format)
    335         self.assertRaises(ValueError, "{0".format)
    336         self.assertRaises(IndexError, "{0.}".format)
    337         self.assertRaises(ValueError, "{0.}".format, 0)
    338         self.assertRaises(IndexError, "{0[}".format)
    339         self.assertRaises(ValueError, "{0[}".format, [])
    340         self.assertRaises(KeyError,   "{0]}".format)
    341         self.assertRaises(ValueError, "{0.[]}".format, 0)
    342         self.assertRaises(ValueError, "{0..foo}".format, 0)
    343         self.assertRaises(ValueError, "{0[0}".format, 0)
    344         self.assertRaises(ValueError, "{0[0:foo}".format, 0)
    345         self.assertRaises(KeyError,   "{c]}".format)
    346         self.assertRaises(ValueError, "{{ {{{0}}".format, 0)
    347         self.assertRaises(ValueError, "{0}}".format, 0)
    348         self.assertRaises(KeyError,   "{foo}".format, bar=3)
    349         self.assertRaises(ValueError, "{0!x}".format, 3)
    350         self.assertRaises(ValueError, "{0!}".format, 0)
    351         self.assertRaises(ValueError, "{0!rs}".format, 0)
    352         self.assertRaises(ValueError, "{!}".format)
    353         self.assertRaises(IndexError, "{:}".format)
    354         self.assertRaises(IndexError, "{:s}".format)
    355         self.assertRaises(IndexError, "{}".format)
    356 
    357         # issue 6089

    358         self.assertRaises(ValueError, "{0[0]x}".format, [None])
    359         self.assertRaises(ValueError, "{0[0](10)}".format, [None])
    360 
    361         # can't have a replacement on the field name portion

    362         self.assertRaises(TypeError, '{0[{1}]}'.format, 'abcdefg', 4)
    363 
    364         # exceed maximum recursion depth

    365         self.assertRaises(ValueError, "{0:{1:{2}}}".format, 'abc', 's', '')
    366         self.assertRaises(ValueError, "{0:{1:{2:{3:{4:{5:{6}}}}}}}".format,
    367                           0, 1, 2, 3, 4, 5, 6, 7)
    368 
    369         # string format spec errors

    370         self.assertRaises(ValueError, "{0:-s}".format, '')
    371         self.assertRaises(ValueError, format, "", "-")
    372         self.assertRaises(ValueError, "{0:=s}".format, '')
    373 
    374     def test_format_auto_numbering(self):
    375         class C:
    376             def __init__(self, x=100):
    377                 self._x = x
    378             def __format__(self, spec):
    379                 return spec
    380 
    381         self.assertEqual('{}'.format(10), '10')
    382         self.assertEqual('{:5}'.format('s'), 's    ')
    383         self.assertEqual('{!r}'.format('s'), "'s'")
    384         self.assertEqual('{._x}'.format(C(10)), '10')
    385         self.assertEqual('{[1]}'.format([1, 2]), '2')
    386         self.assertEqual('{[a]}'.format({'a':4, 'b':2}), '4')
    387         self.assertEqual('a{}b{}c'.format(0, 1), 'a0b1c')
    388 
    389         self.assertEqual('a{:{}}b'.format('x', '^10'), 'a    x     b')
    390         self.assertEqual('a{:{}x}b'.format(20, '#'), 'a0x14b')
    391 
    392         # can't mix and match numbering and auto-numbering

    393         self.assertRaises(ValueError, '{}{1}'.format, 1, 2)
    394         self.assertRaises(ValueError, '{1}{}'.format, 1, 2)
    395         self.assertRaises(ValueError, '{:{1}}'.format, 1, 2)
    396         self.assertRaises(ValueError, '{0:{}}'.format, 1, 2)
    397 
    398         # can mix and match auto-numbering and named

    399         self.assertEqual('{f}{}'.format(4, f='test'), 'test4')
    400         self.assertEqual('{}{f}'.format(4, f='test'), '4test')
    401         self.assertEqual('{:{f}}{g}{}'.format(1, 3, g='g', f=2), ' 1g3')
    402         self.assertEqual('{f:{}}{}{g}'.format(2, 4, f=1, g='g'), ' 14g')
    403 
    404     def test_buffer_is_readonly(self):
    405         self.assertRaises(TypeError, sys.stdin.readinto, b"")
    406 
    407     def test_encode_and_decode_kwargs(self):
    408         self.assertEqual('abcde'.encode('ascii', 'replace'),
    409                          'abcde'.encode('ascii', errors='replace'))
    410         self.assertEqual('abcde'.encode('ascii', 'ignore'),
    411                          'abcde'.encode(encoding='ascii', errors='ignore'))
    412         self.assertEqual('Andr\202 x'.decode('ascii', 'ignore'),
    413                          'Andr\202 x'.decode('ascii', errors='ignore'))
    414         self.assertEqual('Andr\202 x'.decode('ascii', 'replace'),
    415                          'Andr\202 x'.decode(encoding='ascii', errors='replace'))
    416 
    417     def test_startswith_endswith_errors(self):
    418         with self.assertRaises(UnicodeDecodeError):
    419             '\xff'.startswith(u'x')
    420         with self.assertRaises(UnicodeDecodeError):
    421             '\xff'.endswith(u'x')
    422         for meth in ('foo'.startswith, 'foo'.endswith):
    423             with self.assertRaises(TypeError) as cm:
    424                 meth(['f'])
    425             exc = str(cm.exception)
    426             self.assertIn('unicode', exc)
    427             self.assertIn('str', exc)
    428             self.assertIn('tuple', exc)
    429 
    430 def test_main():
    431     test_support.run_unittest(StrTest)
    432 
    433 if __name__ == "__main__":
    434     test_main()
    435