1
2import struct
3import sys
4from test import test_support, string_tests
5
6
7class 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
457def test_main():
458    test_support.run_unittest(StrTest)
459
460if __name__ == "__main__":
461    test_main()
462