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