1import unittest 2import struct 3import sys 4from test import test_support, string_tests 5 6 7class StrSubclass(str): 8 pass 9 10class StrTest( 11 string_tests.CommonTest, 12 string_tests.MixinStrUnicodeUserStringTest, 13 string_tests.MixinStrUserStringTest, 14 string_tests.MixinStrUnicodeTest, 15 ): 16 17 type2test = str 18 19 # We don't need to propagate to str 20 def fixtype(self, obj): 21 return obj 22 23 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 37 def test_formatting(self): 38 string_tests.MixinStrUnicodeUserStringTest.test_formatting(self) 39 self.assertRaises(OverflowError, '%c'.__mod__, 0x1234) 40 41 @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 53 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 104 self.assertTrue(str(Foo0()).startswith("<")) # this is different from __unicode__ 105 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") 113 self.assertIs(type(str(Foo8("foo"))), Foo8) 114 self.assertEqual(StrSubclass(Foo8("foo")), "foofoo") 115 self.assertIs(type(StrSubclass(Foo8("foo"))), StrSubclass) 116 self.assertEqual(str(Foo9("foo")), "string") 117 self.assertEqual(unicode(Foo9("foo")), u"not unicode") 118 119 # 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') 124 def test_expandtabs_overflows_gracefully(self): 125 self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxint) 126 127 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 297 # !r and !s coercions 298 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)') 311 self.assertEqual('{0:d}'.format(G('data')), 'G(data)') 312 self.assertEqual('{0!s}'.format(G('data')), 'string is data') 313 314 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 320 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) 371 self.assertRaises(IndexError, "{:}".format) 372 self.assertRaises(IndexError, "{:s}".format) 373 self.assertRaises(IndexError, "{}".format) 374 375 # issue 6089 376 self.assertRaises(ValueError, "{0[0]x}".format, [None]) 377 self.assertRaises(ValueError, "{0[0](10)}".format, [None]) 378 379 # 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 392 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 407 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 437 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 442 def test_buffer_is_readonly(self): 443 self.assertRaises(TypeError, sys.stdin.readinto, b"") 444 445 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 455 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) 467 468def test_main(): 469 test_support.run_unittest(StrTest) 470 471if __name__ == "__main__": 472 test_main() 473