blob: 37db252a27f74770bc30a1e18feefdb108ace386 [file] [log] [blame]
Neal Norwitz7dbd2a32007-06-09 03:36:34 +00001
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
Walter Dörwald43440a62003-03-31 18:07:50 +000020 def test_formatting(self):
21 string_tests.MixinStrUnicodeUserStringTest.test_formatting(self)
22 self.assertRaises(OverflowError, '%c'.__mod__, 0x1234)
23
Brett Cannonc3647ac2005-04-26 03:45:26 +000024 def test_conversion(self):
25 # Make sure __str__() behaves properly
26 class Foo0:
27 def __unicode__(self):
28 return u"foo"
29
30 class Foo1:
31 def __str__(self):
32 return "foo"
33
34 class Foo2(object):
35 def __str__(self):
36 return "foo"
37
38 class Foo3(object):
39 def __str__(self):
40 return u"foo"
41
42 class Foo4(unicode):
43 def __str__(self):
44 return u"foo"
45
46 class Foo5(str):
47 def __str__(self):
48 return u"foo"
49
50 class Foo6(str):
51 def __str__(self):
52 return "foos"
53
54 def __unicode__(self):
55 return u"foou"
56
57 class Foo7(unicode):
58 def __str__(self):
59 return "foos"
60 def __unicode__(self):
61 return u"foou"
62
63 class Foo8(str):
64 def __new__(cls, content=""):
65 return str.__new__(cls, 2*content)
66 def __str__(self):
67 return self
68
69 class Foo9(str):
70 def __str__(self):
71 return "string"
72 def __unicode__(self):
73 return "not unicode"
74
75 self.assert_(str(Foo0()).startswith("<")) # this is different from __unicode__
76 self.assertEqual(str(Foo1()), "foo")
77 self.assertEqual(str(Foo2()), "foo")
78 self.assertEqual(str(Foo3()), "foo")
79 self.assertEqual(str(Foo4("bar")), "foo")
80 self.assertEqual(str(Foo5("bar")), "foo")
81 self.assertEqual(str(Foo6("bar")), "foos")
82 self.assertEqual(str(Foo7("bar")), "foos")
83 self.assertEqual(str(Foo8("foo")), "foofoo")
84 self.assertEqual(str(Foo9("foo")), "string")
85 self.assertEqual(unicode(Foo9("foo")), u"not unicode")
86
Neal Norwitz7dbd2a32007-06-09 03:36:34 +000087 def test_expandtabs_overflows_gracefully(self):
88 # This test only affects 32-bit platforms because expandtabs can only take
89 # an int as the max value, not a 64-bit C long. If expandtabs is changed
90 # to take a 64-bit long, this test should apply to all platforms.
Neal Norwitzba965de2007-06-11 02:14:39 +000091 if sys.maxint > (1 << 32) or struct.calcsize('P') != 4:
Neal Norwitz7dbd2a32007-06-09 03:36:34 +000092 return
93 self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxint)
94
Eric Smitha9f7d622008-02-17 19:46:49 +000095 def test__format__(self):
96 def test(value, format, expected):
97 # test both with and without the trailing 's'
98 self.assertEqual(value.__format__(format), expected)
99 self.assertEqual(value.__format__(format + 's'), expected)
100
101 test('', '', '')
102 test('abc', '', 'abc')
103 test('abc', '.3', 'abc')
104 test('ab', '.3', 'ab')
105 test('abcdef', '.3', 'abc')
106 test('abcdef', '.0', '')
107 test('abc', '3.3', 'abc')
108 test('abc', '2.3', 'abc')
109 test('abc', '2.2', 'ab')
110 test('abc', '3.2', 'ab ')
111 test('result', 'x<0', 'result')
112 test('result', 'x<5', 'result')
113 test('result', 'x<6', 'result')
114 test('result', 'x<7', 'resultx')
115 test('result', 'x<8', 'resultxx')
116 test('result', ' <7', 'result ')
117 test('result', '<7', 'result ')
118 test('result', '>7', ' result')
119 test('result', '>8', ' result')
120 test('result', '^8', ' result ')
121 test('result', '^9', ' result ')
122 test('result', '^10', ' result ')
123 test('a', '10000', 'a' + ' ' * 9999)
124 test('', '10000', ' ' * 10000)
125 test('', '10000000', ' ' * 10000000)
126
127 def test_format(self):
128 self.assertEqual(''.format(), '')
129 self.assertEqual('a'.format(), 'a')
130 self.assertEqual('ab'.format(), 'ab')
131 self.assertEqual('a{{'.format(), 'a{')
132 self.assertEqual('a}}'.format(), 'a}')
133 self.assertEqual('{{b'.format(), '{b')
134 self.assertEqual('}}b'.format(), '}b')
135 self.assertEqual('a{{b'.format(), 'a{b')
136
137 # examples from the PEP:
138 import datetime
139 self.assertEqual("My name is {0}".format('Fred'), "My name is Fred")
140 self.assertEqual("My name is {0[name]}".format(dict(name='Fred')),
141 "My name is Fred")
142 self.assertEqual("My name is {0} :-{{}}".format('Fred'),
143 "My name is Fred :-{}")
144
145 d = datetime.date(2007, 8, 18)
146 self.assertEqual("The year is {0.year}".format(d),
147 "The year is 2007")
148
149 # classes we'll use for testing
150 class C:
151 def __init__(self, x=100):
152 self._x = x
153 def __format__(self, spec):
154 return spec
155
156 class D:
157 def __init__(self, x):
158 self.x = x
159 def __format__(self, spec):
160 return str(self.x)
161
162 # class with __str__, but no __format__
163 class E:
164 def __init__(self, x):
165 self.x = x
166 def __str__(self):
167 return 'E(' + self.x + ')'
168
169 # class with __repr__, but no __format__ or __str__
170 class F:
171 def __init__(self, x):
172 self.x = x
173 def __repr__(self):
174 return 'F(' + self.x + ')'
175
176 # class with __format__ that forwards to string, for some format_spec's
177 class G:
178 def __init__(self, x):
179 self.x = x
180 def __str__(self):
181 return "string is " + self.x
182 def __format__(self, format_spec):
183 if format_spec == 'd':
184 return 'G(' + self.x + ')'
185 return object.__format__(self, format_spec)
186
187 # class that returns a bad type from __format__
188 class H:
189 def __format__(self, format_spec):
190 return 1.0
191
192 class I(datetime.date):
193 def __format__(self, format_spec):
194 return self.strftime(format_spec)
195
196 class J(int):
197 def __format__(self, format_spec):
198 return int.__format__(self * 2, format_spec)
199
200
201 self.assertEqual(''.format(), '')
202 self.assertEqual('abc'.format(), 'abc')
203 self.assertEqual('{0}'.format('abc'), 'abc')
204 self.assertEqual('{0:}'.format('abc'), 'abc')
205 self.assertEqual('X{0}'.format('abc'), 'Xabc')
206 self.assertEqual('{0}X'.format('abc'), 'abcX')
207 self.assertEqual('X{0}Y'.format('abc'), 'XabcY')
208 self.assertEqual('{1}'.format(1, 'abc'), 'abc')
209 self.assertEqual('X{1}'.format(1, 'abc'), 'Xabc')
210 self.assertEqual('{1}X'.format(1, 'abc'), 'abcX')
211 self.assertEqual('X{1}Y'.format(1, 'abc'), 'XabcY')
212 self.assertEqual('{0}'.format(-15), '-15')
213 self.assertEqual('{0}{1}'.format(-15, 'abc'), '-15abc')
214 self.assertEqual('{0}X{1}'.format(-15, 'abc'), '-15Xabc')
215 self.assertEqual('{{'.format(), '{')
216 self.assertEqual('}}'.format(), '}')
217 self.assertEqual('{{}}'.format(), '{}')
218 self.assertEqual('{{x}}'.format(), '{x}')
219 self.assertEqual('{{{0}}}'.format(123), '{123}')
220 self.assertEqual('{{{{0}}}}'.format(), '{{0}}')
221 self.assertEqual('}}{{'.format(), '}{')
222 self.assertEqual('}}x{{'.format(), '}x{')
223
224 # weird field names
225 self.assertEqual("{0[foo-bar]}".format({'foo-bar':'baz'}), 'baz')
226 self.assertEqual("{0[foo bar]}".format({'foo bar':'baz'}), 'baz')
227 self.assertEqual("{0[ ]}".format({' ':3}), '3')
228
229 self.assertEqual('{foo._x}'.format(foo=C(20)), '20')
230 self.assertEqual('{1}{0}'.format(D(10), D(20)), '2010')
231 self.assertEqual('{0._x.x}'.format(C(D('abc'))), 'abc')
232 self.assertEqual('{0[0]}'.format(['abc', 'def']), 'abc')
233 self.assertEqual('{0[1]}'.format(['abc', 'def']), 'def')
234 self.assertEqual('{0[1][0]}'.format(['abc', ['def']]), 'def')
235 self.assertEqual('{0[1][0].x}'.format(['abc', [D('def')]]), 'def')
236
237 # strings
238 self.assertEqual('{0:.3s}'.format('abc'), 'abc')
239 self.assertEqual('{0:.3s}'.format('ab'), 'ab')
240 self.assertEqual('{0:.3s}'.format('abcdef'), 'abc')
241 self.assertEqual('{0:.0s}'.format('abcdef'), '')
242 self.assertEqual('{0:3.3s}'.format('abc'), 'abc')
243 self.assertEqual('{0:2.3s}'.format('abc'), 'abc')
244 self.assertEqual('{0:2.2s}'.format('abc'), 'ab')
245 self.assertEqual('{0:3.2s}'.format('abc'), 'ab ')
246 self.assertEqual('{0:x<0s}'.format('result'), 'result')
247 self.assertEqual('{0:x<5s}'.format('result'), 'result')
248 self.assertEqual('{0:x<6s}'.format('result'), 'result')
249 self.assertEqual('{0:x<7s}'.format('result'), 'resultx')
250 self.assertEqual('{0:x<8s}'.format('result'), 'resultxx')
251 self.assertEqual('{0: <7s}'.format('result'), 'result ')
252 self.assertEqual('{0:<7s}'.format('result'), 'result ')
253 self.assertEqual('{0:>7s}'.format('result'), ' result')
254 self.assertEqual('{0:>8s}'.format('result'), ' result')
255 self.assertEqual('{0:^8s}'.format('result'), ' result ')
256 self.assertEqual('{0:^9s}'.format('result'), ' result ')
257 self.assertEqual('{0:^10s}'.format('result'), ' result ')
258 self.assertEqual('{0:10000}'.format('a'), 'a' + ' ' * 9999)
259 self.assertEqual('{0:10000}'.format(''), ' ' * 10000)
260 self.assertEqual('{0:10000000}'.format(''), ' ' * 10000000)
261
262 # format specifiers for user defined type
263 self.assertEqual('{0:abc}'.format(C()), 'abc')
264
265 # !r and !s coersions
266 self.assertEqual('{0!s}'.format('Hello'), 'Hello')
267 self.assertEqual('{0!s:}'.format('Hello'), 'Hello')
268 self.assertEqual('{0!s:15}'.format('Hello'), 'Hello ')
269 self.assertEqual('{0!s:15s}'.format('Hello'), 'Hello ')
270 self.assertEqual('{0!r}'.format('Hello'), "'Hello'")
271 self.assertEqual('{0!r:}'.format('Hello'), "'Hello'")
272 self.assertEqual('{0!r}'.format(F('Hello')), 'F(Hello)')
273
274 # test fallback to object.__format__
275 self.assertEqual('{0}'.format({}), '{}')
276 self.assertEqual('{0}'.format([]), '[]')
277 self.assertEqual('{0}'.format([1]), '[1]')
278 self.assertEqual('{0}'.format(E('data')), 'E(data)')
279 self.assertEqual('{0:^10}'.format(E('data')), ' E(data) ')
280 self.assertEqual('{0:^10s}'.format(E('data')), ' E(data) ')
281 self.assertEqual('{0:d}'.format(G('data')), 'G(data)')
282 self.assertEqual('{0:>15s}'.format(G('data')), ' string is data')
283 self.assertEqual('{0!s}'.format(G('data')), 'string is data')
284
285 self.assertEqual("{0:date: %Y-%m-%d}".format(I(year=2007,
286 month=8,
287 day=27)),
288 "date: 2007-08-27")
289
290 # test deriving from a builtin type and overriding __format__
291 self.assertEqual("{0}".format(J(10)), "20")
292
293
294 # string format specifiers
295 self.assertEqual('{0:}'.format('a'), 'a')
296
297 # computed format specifiers
298 self.assertEqual("{0:.{1}}".format('hello world', 5), 'hello')
299 self.assertEqual("{0:.{1}s}".format('hello world', 5), 'hello')
300 self.assertEqual("{0:.{precision}s}".format('hello world', precision=5), 'hello')
301 self.assertEqual("{0:{width}.{precision}s}".format('hello world', width=10, precision=5), 'hello ')
302 self.assertEqual("{0:{width}.{precision}s}".format('hello world', width='10', precision='5'), 'hello ')
303
304 # test various errors
305 self.assertRaises(ValueError, '{'.format)
306 self.assertRaises(ValueError, '}'.format)
307 self.assertRaises(ValueError, 'a{'.format)
308 self.assertRaises(ValueError, 'a}'.format)
309 self.assertRaises(ValueError, '{a'.format)
310 self.assertRaises(ValueError, '}a'.format)
311 self.assertRaises(IndexError, '{0}'.format)
312 self.assertRaises(IndexError, '{1}'.format, 'abc')
313 self.assertRaises(KeyError, '{x}'.format)
314 self.assertRaises(ValueError, "}{".format)
315 self.assertRaises(ValueError, "{".format)
316 self.assertRaises(ValueError, "}".format)
317 self.assertRaises(ValueError, "abc{0:{}".format)
318 self.assertRaises(ValueError, "{0".format)
319 self.assertRaises(IndexError, "{0.}".format)
320 self.assertRaises(ValueError, "{0.}".format, 0)
321 self.assertRaises(IndexError, "{0[}".format)
322 self.assertRaises(ValueError, "{0[}".format, [])
323 self.assertRaises(KeyError, "{0]}".format)
324 self.assertRaises(ValueError, "{0.[]}".format, 0)
325 self.assertRaises(ValueError, "{0..foo}".format, 0)
326 self.assertRaises(ValueError, "{0[0}".format, 0)
327 self.assertRaises(ValueError, "{0[0:foo}".format, 0)
328 self.assertRaises(KeyError, "{c]}".format)
329 self.assertRaises(ValueError, "{{ {{{0}}".format, 0)
330 self.assertRaises(ValueError, "{0}}".format, 0)
331 self.assertRaises(KeyError, "{foo}".format, bar=3)
332 self.assertRaises(ValueError, "{0!x}".format, 3)
333 self.assertRaises(ValueError, "{0!}".format, 0)
334 self.assertRaises(ValueError, "{0!rs}".format, 0)
335 self.assertRaises(ValueError, "{!}".format)
336 self.assertRaises(ValueError, "{:}".format)
337 self.assertRaises(ValueError, "{:s}".format)
338 self.assertRaises(ValueError, "{}".format)
339
340 # can't have a replacement on the field name portion
341 self.assertRaises(TypeError, '{0[{1}]}'.format, 'abcdefg', 4)
342
343 # exceed maximum recursion depth
344 self.assertRaises(ValueError, "{0:{1:{2}}}".format, 'abc', 's', '')
345 self.assertRaises(ValueError, "{0:{1:{2:{3:{4:{5:{6}}}}}}}".format,
346 0, 1, 2, 3, 4, 5, 6, 7)
347
348 # string format spec errors
349 self.assertRaises(ValueError, "{0:-s}".format, '')
350 self.assertRaises(ValueError, format, "", "-")
351 self.assertRaises(ValueError, "{0:=s}".format, '')
352
Neal Norwitz7dbd2a32007-06-09 03:36:34 +0000353
Walter Dörwald0fd583c2003-02-21 12:53:50 +0000354def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000355 test_support.run_unittest(StrTest)
Walter Dörwald0fd583c2003-02-21 12:53:50 +0000356
357if __name__ == "__main__":
358 test_main()