blob: 774c6346ffb0833910c33d839622909a4ca6d0e9 [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
7class StrTest(
8 string_tests.CommonTest,
9 string_tests.MixinStrUnicodeUserStringTest,
Walter Dörwald57d88e52004-08-26 16:53:04 +000010 string_tests.MixinStrUserStringTest,
11 string_tests.MixinStrUnicodeTest,
Walter Dörwald0fd583c2003-02-21 12:53:50 +000012 ):
13
14 type2test = str
15
16 # We don't need to propagate to str
17 def fixtype(self, obj):
18 return obj
19
Benjamin Peterson979395b2008-05-03 21:35:18 +000020 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
Walter Dörwald43440a62003-03-31 18:07:50 +000034 def test_formatting(self):
35 string_tests.MixinStrUnicodeUserStringTest.test_formatting(self)
36 self.assertRaises(OverflowError, '%c'.__mod__, 0x1234)
37
Mark Dickinson75d36002012-10-28 10:00:46 +000038 @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
Brett Cannonc3647ac2005-04-26 03:45:26 +000050 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
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000101 self.assertTrue(str(Foo0()).startswith("<")) # this is different from __unicode__
Brett Cannonc3647ac2005-04-26 03:45:26 +0000102 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
Zachary Ware1f702212013-12-10 14:09:20 -0600113 # This test only affects 32-bit platforms because expandtabs can only take
114 # an int as the max value, not a 64-bit C long. If expandtabs is changed
115 # to take a 64-bit long, this test should apply to all platforms.
116 @unittest.skipIf(sys.maxint > (1 << 32) or struct.calcsize('P') != 4,
117 'only applies to 32-bit platforms')
Neal Norwitz7dbd2a32007-06-09 03:36:34 +0000118 def test_expandtabs_overflows_gracefully(self):
Neal Norwitz7dbd2a32007-06-09 03:36:34 +0000119 self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxint)
120
Eric Smitha9f7d622008-02-17 19:46:49 +0000121 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
Florent Xicluna60d512c2010-09-13 08:21:43 +0000291 # !r and !s coercions
Eric Smitha9f7d622008-02-17 19:46:49 +0000292 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)')
Eric Smitha9f7d622008-02-17 19:46:49 +0000305 self.assertEqual('{0:d}'.format(G('data')), 'G(data)')
Eric Smitha9f7d622008-02-17 19:46:49 +0000306 self.assertEqual('{0!s}'.format(G('data')), 'string is data')
307
Florent Xicluna60d512c2010-09-13 08:21:43 +0000308 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
Eric Smitha9f7d622008-02-17 19:46:49 +0000314 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)
Eric Smith6f42edb2009-03-14 11:57:26 +0000365 self.assertRaises(IndexError, "{:}".format)
366 self.assertRaises(IndexError, "{:s}".format)
367 self.assertRaises(IndexError, "{}".format)
Eric Smitha9f7d622008-02-17 19:46:49 +0000368
Eric Smith4b94b192009-05-23 13:56:13 +0000369 # issue 6089
370 self.assertRaises(ValueError, "{0[0]x}".format, [None])
371 self.assertRaises(ValueError, "{0[0](10)}".format, [None])
372
Eric Smitha9f7d622008-02-17 19:46:49 +0000373 # 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
Mark Dickinson75d36002012-10-28 10:00:46 +0000386 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
Eric Smith6f42edb2009-03-14 11:57:26 +0000401 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
Victor Stinnere192d0b2015-11-09 12:21:09 +0100431 def test_format_c_overflow(self):
432 # issue #7267
433 self.assertRaises(OverflowError, '{0:c}'.format, -1)
434 self.assertRaises(OverflowError, '{0:c}'.format, 256)
435
Antoine Pitrou92a62402008-08-02 21:58:05 +0000436 def test_buffer_is_readonly(self):
437 self.assertRaises(TypeError, sys.stdin.readinto, b"")
438
Benjamin Peterson332d7212009-09-18 21:14:55 +0000439 def test_encode_and_decode_kwargs(self):
440 self.assertEqual('abcde'.encode('ascii', 'replace'),
441 'abcde'.encode('ascii', errors='replace'))
442 self.assertEqual('abcde'.encode('ascii', 'ignore'),
443 'abcde'.encode(encoding='ascii', errors='ignore'))
444 self.assertEqual('Andr\202 x'.decode('ascii', 'ignore'),
445 'Andr\202 x'.decode('ascii', errors='ignore'))
446 self.assertEqual('Andr\202 x'.decode('ascii', 'replace'),
447 'Andr\202 x'.decode(encoding='ascii', errors='replace'))
448
Ezio Melottie3685f62011-04-26 05:12:51 +0300449 def test_startswith_endswith_errors(self):
450 with self.assertRaises(UnicodeDecodeError):
451 '\xff'.startswith(u'x')
452 with self.assertRaises(UnicodeDecodeError):
453 '\xff'.endswith(u'x')
454 for meth in ('foo'.startswith, 'foo'.endswith):
455 with self.assertRaises(TypeError) as cm:
456 meth(['f'])
457 exc = str(cm.exception)
458 self.assertIn('unicode', exc)
459 self.assertIn('str', exc)
460 self.assertIn('tuple', exc)
Neal Norwitz7dbd2a32007-06-09 03:36:34 +0000461
Walter Dörwald0fd583c2003-02-21 12:53:50 +0000462def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000463 test_support.run_unittest(StrTest)
Walter Dörwald0fd583c2003-02-21 12:53:50 +0000464
465if __name__ == "__main__":
466 test_main()