blob: 5bb9f4867bcb0e888910c5eedfc0849840d3557f [file] [log] [blame]
Zachary Ware1f702212013-12-10 14:09:20 -06001import unittest
Neal Norwitzba965de2007-06-11 02:14:39 +00002import struct
Neal Norwitz7dbd2a32007-06-09 03:36:34 +00003import sys
Walter Dörwald0fd583c2003-02-21 12:53:50 +00004from test import test_support, string_tests
5
6
Serhiy Storchaka8d30ad72015-11-25 15:55:54 +02007class StrSubclass(str):
8 pass
9
Walter Dörwald0fd583c2003-02-21 12:53:50 +000010class StrTest(
11 string_tests.CommonTest,
12 string_tests.MixinStrUnicodeUserStringTest,
Walter Dörwald57d88e52004-08-26 16:53:04 +000013 string_tests.MixinStrUserStringTest,
14 string_tests.MixinStrUnicodeTest,
Walter Dörwald0fd583c2003-02-21 12:53:50 +000015 ):
16
17 type2test = str
18
19 # We don't need to propagate to str
20 def fixtype(self, obj):
21 return obj
22
Benjamin Peterson979395b2008-05-03 21:35:18 +000023 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
Walter Dörwald43440a62003-03-31 18:07:50 +000037 def test_formatting(self):
38 string_tests.MixinStrUnicodeUserStringTest.test_formatting(self)
39 self.assertRaises(OverflowError, '%c'.__mod__, 0x1234)
40
Mark Dickinson75d36002012-10-28 10:00:46 +000041 @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
Brett Cannonc3647ac2005-04-26 03:45:26 +000053 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
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000104 self.assertTrue(str(Foo0()).startswith("<")) # this is different from __unicode__
Brett Cannonc3647ac2005-04-26 03:45:26 +0000105 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")
Serhiy Storchaka8d30ad72015-11-25 15:55:54 +0200113 self.assertIs(type(str(Foo8("foo"))), Foo8)
114 self.assertEqual(StrSubclass(Foo8("foo")), "foofoo")
115 self.assertIs(type(StrSubclass(Foo8("foo"))), StrSubclass)
Brett Cannonc3647ac2005-04-26 03:45:26 +0000116 self.assertEqual(str(Foo9("foo")), "string")
117 self.assertEqual(unicode(Foo9("foo")), u"not unicode")
118
Zachary Ware1f702212013-12-10 14:09:20 -0600119 # 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')
Neal Norwitz7dbd2a32007-06-09 03:36:34 +0000124 def test_expandtabs_overflows_gracefully(self):
Neal Norwitz7dbd2a32007-06-09 03:36:34 +0000125 self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxint)
126
Eric Smitha9f7d622008-02-17 19:46:49 +0000127 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
Florent Xicluna60d512c2010-09-13 08:21:43 +0000297 # !r and !s coercions
Eric Smitha9f7d622008-02-17 19:46:49 +0000298 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)')
Eric Smitha9f7d622008-02-17 19:46:49 +0000311 self.assertEqual('{0:d}'.format(G('data')), 'G(data)')
Eric Smitha9f7d622008-02-17 19:46:49 +0000312 self.assertEqual('{0!s}'.format(G('data')), 'string is data')
313
Florent Xicluna60d512c2010-09-13 08:21:43 +0000314 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
Eric Smitha9f7d622008-02-17 19:46:49 +0000320 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)
Eric Smith6f42edb2009-03-14 11:57:26 +0000371 self.assertRaises(IndexError, "{:}".format)
372 self.assertRaises(IndexError, "{:s}".format)
373 self.assertRaises(IndexError, "{}".format)
Eric Smitha9f7d622008-02-17 19:46:49 +0000374
Eric Smith4b94b192009-05-23 13:56:13 +0000375 # issue 6089
376 self.assertRaises(ValueError, "{0[0]x}".format, [None])
377 self.assertRaises(ValueError, "{0[0](10)}".format, [None])
378
Eric Smitha9f7d622008-02-17 19:46:49 +0000379 # 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
Mark Dickinson75d36002012-10-28 10:00:46 +0000392 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
Eric Smith6f42edb2009-03-14 11:57:26 +0000407 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
Victor Stinnere192d0b2015-11-09 12:21:09 +0100437 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
Antoine Pitrou92a62402008-08-02 21:58:05 +0000442 def test_buffer_is_readonly(self):
443 self.assertRaises(TypeError, sys.stdin.readinto, b"")
444
Benjamin Peterson332d7212009-09-18 21:14:55 +0000445 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
Ezio Melottie3685f62011-04-26 05:12:51 +0300455 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)
Neal Norwitz7dbd2a32007-06-09 03:36:34 +0000467
Walter Dörwald0fd583c2003-02-21 12:53:50 +0000468def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000469 test_support.run_unittest(StrTest)
Walter Dörwald0fd583c2003-02-21 12:53:50 +0000470
471if __name__ == "__main__":
472 test_main()