1# Python test set -- part 6, built-in types 2 3from test.support import ( 4 run_with_locale, is_apple_mobile, cpython_only, 5 iter_builtin_types, iter_slot_wrappers, 6 MISSING_C_DOCSTRINGS, 7) 8from test.test_import import no_rerun 9import collections.abc 10from collections import namedtuple, UserDict 11import copy 12import _datetime 13import gc 14import inspect 15import pickle 16import locale 17import sys 18import textwrap 19import types 20import unittest.mock 21import weakref 22import typing 23 24 25T = typing.TypeVar("T") 26 27class Example: 28 pass 29 30class Forward: ... 31 32def clear_typing_caches(): 33 for f in typing._cleanups: 34 f() 35 36 37class TypesTests(unittest.TestCase): 38 39 def test_truth_values(self): 40 if None: self.fail('None is true instead of false') 41 if 0: self.fail('0 is true instead of false') 42 if 0.0: self.fail('0.0 is true instead of false') 43 if '': self.fail('\'\' is true instead of false') 44 if not 1: self.fail('1 is false instead of true') 45 if not 1.0: self.fail('1.0 is false instead of true') 46 if not 'x': self.fail('\'x\' is false instead of true') 47 if not {'x': 1}: self.fail('{\'x\': 1} is false instead of true') 48 def f(): pass 49 class C: pass 50 x = C() 51 if not f: self.fail('f is false instead of true') 52 if not C: self.fail('C is false instead of true') 53 if not sys: self.fail('sys is false instead of true') 54 if not x: self.fail('x is false instead of true') 55 56 def test_boolean_ops(self): 57 if 0 or 0: self.fail('0 or 0 is true instead of false') 58 if 1 and 1: pass 59 else: self.fail('1 and 1 is false instead of true') 60 if not 1: self.fail('not 1 is true instead of false') 61 62 def test_comparisons(self): 63 if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass 64 else: self.fail('int comparisons failed') 65 if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass 66 else: self.fail('float comparisons failed') 67 if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass 68 else: self.fail('string comparisons failed') 69 if None is None: pass 70 else: self.fail('identity test failed') 71 72 def test_float_constructor(self): 73 self.assertRaises(ValueError, float, '') 74 self.assertRaises(ValueError, float, '5\0') 75 self.assertRaises(ValueError, float, '5_5\0') 76 77 def test_zero_division(self): 78 try: 5.0 / 0.0 79 except ZeroDivisionError: pass 80 else: self.fail("5.0 / 0.0 didn't raise ZeroDivisionError") 81 82 try: 5.0 // 0.0 83 except ZeroDivisionError: pass 84 else: self.fail("5.0 // 0.0 didn't raise ZeroDivisionError") 85 86 try: 5.0 % 0.0 87 except ZeroDivisionError: pass 88 else: self.fail("5.0 % 0.0 didn't raise ZeroDivisionError") 89 90 try: 5 / 0 91 except ZeroDivisionError: pass 92 else: self.fail("5 / 0 didn't raise ZeroDivisionError") 93 94 try: 5 // 0 95 except ZeroDivisionError: pass 96 else: self.fail("5 // 0 didn't raise ZeroDivisionError") 97 98 try: 5 % 0 99 except ZeroDivisionError: pass 100 else: self.fail("5 % 0 didn't raise ZeroDivisionError") 101 102 def test_numeric_types(self): 103 if 0 != 0.0 or 1 != 1.0 or -1 != -1.0: 104 self.fail('int/float value not equal') 105 # calling built-in types without argument must return 0 106 if int() != 0: self.fail('int() does not return 0') 107 if float() != 0.0: self.fail('float() does not return 0.0') 108 if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass 109 else: self.fail('int() does not round properly') 110 if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass 111 else: self.fail('float() does not work properly') 112 113 def test_float_to_string(self): 114 def test(f, result): 115 self.assertEqual(f.__format__('e'), result) 116 self.assertEqual('%e' % f, result) 117 118 # test all 2 digit exponents, both with __format__ and with 119 # '%' formatting 120 for i in range(-99, 100): 121 test(float('1.5e'+str(i)), '1.500000e{0:+03d}'.format(i)) 122 123 # test some 3 digit exponents 124 self.assertEqual(1.5e100.__format__('e'), '1.500000e+100') 125 self.assertEqual('%e' % 1.5e100, '1.500000e+100') 126 127 self.assertEqual(1.5e101.__format__('e'), '1.500000e+101') 128 self.assertEqual('%e' % 1.5e101, '1.500000e+101') 129 130 self.assertEqual(1.5e-100.__format__('e'), '1.500000e-100') 131 self.assertEqual('%e' % 1.5e-100, '1.500000e-100') 132 133 self.assertEqual(1.5e-101.__format__('e'), '1.500000e-101') 134 self.assertEqual('%e' % 1.5e-101, '1.500000e-101') 135 136 self.assertEqual('%g' % 1.0, '1') 137 self.assertEqual('%#g' % 1.0, '1.00000') 138 139 def test_normal_integers(self): 140 # Ensure the first 256 integers are shared 141 a = 256 142 b = 128*2 143 if a is not b: self.fail('256 is not shared') 144 if 12 + 24 != 36: self.fail('int op') 145 if 12 + (-24) != -12: self.fail('int op') 146 if (-12) + 24 != 12: self.fail('int op') 147 if (-12) + (-24) != -36: self.fail('int op') 148 if not 12 < 24: self.fail('int op') 149 if not -24 < -12: self.fail('int op') 150 # Test for a particular bug in integer multiply 151 xsize, ysize, zsize = 238, 356, 4 152 if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912): 153 self.fail('int mul commutativity') 154 # And another. 155 m = -sys.maxsize - 1 156 for divisor in 1, 2, 4, 8, 16, 32: 157 j = m // divisor 158 prod = divisor * j 159 if prod != m: 160 self.fail("%r * %r == %r != %r" % (divisor, j, prod, m)) 161 if type(prod) is not int: 162 self.fail("expected type(prod) to be int, not %r" % 163 type(prod)) 164 # Check for unified integral type 165 for divisor in 1, 2, 4, 8, 16, 32: 166 j = m // divisor - 1 167 prod = divisor * j 168 if type(prod) is not int: 169 self.fail("expected type(%r) to be int, not %r" % 170 (prod, type(prod))) 171 # Check for unified integral type 172 m = sys.maxsize 173 for divisor in 1, 2, 4, 8, 16, 32: 174 j = m // divisor + 1 175 prod = divisor * j 176 if type(prod) is not int: 177 self.fail("expected type(%r) to be int, not %r" % 178 (prod, type(prod))) 179 180 x = sys.maxsize 181 self.assertIsInstance(x + 1, int, 182 "(sys.maxsize + 1) should have returned int") 183 self.assertIsInstance(-x - 1, int, 184 "(-sys.maxsize - 1) should have returned int") 185 self.assertIsInstance(-x - 2, int, 186 "(-sys.maxsize - 2) should have returned int") 187 188 try: 5 << -5 189 except ValueError: pass 190 else: self.fail('int negative shift <<') 191 192 try: 5 >> -5 193 except ValueError: pass 194 else: self.fail('int negative shift >>') 195 196 def test_floats(self): 197 if 12.0 + 24.0 != 36.0: self.fail('float op') 198 if 12.0 + (-24.0) != -12.0: self.fail('float op') 199 if (-12.0) + 24.0 != 12.0: self.fail('float op') 200 if (-12.0) + (-24.0) != -36.0: self.fail('float op') 201 if not 12.0 < 24.0: self.fail('float op') 202 if not -24.0 < -12.0: self.fail('float op') 203 204 def test_strings(self): 205 if len('') != 0: self.fail('len(\'\')') 206 if len('a') != 1: self.fail('len(\'a\')') 207 if len('abcdef') != 6: self.fail('len(\'abcdef\')') 208 if 'xyz' + 'abcde' != 'xyzabcde': self.fail('string concatenation') 209 if 'xyz'*3 != 'xyzxyzxyz': self.fail('string repetition *3') 210 if 0*'abcde' != '': self.fail('string repetition 0*') 211 if min('abc') != 'a' or max('abc') != 'c': self.fail('min/max string') 212 if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass 213 else: self.fail('in/not in string') 214 x = 'x'*103 215 if '%s!'%x != x+'!': self.fail('nasty string formatting bug') 216 217 #extended slices for strings 218 a = '0123456789' 219 self.assertEqual(a[::], a) 220 self.assertEqual(a[::2], '02468') 221 self.assertEqual(a[1::2], '13579') 222 self.assertEqual(a[::-1],'9876543210') 223 self.assertEqual(a[::-2], '97531') 224 self.assertEqual(a[3::-2], '31') 225 self.assertEqual(a[-100:100:], a) 226 self.assertEqual(a[100:-100:-1], a[::-1]) 227 self.assertEqual(a[-100:100:2], '02468') 228 229 def test_type_function(self): 230 self.assertRaises(TypeError, type, 1, 2) 231 self.assertRaises(TypeError, type, 1, 2, 3, 4) 232 233 def test_int__format__(self): 234 def test(i, format_spec, result): 235 # just make sure we have the unified type for integers 236 self.assertIs(type(i), int) 237 self.assertIs(type(format_spec), str) 238 self.assertEqual(i.__format__(format_spec), result) 239 240 test(123456789, 'd', '123456789') 241 test(123456789, 'd', '123456789') 242 243 test(1, 'c', '\01') 244 245 # sign and aligning are interdependent 246 test(1, "-", '1') 247 test(-1, "-", '-1') 248 test(1, "-3", ' 1') 249 test(-1, "-3", ' -1') 250 test(1, "+3", ' +1') 251 test(-1, "+3", ' -1') 252 test(1, " 3", ' 1') 253 test(-1, " 3", ' -1') 254 test(1, " ", ' 1') 255 test(-1, " ", '-1') 256 257 # hex 258 test(3, "x", "3") 259 test(3, "X", "3") 260 test(1234, "x", "4d2") 261 test(-1234, "x", "-4d2") 262 test(1234, "8x", " 4d2") 263 test(-1234, "8x", " -4d2") 264 test(1234, "x", "4d2") 265 test(-1234, "x", "-4d2") 266 test(-3, "x", "-3") 267 test(-3, "X", "-3") 268 test(int('be', 16), "x", "be") 269 test(int('be', 16), "X", "BE") 270 test(-int('be', 16), "x", "-be") 271 test(-int('be', 16), "X", "-BE") 272 273 # octal 274 test(3, "o", "3") 275 test(-3, "o", "-3") 276 test(65, "o", "101") 277 test(-65, "o", "-101") 278 test(1234, "o", "2322") 279 test(-1234, "o", "-2322") 280 test(1234, "-o", "2322") 281 test(-1234, "-o", "-2322") 282 test(1234, " o", " 2322") 283 test(-1234, " o", "-2322") 284 test(1234, "+o", "+2322") 285 test(-1234, "+o", "-2322") 286 287 # binary 288 test(3, "b", "11") 289 test(-3, "b", "-11") 290 test(1234, "b", "10011010010") 291 test(-1234, "b", "-10011010010") 292 test(1234, "-b", "10011010010") 293 test(-1234, "-b", "-10011010010") 294 test(1234, " b", " 10011010010") 295 test(-1234, " b", "-10011010010") 296 test(1234, "+b", "+10011010010") 297 test(-1234, "+b", "-10011010010") 298 299 # alternate (#) formatting 300 test(0, "#b", '0b0') 301 test(0, "-#b", '0b0') 302 test(1, "-#b", '0b1') 303 test(-1, "-#b", '-0b1') 304 test(-1, "-#5b", ' -0b1') 305 test(1, "+#5b", ' +0b1') 306 test(100, "+#b", '+0b1100100') 307 test(100, "#012b", '0b0001100100') 308 test(-100, "#012b", '-0b001100100') 309 310 test(0, "#o", '0o0') 311 test(0, "-#o", '0o0') 312 test(1, "-#o", '0o1') 313 test(-1, "-#o", '-0o1') 314 test(-1, "-#5o", ' -0o1') 315 test(1, "+#5o", ' +0o1') 316 test(100, "+#o", '+0o144') 317 test(100, "#012o", '0o0000000144') 318 test(-100, "#012o", '-0o000000144') 319 320 test(0, "#x", '0x0') 321 test(0, "-#x", '0x0') 322 test(1, "-#x", '0x1') 323 test(-1, "-#x", '-0x1') 324 test(-1, "-#5x", ' -0x1') 325 test(1, "+#5x", ' +0x1') 326 test(100, "+#x", '+0x64') 327 test(100, "#012x", '0x0000000064') 328 test(-100, "#012x", '-0x000000064') 329 test(123456, "#012x", '0x000001e240') 330 test(-123456, "#012x", '-0x00001e240') 331 332 test(0, "#X", '0X0') 333 test(0, "-#X", '0X0') 334 test(1, "-#X", '0X1') 335 test(-1, "-#X", '-0X1') 336 test(-1, "-#5X", ' -0X1') 337 test(1, "+#5X", ' +0X1') 338 test(100, "+#X", '+0X64') 339 test(100, "#012X", '0X0000000064') 340 test(-100, "#012X", '-0X000000064') 341 test(123456, "#012X", '0X000001E240') 342 test(-123456, "#012X", '-0X00001E240') 343 344 test(123, ',', '123') 345 test(-123, ',', '-123') 346 test(1234, ',', '1,234') 347 test(-1234, ',', '-1,234') 348 test(123456, ',', '123,456') 349 test(-123456, ',', '-123,456') 350 test(1234567, ',', '1,234,567') 351 test(-1234567, ',', '-1,234,567') 352 353 # issue 5782, commas with no specifier type 354 test(1234, '010,', '00,001,234') 355 356 # Unified type for integers 357 test(10**100, 'd', '1' + '0' * 100) 358 test(10**100+100, 'd', '1' + '0' * 97 + '100') 359 360 # make sure these are errors 361 362 # precision disallowed 363 self.assertRaises(ValueError, 3 .__format__, "1.3") 364 # sign not allowed with 'c' 365 self.assertRaises(ValueError, 3 .__format__, "+c") 366 # format spec must be string 367 self.assertRaises(TypeError, 3 .__format__, None) 368 self.assertRaises(TypeError, 3 .__format__, 0) 369 # can't have ',' with 'n' 370 self.assertRaises(ValueError, 3 .__format__, ",n") 371 # can't have ',' with 'c' 372 self.assertRaises(ValueError, 3 .__format__, ",c") 373 # can't have '#' with 'c' 374 self.assertRaises(ValueError, 3 .__format__, "#c") 375 376 # ensure that only int and float type specifiers work 377 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + 378 [chr(x) for x in range(ord('A'), ord('Z')+1)]): 379 if not format_spec in 'bcdoxXeEfFgGn%': 380 self.assertRaises(ValueError, 0 .__format__, format_spec) 381 self.assertRaises(ValueError, 1 .__format__, format_spec) 382 self.assertRaises(ValueError, (-1) .__format__, format_spec) 383 384 # ensure that float type specifiers work; format converts 385 # the int to a float 386 for format_spec in 'eEfFgG%': 387 for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]: 388 self.assertEqual(value.__format__(format_spec), 389 float(value).__format__(format_spec)) 390 391 # Issue 6902 392 test(123456, "0<20", '12345600000000000000') 393 test(123456, "1<20", '12345611111111111111') 394 test(123456, "*<20", '123456**************') 395 test(123456, "0>20", '00000000000000123456') 396 test(123456, "1>20", '11111111111111123456') 397 test(123456, "*>20", '**************123456') 398 test(123456, "0=20", '00000000000000123456') 399 test(123456, "1=20", '11111111111111123456') 400 test(123456, "*=20", '**************123456') 401 402 @run_with_locale('LC_NUMERIC', 'en_US.UTF8', '') 403 def test_float__format__locale(self): 404 # test locale support for __format__ code 'n' 405 406 for i in range(-10, 10): 407 x = 1234567890.0 * (10.0 ** i) 408 self.assertEqual(locale.format_string('%g', x, grouping=True), format(x, 'n')) 409 self.assertEqual(locale.format_string('%.10g', x, grouping=True), format(x, '.10n')) 410 411 @run_with_locale('LC_NUMERIC', 'en_US.UTF8', '') 412 def test_int__format__locale(self): 413 # test locale support for __format__ code 'n' for integers 414 415 x = 123456789012345678901234567890 416 for i in range(0, 30): 417 self.assertEqual(locale.format_string('%d', x, grouping=True), format(x, 'n')) 418 419 # move to the next integer to test 420 x = x // 10 421 422 rfmt = ">20n" 423 lfmt = "<20n" 424 cfmt = "^20n" 425 for x in (1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890, 12345678900): 426 self.assertEqual(len(format(0, rfmt)), len(format(x, rfmt))) 427 self.assertEqual(len(format(0, lfmt)), len(format(x, lfmt))) 428 self.assertEqual(len(format(0, cfmt)), len(format(x, cfmt))) 429 430 def test_float__format__(self): 431 def test(f, format_spec, result): 432 self.assertEqual(f.__format__(format_spec), result) 433 self.assertEqual(format(f, format_spec), result) 434 435 test(0.0, 'f', '0.000000') 436 437 # the default is 'g', except for empty format spec 438 test(0.0, '', '0.0') 439 test(0.01, '', '0.01') 440 test(0.01, 'g', '0.01') 441 442 # test for issue 3411 443 test(1.23, '1', '1.23') 444 test(-1.23, '1', '-1.23') 445 test(1.23, '1g', '1.23') 446 test(-1.23, '1g', '-1.23') 447 448 test( 1.0, ' g', ' 1') 449 test(-1.0, ' g', '-1') 450 test( 1.0, '+g', '+1') 451 test(-1.0, '+g', '-1') 452 test(1.1234e200, 'g', '1.1234e+200') 453 test(1.1234e200, 'G', '1.1234E+200') 454 455 456 test(1.0, 'f', '1.000000') 457 458 test(-1.0, 'f', '-1.000000') 459 460 test( 1.0, ' f', ' 1.000000') 461 test(-1.0, ' f', '-1.000000') 462 test( 1.0, '+f', '+1.000000') 463 test(-1.0, '+f', '-1.000000') 464 465 # Python versions <= 3.0 switched from 'f' to 'g' formatting for 466 # values larger than 1e50. No longer. 467 f = 1.1234e90 468 for fmt in 'f', 'F': 469 # don't do a direct equality check, since on some 470 # platforms only the first few digits of dtoa 471 # will be reliable 472 result = f.__format__(fmt) 473 self.assertEqual(len(result), 98) 474 self.assertEqual(result[-7], '.') 475 self.assertIn(result[:12], ('112340000000', '112339999999')) 476 f = 1.1234e200 477 for fmt in 'f', 'F': 478 result = f.__format__(fmt) 479 self.assertEqual(len(result), 208) 480 self.assertEqual(result[-7], '.') 481 self.assertIn(result[:12], ('112340000000', '112339999999')) 482 483 484 test( 1.0, 'e', '1.000000e+00') 485 test(-1.0, 'e', '-1.000000e+00') 486 test( 1.0, 'E', '1.000000E+00') 487 test(-1.0, 'E', '-1.000000E+00') 488 test(1.1234e20, 'e', '1.123400e+20') 489 test(1.1234e20, 'E', '1.123400E+20') 490 491 # No format code means use g, but must have a decimal 492 # and a number after the decimal. This is tricky, because 493 # a totally empty format specifier means something else. 494 # So, just use a sign flag 495 test(1e200, '+g', '+1e+200') 496 test(1e200, '+', '+1e+200') 497 498 test(1.1e200, '+g', '+1.1e+200') 499 test(1.1e200, '+', '+1.1e+200') 500 501 # 0 padding 502 test(1234., '010f', '1234.000000') 503 test(1234., '011f', '1234.000000') 504 test(1234., '012f', '01234.000000') 505 test(-1234., '011f', '-1234.000000') 506 test(-1234., '012f', '-1234.000000') 507 test(-1234., '013f', '-01234.000000') 508 test(-1234.12341234, '013f', '-01234.123412') 509 test(-123456.12341234, '011.2f', '-0123456.12') 510 511 # issue 5782, commas with no specifier type 512 test(1.2, '010,.2', '0,000,001.2') 513 514 # 0 padding with commas 515 test(1234., '011,f', '1,234.000000') 516 test(1234., '012,f', '1,234.000000') 517 test(1234., '013,f', '01,234.000000') 518 test(-1234., '012,f', '-1,234.000000') 519 test(-1234., '013,f', '-1,234.000000') 520 test(-1234., '014,f', '-01,234.000000') 521 test(-12345., '015,f', '-012,345.000000') 522 test(-123456., '016,f', '-0,123,456.000000') 523 test(-123456., '017,f', '-0,123,456.000000') 524 test(-123456.12341234, '017,f', '-0,123,456.123412') 525 test(-123456.12341234, '013,.2f', '-0,123,456.12') 526 527 # % formatting 528 test(-1.0, '%', '-100.000000%') 529 530 # format spec must be string 531 self.assertRaises(TypeError, 3.0.__format__, None) 532 self.assertRaises(TypeError, 3.0.__format__, 0) 533 534 # confirm format options expected to fail on floats, such as integer 535 # presentation types 536 for format_spec in 'sbcdoxX': 537 self.assertRaises(ValueError, format, 0.0, format_spec) 538 self.assertRaises(ValueError, format, 1.0, format_spec) 539 self.assertRaises(ValueError, format, -1.0, format_spec) 540 self.assertRaises(ValueError, format, 1e100, format_spec) 541 self.assertRaises(ValueError, format, -1e100, format_spec) 542 self.assertRaises(ValueError, format, 1e-100, format_spec) 543 self.assertRaises(ValueError, format, -1e-100, format_spec) 544 545 # Alternate float formatting 546 test(1.0, '.0e', '1e+00') 547 test(1.0, '#.0e', '1.e+00') 548 test(1.0, '.0f', '1') 549 test(1.0, '#.0f', '1.') 550 test(1.1, 'g', '1.1') 551 test(1.1, '#g', '1.10000') 552 test(1.0, '.0%', '100%') 553 test(1.0, '#.0%', '100.%') 554 555 # Issue 7094: Alternate formatting (specified by #) 556 test(1.0, '0e', '1.000000e+00') 557 test(1.0, '#0e', '1.000000e+00') 558 test(1.0, '0f', '1.000000' ) 559 test(1.0, '#0f', '1.000000') 560 test(1.0, '.1e', '1.0e+00') 561 test(1.0, '#.1e', '1.0e+00') 562 test(1.0, '.1f', '1.0') 563 test(1.0, '#.1f', '1.0') 564 test(1.0, '.1%', '100.0%') 565 test(1.0, '#.1%', '100.0%') 566 567 # Issue 6902 568 test(12345.6, "0<20", '12345.60000000000000') 569 test(12345.6, "1<20", '12345.61111111111111') 570 test(12345.6, "*<20", '12345.6*************') 571 test(12345.6, "0>20", '000000000000012345.6') 572 test(12345.6, "1>20", '111111111111112345.6') 573 test(12345.6, "*>20", '*************12345.6') 574 test(12345.6, "0=20", '000000000000012345.6') 575 test(12345.6, "1=20", '111111111111112345.6') 576 test(12345.6, "*=20", '*************12345.6') 577 578 def test_format_spec_errors(self): 579 # int, float, and string all share the same format spec 580 # mini-language parser. 581 582 # Check that we can't ask for too many digits. This is 583 # probably a CPython specific test. It tries to put the width 584 # into a C long. 585 self.assertRaises(ValueError, format, 0, '1'*10000 + 'd') 586 587 # Similar with the precision. 588 self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd') 589 590 # And may as well test both. 591 self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd') 592 593 # Make sure commas aren't allowed with various type codes 594 for code in 'xXobns': 595 self.assertRaises(ValueError, format, 0, ',' + code) 596 597 def test_internal_sizes(self): 598 self.assertGreater(object.__basicsize__, 0) 599 self.assertGreater(tuple.__itemsize__, 0) 600 601 def test_slot_wrapper_types(self): 602 self.assertIsInstance(object.__init__, types.WrapperDescriptorType) 603 self.assertIsInstance(object.__str__, types.WrapperDescriptorType) 604 self.assertIsInstance(object.__lt__, types.WrapperDescriptorType) 605 self.assertIsInstance(int.__lt__, types.WrapperDescriptorType) 606 607 @unittest.skipIf(MISSING_C_DOCSTRINGS, 608 "Signature information for builtins requires docstrings") 609 def test_dunder_get_signature(self): 610 sig = inspect.signature(object.__init__.__get__) 611 self.assertEqual(list(sig.parameters), ["instance", "owner"]) 612 # gh-93021: Second parameter is optional 613 self.assertIs(sig.parameters["owner"].default, None) 614 615 def test_method_wrapper_types(self): 616 self.assertIsInstance(object().__init__, types.MethodWrapperType) 617 self.assertIsInstance(object().__str__, types.MethodWrapperType) 618 self.assertIsInstance(object().__lt__, types.MethodWrapperType) 619 self.assertIsInstance((42).__lt__, types.MethodWrapperType) 620 621 def test_method_descriptor_types(self): 622 self.assertIsInstance(str.join, types.MethodDescriptorType) 623 self.assertIsInstance(list.append, types.MethodDescriptorType) 624 self.assertIsInstance(''.join, types.BuiltinMethodType) 625 self.assertIsInstance([].append, types.BuiltinMethodType) 626 627 self.assertIsInstance(int.__dict__['from_bytes'], types.ClassMethodDescriptorType) 628 self.assertIsInstance(int.from_bytes, types.BuiltinMethodType) 629 self.assertIsInstance(int.__new__, types.BuiltinMethodType) 630 631 def test_ellipsis_type(self): 632 self.assertIsInstance(Ellipsis, types.EllipsisType) 633 634 def test_notimplemented_type(self): 635 self.assertIsInstance(NotImplemented, types.NotImplementedType) 636 637 def test_none_type(self): 638 self.assertIsInstance(None, types.NoneType) 639 640 def test_traceback_and_frame_types(self): 641 try: 642 raise OSError 643 except OSError as e: 644 exc = e 645 self.assertIsInstance(exc.__traceback__, types.TracebackType) 646 self.assertIsInstance(exc.__traceback__.tb_frame, types.FrameType) 647 648 def test_capsule_type(self): 649 self.assertIsInstance(_datetime.datetime_CAPI, types.CapsuleType) 650 651 652class UnionTests(unittest.TestCase): 653 654 def test_or_types_operator(self): 655 self.assertEqual(int | str, typing.Union[int, str]) 656 self.assertNotEqual(int | list, typing.Union[int, str]) 657 self.assertEqual(str | int, typing.Union[int, str]) 658 self.assertEqual(int | None, typing.Union[int, None]) 659 self.assertEqual(None | int, typing.Union[int, None]) 660 self.assertEqual(int | type(None), int | None) 661 self.assertEqual(type(None) | int, None | int) 662 self.assertEqual(int | str | list, typing.Union[int, str, list]) 663 self.assertEqual(int | (str | list), typing.Union[int, str, list]) 664 self.assertEqual(str | (int | list), typing.Union[int, str, list]) 665 self.assertEqual(typing.List | typing.Tuple, typing.Union[typing.List, typing.Tuple]) 666 self.assertEqual(typing.List[int] | typing.Tuple[int], typing.Union[typing.List[int], typing.Tuple[int]]) 667 self.assertEqual(typing.List[int] | None, typing.Union[typing.List[int], None]) 668 self.assertEqual(None | typing.List[int], typing.Union[None, typing.List[int]]) 669 self.assertEqual(str | float | int | complex | int, (int | str) | (float | complex)) 670 self.assertEqual(typing.Union[str, int, typing.List[int]], str | int | typing.List[int]) 671 self.assertIs(int | int, int) 672 self.assertEqual( 673 BaseException | 674 bool | 675 bytes | 676 complex | 677 float | 678 int | 679 list | 680 map | 681 set, 682 typing.Union[ 683 BaseException, 684 bool, 685 bytes, 686 complex, 687 float, 688 int, 689 list, 690 map, 691 set, 692 ]) 693 with self.assertRaises(TypeError): 694 int | 3 695 with self.assertRaises(TypeError): 696 3 | int 697 with self.assertRaises(TypeError): 698 Example() | int 699 x = int | str 700 self.assertEqual(x, int | str) 701 self.assertEqual(x, str | int) 702 self.assertNotEqual(x, {}) # should not raise exception 703 with self.assertRaises(TypeError): 704 x < x 705 with self.assertRaises(TypeError): 706 x <= x 707 y = typing.Union[str, int] 708 with self.assertRaises(TypeError): 709 x < y 710 y = int | bool 711 with self.assertRaises(TypeError): 712 x < y 713 # Check that we don't crash if typing.Union does not have a tuple in __args__ 714 y = typing.Union[str, int] 715 y.__args__ = [str, int] 716 self.assertEqual(x, y) 717 718 def test_hash(self): 719 self.assertEqual(hash(int | str), hash(str | int)) 720 self.assertEqual(hash(int | str), hash(typing.Union[int, str])) 721 722 def test_union_of_unhashable(self): 723 class UnhashableMeta(type): 724 __hash__ = None 725 726 class A(metaclass=UnhashableMeta): ... 727 class B(metaclass=UnhashableMeta): ... 728 729 self.assertEqual((A | B).__args__, (A, B)) 730 union1 = A | B 731 with self.assertRaises(TypeError): 732 hash(union1) 733 734 union2 = int | B 735 with self.assertRaises(TypeError): 736 hash(union2) 737 738 union3 = A | int 739 with self.assertRaises(TypeError): 740 hash(union3) 741 742 def test_instancecheck_and_subclasscheck(self): 743 for x in (int | str, typing.Union[int, str]): 744 with self.subTest(x=x): 745 self.assertIsInstance(1, x) 746 self.assertIsInstance(True, x) 747 self.assertIsInstance('a', x) 748 self.assertNotIsInstance(None, x) 749 self.assertTrue(issubclass(int, x)) 750 self.assertTrue(issubclass(bool, x)) 751 self.assertTrue(issubclass(str, x)) 752 self.assertFalse(issubclass(type(None), x)) 753 754 for x in (int | None, typing.Union[int, None]): 755 with self.subTest(x=x): 756 self.assertIsInstance(None, x) 757 self.assertTrue(issubclass(type(None), x)) 758 759 for x in ( 760 int | collections.abc.Mapping, 761 typing.Union[int, collections.abc.Mapping], 762 ): 763 with self.subTest(x=x): 764 self.assertIsInstance({}, x) 765 self.assertNotIsInstance((), x) 766 self.assertTrue(issubclass(dict, x)) 767 self.assertFalse(issubclass(list, x)) 768 769 def test_instancecheck_and_subclasscheck_order(self): 770 T = typing.TypeVar('T') 771 772 will_resolve = ( 773 int | T, 774 typing.Union[int, T], 775 ) 776 for x in will_resolve: 777 with self.subTest(x=x): 778 self.assertIsInstance(1, x) 779 self.assertTrue(issubclass(int, x)) 780 781 wont_resolve = ( 782 T | int, 783 typing.Union[T, int], 784 ) 785 for x in wont_resolve: 786 with self.subTest(x=x): 787 with self.assertRaises(TypeError): 788 issubclass(int, x) 789 with self.assertRaises(TypeError): 790 isinstance(1, x) 791 792 for x in (*will_resolve, *wont_resolve): 793 with self.subTest(x=x): 794 with self.assertRaises(TypeError): 795 issubclass(object, x) 796 with self.assertRaises(TypeError): 797 isinstance(object(), x) 798 799 def test_bad_instancecheck(self): 800 class BadMeta(type): 801 def __instancecheck__(cls, inst): 802 1/0 803 x = int | BadMeta('A', (), {}) 804 self.assertTrue(isinstance(1, x)) 805 self.assertRaises(ZeroDivisionError, isinstance, [], x) 806 807 def test_bad_subclasscheck(self): 808 class BadMeta(type): 809 def __subclasscheck__(cls, sub): 810 1/0 811 x = int | BadMeta('A', (), {}) 812 self.assertTrue(issubclass(int, x)) 813 self.assertRaises(ZeroDivisionError, issubclass, list, x) 814 815 def test_or_type_operator_with_TypeVar(self): 816 TV = typing.TypeVar('T') 817 self.assertEqual(TV | str, typing.Union[TV, str]) 818 self.assertEqual(str | TV, typing.Union[str, TV]) 819 self.assertIs((int | TV)[int], int) 820 self.assertIs((TV | int)[int], int) 821 822 def test_union_args(self): 823 def check(arg, expected): 824 clear_typing_caches() 825 self.assertEqual(arg.__args__, expected) 826 827 check(int | str, (int, str)) 828 check((int | str) | list, (int, str, list)) 829 check(int | (str | list), (int, str, list)) 830 check((int | str) | int, (int, str)) 831 check(int | (str | int), (int, str)) 832 check((int | str) | (str | int), (int, str)) 833 check(typing.Union[int, str] | list, (int, str, list)) 834 check(int | typing.Union[str, list], (int, str, list)) 835 check((int | str) | (list | int), (int, str, list)) 836 check((int | str) | typing.Union[list, int], (int, str, list)) 837 check(typing.Union[int, str] | (list | int), (int, str, list)) 838 check((str | int) | (int | list), (str, int, list)) 839 check((str | int) | typing.Union[int, list], (str, int, list)) 840 check(typing.Union[str, int] | (int | list), (str, int, list)) 841 check(int | type(None), (int, type(None))) 842 check(type(None) | int, (type(None), int)) 843 844 args = (int, list[int], typing.List[int], 845 typing.Tuple[int, int], typing.Callable[[int], int], 846 typing.Hashable, typing.TypeVar('T')) 847 for x in args: 848 with self.subTest(x): 849 check(x | None, (x, type(None))) 850 check(None | x, (type(None), x)) 851 852 def test_union_parameter_chaining(self): 853 T = typing.TypeVar("T") 854 S = typing.TypeVar("S") 855 856 self.assertEqual((float | list[T])[int], float | list[int]) 857 self.assertEqual(list[int | list[T]].__parameters__, (T,)) 858 self.assertEqual(list[int | list[T]][str], list[int | list[str]]) 859 self.assertEqual((list[T] | list[S]).__parameters__, (T, S)) 860 self.assertEqual((list[T] | list[S])[int, T], list[int] | list[T]) 861 self.assertEqual((list[T] | list[S])[int, int], list[int]) 862 863 def test_union_parameter_substitution(self): 864 def eq(actual, expected, typed=True): 865 self.assertEqual(actual, expected) 866 if typed: 867 self.assertIs(type(actual), type(expected)) 868 869 T = typing.TypeVar('T') 870 S = typing.TypeVar('S') 871 NT = typing.NewType('NT', str) 872 x = int | T | bytes 873 874 eq(x[str], int | str | bytes, typed=False) 875 eq(x[list[int]], int | list[int] | bytes, typed=False) 876 eq(x[typing.List], int | typing.List | bytes) 877 eq(x[typing.List[int]], int | typing.List[int] | bytes) 878 eq(x[typing.Hashable], int | typing.Hashable | bytes) 879 eq(x[collections.abc.Hashable], 880 int | collections.abc.Hashable | bytes, typed=False) 881 eq(x[typing.Callable[[int], str]], 882 int | typing.Callable[[int], str] | bytes) 883 eq(x[collections.abc.Callable[[int], str]], 884 int | collections.abc.Callable[[int], str] | bytes, typed=False) 885 eq(x[typing.Tuple[int, str]], int | typing.Tuple[int, str] | bytes) 886 eq(x[typing.Literal['none']], int | typing.Literal['none'] | bytes) 887 eq(x[str | list], int | str | list | bytes, typed=False) 888 eq(x[typing.Union[str, list]], typing.Union[int, str, list, bytes]) 889 eq(x[str | int], int | str | bytes, typed=False) 890 eq(x[typing.Union[str, int]], typing.Union[int, str, bytes]) 891 eq(x[NT], int | NT | bytes) 892 eq(x[S], int | S | bytes) 893 894 def test_union_pickle(self): 895 orig = list[T] | int 896 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 897 s = pickle.dumps(orig, proto) 898 loaded = pickle.loads(s) 899 self.assertEqual(loaded, orig) 900 self.assertEqual(loaded.__args__, orig.__args__) 901 self.assertEqual(loaded.__parameters__, orig.__parameters__) 902 903 def test_union_copy(self): 904 orig = list[T] | int 905 for copied in (copy.copy(orig), copy.deepcopy(orig)): 906 self.assertEqual(copied, orig) 907 self.assertEqual(copied.__args__, orig.__args__) 908 self.assertEqual(copied.__parameters__, orig.__parameters__) 909 910 def test_union_parameter_substitution_errors(self): 911 T = typing.TypeVar("T") 912 x = int | T 913 with self.assertRaises(TypeError): 914 x[int, str] 915 916 def test_or_type_operator_with_forward(self): 917 T = typing.TypeVar('T') 918 ForwardAfter = T | 'Forward' 919 ForwardBefore = 'Forward' | T 920 def forward_after(x: ForwardAfter[int]) -> None: ... 921 def forward_before(x: ForwardBefore[int]) -> None: ... 922 self.assertEqual(typing.get_args(typing.get_type_hints(forward_after)['x']), 923 (int, Forward)) 924 self.assertEqual(typing.get_args(typing.get_type_hints(forward_before)['x']), 925 (int, Forward)) 926 927 def test_or_type_operator_with_Protocol(self): 928 class Proto(typing.Protocol): 929 def meth(self) -> int: 930 ... 931 self.assertEqual(Proto | str, typing.Union[Proto, str]) 932 933 def test_or_type_operator_with_Alias(self): 934 self.assertEqual(list | str, typing.Union[list, str]) 935 self.assertEqual(typing.List | str, typing.Union[typing.List, str]) 936 937 def test_or_type_operator_with_NamedTuple(self): 938 NT = namedtuple('A', ['B', 'C', 'D']) 939 self.assertEqual(NT | str, typing.Union[NT, str]) 940 941 def test_or_type_operator_with_TypedDict(self): 942 class Point2D(typing.TypedDict): 943 x: int 944 y: int 945 label: str 946 self.assertEqual(Point2D | str, typing.Union[Point2D, str]) 947 948 def test_or_type_operator_with_NewType(self): 949 UserId = typing.NewType('UserId', int) 950 self.assertEqual(UserId | str, typing.Union[UserId, str]) 951 952 def test_or_type_operator_with_IO(self): 953 self.assertEqual(typing.IO | str, typing.Union[typing.IO, str]) 954 955 def test_or_type_operator_with_SpecialForm(self): 956 self.assertEqual(typing.Any | str, typing.Union[typing.Any, str]) 957 self.assertEqual(typing.NoReturn | str, typing.Union[typing.NoReturn, str]) 958 self.assertEqual(typing.Optional[int] | str, typing.Union[typing.Optional[int], str]) 959 self.assertEqual(typing.Optional[int] | str, typing.Union[int, str, None]) 960 self.assertEqual(typing.Union[int, bool] | str, typing.Union[int, bool, str]) 961 962 def test_or_type_operator_with_Literal(self): 963 Literal = typing.Literal 964 self.assertEqual((Literal[1] | Literal[2]).__args__, 965 (Literal[1], Literal[2])) 966 967 self.assertEqual((Literal[0] | Literal[False]).__args__, 968 (Literal[0], Literal[False])) 969 self.assertEqual((Literal[1] | Literal[True]).__args__, 970 (Literal[1], Literal[True])) 971 972 self.assertEqual(Literal[1] | Literal[1], Literal[1]) 973 self.assertEqual(Literal['a'] | Literal['a'], Literal['a']) 974 975 import enum 976 class Ints(enum.IntEnum): 977 A = 0 978 B = 1 979 980 self.assertEqual(Literal[Ints.A] | Literal[Ints.A], Literal[Ints.A]) 981 self.assertEqual(Literal[Ints.B] | Literal[Ints.B], Literal[Ints.B]) 982 983 self.assertEqual((Literal[Ints.B] | Literal[Ints.A]).__args__, 984 (Literal[Ints.B], Literal[Ints.A])) 985 986 self.assertEqual((Literal[0] | Literal[Ints.A]).__args__, 987 (Literal[0], Literal[Ints.A])) 988 self.assertEqual((Literal[1] | Literal[Ints.B]).__args__, 989 (Literal[1], Literal[Ints.B])) 990 991 def test_or_type_repr(self): 992 self.assertEqual(repr(int | str), "int | str") 993 self.assertEqual(repr((int | str) | list), "int | str | list") 994 self.assertEqual(repr(int | (str | list)), "int | str | list") 995 self.assertEqual(repr(int | None), "int | None") 996 self.assertEqual(repr(int | type(None)), "int | None") 997 self.assertEqual(repr(int | typing.GenericAlias(list, int)), "int | list[int]") 998 999 def test_or_type_operator_with_genericalias(self): 1000 a = list[int] 1001 b = list[str] 1002 c = dict[float, str] 1003 class SubClass(types.GenericAlias): ... 1004 d = SubClass(list, float) 1005 # equivalence with typing.Union 1006 self.assertEqual(a | b | c | d, typing.Union[a, b, c, d]) 1007 # de-duplicate 1008 self.assertEqual(a | c | b | b | a | c | d | d, a | b | c | d) 1009 # order shouldn't matter 1010 self.assertEqual(a | b | d, b | a | d) 1011 self.assertEqual(repr(a | b | c | d), 1012 "list[int] | list[str] | dict[float, str] | list[float]") 1013 1014 class BadType(type): 1015 def __eq__(self, other): 1016 return 1 / 0 1017 1018 bt = BadType('bt', (), {}) 1019 # Comparison should fail and errors should propagate out for bad types. 1020 with self.assertRaises(ZeroDivisionError): 1021 list[int] | list[bt] 1022 1023 union_ga = (list[str] | int, collections.abc.Callable[..., str] | int, 1024 d | int) 1025 # Raise error when isinstance(type, genericalias | type) 1026 for type_ in union_ga: 1027 with self.subTest(f"check isinstance/issubclass is invalid for {type_}"): 1028 with self.assertRaises(TypeError): 1029 isinstance(1, type_) 1030 with self.assertRaises(TypeError): 1031 issubclass(int, type_) 1032 1033 def test_or_type_operator_with_bad_module(self): 1034 class BadMeta(type): 1035 __qualname__ = 'TypeVar' 1036 @property 1037 def __module__(self): 1038 1 / 0 1039 TypeVar = BadMeta('TypeVar', (), {}) 1040 _SpecialForm = BadMeta('_SpecialForm', (), {}) 1041 # Crashes in Issue44483 1042 with self.assertRaises((TypeError, ZeroDivisionError)): 1043 str | TypeVar() 1044 with self.assertRaises((TypeError, ZeroDivisionError)): 1045 str | _SpecialForm() 1046 1047 @cpython_only 1048 def test_or_type_operator_reference_cycle(self): 1049 if not hasattr(sys, 'gettotalrefcount'): 1050 self.skipTest('Cannot get total reference count.') 1051 gc.collect() 1052 before = sys.gettotalrefcount() 1053 for _ in range(30): 1054 T = typing.TypeVar('T') 1055 U = int | list[T] 1056 T.blah = U 1057 del T 1058 del U 1059 gc.collect() 1060 leeway = 15 1061 self.assertLessEqual(sys.gettotalrefcount() - before, leeway, 1062 msg='Check for union reference leak.') 1063 1064 1065class MappingProxyTests(unittest.TestCase): 1066 mappingproxy = types.MappingProxyType 1067 1068 def test_constructor(self): 1069 class userdict(dict): 1070 pass 1071 1072 mapping = {'x': 1, 'y': 2} 1073 self.assertEqual(self.mappingproxy(mapping), mapping) 1074 mapping = userdict(x=1, y=2) 1075 self.assertEqual(self.mappingproxy(mapping), mapping) 1076 mapping = collections.ChainMap({'x': 1}, {'y': 2}) 1077 self.assertEqual(self.mappingproxy(mapping), mapping) 1078 1079 self.assertRaises(TypeError, self.mappingproxy, 10) 1080 self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple")) 1081 self.assertRaises(TypeError, self.mappingproxy, ["a", "list"]) 1082 1083 def test_methods(self): 1084 attrs = set(dir(self.mappingproxy({}))) - set(dir(object())) 1085 self.assertEqual(attrs, { 1086 '__contains__', 1087 '__getitem__', 1088 '__class_getitem__', 1089 '__ior__', 1090 '__iter__', 1091 '__len__', 1092 '__or__', 1093 '__reversed__', 1094 '__ror__', 1095 'copy', 1096 'get', 1097 'items', 1098 'keys', 1099 'values', 1100 }) 1101 1102 def test_get(self): 1103 view = self.mappingproxy({'a': 'A', 'b': 'B'}) 1104 self.assertEqual(view['a'], 'A') 1105 self.assertEqual(view['b'], 'B') 1106 self.assertRaises(KeyError, view.__getitem__, 'xxx') 1107 self.assertEqual(view.get('a'), 'A') 1108 self.assertIsNone(view.get('xxx')) 1109 self.assertEqual(view.get('xxx', 42), 42) 1110 1111 def test_missing(self): 1112 class dictmissing(dict): 1113 def __missing__(self, key): 1114 return "missing=%s" % key 1115 1116 view = self.mappingproxy(dictmissing(x=1)) 1117 self.assertEqual(view['x'], 1) 1118 self.assertEqual(view['y'], 'missing=y') 1119 self.assertEqual(view.get('x'), 1) 1120 self.assertEqual(view.get('y'), None) 1121 self.assertEqual(view.get('y', 42), 42) 1122 self.assertTrue('x' in view) 1123 self.assertFalse('y' in view) 1124 1125 def test_customdict(self): 1126 class customdict(dict): 1127 def __contains__(self, key): 1128 if key == 'magic': 1129 return True 1130 else: 1131 return dict.__contains__(self, key) 1132 1133 def __iter__(self): 1134 return iter(('iter',)) 1135 1136 def __len__(self): 1137 return 500 1138 1139 def copy(self): 1140 return 'copy' 1141 1142 def keys(self): 1143 return 'keys' 1144 1145 def items(self): 1146 return 'items' 1147 1148 def values(self): 1149 return 'values' 1150 1151 def __getitem__(self, key): 1152 return "getitem=%s" % dict.__getitem__(self, key) 1153 1154 def get(self, key, default=None): 1155 return "get=%s" % dict.get(self, key, 'default=%r' % default) 1156 1157 custom = customdict({'key': 'value'}) 1158 view = self.mappingproxy(custom) 1159 self.assertTrue('key' in view) 1160 self.assertTrue('magic' in view) 1161 self.assertFalse('xxx' in view) 1162 self.assertEqual(view['key'], 'getitem=value') 1163 self.assertRaises(KeyError, view.__getitem__, 'xxx') 1164 self.assertEqual(tuple(view), ('iter',)) 1165 self.assertEqual(len(view), 500) 1166 self.assertEqual(view.copy(), 'copy') 1167 self.assertEqual(view.get('key'), 'get=value') 1168 self.assertEqual(view.get('xxx'), 'get=default=None') 1169 self.assertEqual(view.items(), 'items') 1170 self.assertEqual(view.keys(), 'keys') 1171 self.assertEqual(view.values(), 'values') 1172 1173 def test_chainmap(self): 1174 d1 = {'x': 1} 1175 d2 = {'y': 2} 1176 mapping = collections.ChainMap(d1, d2) 1177 view = self.mappingproxy(mapping) 1178 self.assertTrue('x' in view) 1179 self.assertTrue('y' in view) 1180 self.assertFalse('z' in view) 1181 self.assertEqual(view['x'], 1) 1182 self.assertEqual(view['y'], 2) 1183 self.assertRaises(KeyError, view.__getitem__, 'z') 1184 self.assertEqual(tuple(sorted(view)), ('x', 'y')) 1185 self.assertEqual(len(view), 2) 1186 copy = view.copy() 1187 self.assertIsNot(copy, mapping) 1188 self.assertIsInstance(copy, collections.ChainMap) 1189 self.assertEqual(copy, mapping) 1190 self.assertEqual(view.get('x'), 1) 1191 self.assertEqual(view.get('y'), 2) 1192 self.assertIsNone(view.get('z')) 1193 self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2))) 1194 self.assertEqual(tuple(sorted(view.keys())), ('x', 'y')) 1195 self.assertEqual(tuple(sorted(view.values())), (1, 2)) 1196 1197 def test_contains(self): 1198 view = self.mappingproxy(dict.fromkeys('abc')) 1199 self.assertTrue('a' in view) 1200 self.assertTrue('b' in view) 1201 self.assertTrue('c' in view) 1202 self.assertFalse('xxx' in view) 1203 1204 def test_views(self): 1205 mapping = {} 1206 view = self.mappingproxy(mapping) 1207 keys = view.keys() 1208 values = view.values() 1209 items = view.items() 1210 self.assertEqual(list(keys), []) 1211 self.assertEqual(list(values), []) 1212 self.assertEqual(list(items), []) 1213 mapping['key'] = 'value' 1214 self.assertEqual(list(keys), ['key']) 1215 self.assertEqual(list(values), ['value']) 1216 self.assertEqual(list(items), [('key', 'value')]) 1217 1218 def test_len(self): 1219 for expected in range(6): 1220 data = dict.fromkeys('abcde'[:expected]) 1221 self.assertEqual(len(data), expected) 1222 view = self.mappingproxy(data) 1223 self.assertEqual(len(view), expected) 1224 1225 def test_iterators(self): 1226 keys = ('x', 'y') 1227 values = (1, 2) 1228 items = tuple(zip(keys, values)) 1229 view = self.mappingproxy(dict(items)) 1230 self.assertEqual(set(view), set(keys)) 1231 self.assertEqual(set(view.keys()), set(keys)) 1232 self.assertEqual(set(view.values()), set(values)) 1233 self.assertEqual(set(view.items()), set(items)) 1234 1235 def test_reversed(self): 1236 d = {'a': 1, 'b': 2, 'foo': 0, 'c': 3, 'd': 4} 1237 mp = self.mappingproxy(d) 1238 del d['foo'] 1239 r = reversed(mp) 1240 self.assertEqual(list(r), list('dcba')) 1241 self.assertRaises(StopIteration, next, r) 1242 1243 def test_copy(self): 1244 original = {'key1': 27, 'key2': 51, 'key3': 93} 1245 view = self.mappingproxy(original) 1246 copy = view.copy() 1247 self.assertEqual(type(copy), dict) 1248 self.assertEqual(copy, original) 1249 original['key1'] = 70 1250 self.assertEqual(view['key1'], 70) 1251 self.assertEqual(copy['key1'], 27) 1252 1253 def test_union(self): 1254 mapping = {'a': 0, 'b': 1, 'c': 2} 1255 view = self.mappingproxy(mapping) 1256 with self.assertRaises(TypeError): 1257 view | [('r', 2), ('d', 2)] 1258 with self.assertRaises(TypeError): 1259 [('r', 2), ('d', 2)] | view 1260 with self.assertRaises(TypeError): 1261 view |= [('r', 2), ('d', 2)] 1262 other = {'c': 3, 'p': 0} 1263 self.assertDictEqual(view | other, {'a': 0, 'b': 1, 'c': 3, 'p': 0}) 1264 self.assertDictEqual(other | view, {'c': 2, 'p': 0, 'a': 0, 'b': 1}) 1265 self.assertEqual(view, {'a': 0, 'b': 1, 'c': 2}) 1266 self.assertDictEqual(mapping, {'a': 0, 'b': 1, 'c': 2}) 1267 self.assertDictEqual(other, {'c': 3, 'p': 0}) 1268 1269 def test_hash(self): 1270 class HashableDict(dict): 1271 def __hash__(self): 1272 return 3844817361 1273 view = self.mappingproxy({'a': 1, 'b': 2}) 1274 self.assertRaises(TypeError, hash, view) 1275 mapping = HashableDict({'a': 1, 'b': 2}) 1276 view = self.mappingproxy(mapping) 1277 self.assertEqual(hash(view), hash(mapping)) 1278 1279 1280class ClassCreationTests(unittest.TestCase): 1281 1282 class Meta(type): 1283 def __init__(cls, name, bases, ns, **kw): 1284 super().__init__(name, bases, ns) 1285 @staticmethod 1286 def __new__(mcls, name, bases, ns, **kw): 1287 return super().__new__(mcls, name, bases, ns) 1288 @classmethod 1289 def __prepare__(mcls, name, bases, **kw): 1290 ns = super().__prepare__(name, bases) 1291 ns["y"] = 1 1292 ns.update(kw) 1293 return ns 1294 1295 def test_new_class_basics(self): 1296 C = types.new_class("C") 1297 self.assertEqual(C.__name__, "C") 1298 self.assertEqual(C.__bases__, (object,)) 1299 1300 def test_new_class_subclass(self): 1301 C = types.new_class("C", (int,)) 1302 self.assertTrue(issubclass(C, int)) 1303 1304 def test_new_class_meta(self): 1305 Meta = self.Meta 1306 settings = {"metaclass": Meta, "z": 2} 1307 # We do this twice to make sure the passed in dict isn't mutated 1308 for i in range(2): 1309 C = types.new_class("C" + str(i), (), settings) 1310 self.assertIsInstance(C, Meta) 1311 self.assertEqual(C.y, 1) 1312 self.assertEqual(C.z, 2) 1313 1314 def test_new_class_exec_body(self): 1315 Meta = self.Meta 1316 def func(ns): 1317 ns["x"] = 0 1318 C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func) 1319 self.assertIsInstance(C, Meta) 1320 self.assertEqual(C.x, 0) 1321 self.assertEqual(C.y, 1) 1322 self.assertEqual(C.z, 2) 1323 1324 def test_new_class_metaclass_keywords(self): 1325 #Test that keywords are passed to the metaclass: 1326 def meta_func(name, bases, ns, **kw): 1327 return name, bases, ns, kw 1328 res = types.new_class("X", 1329 (int, object), 1330 dict(metaclass=meta_func, x=0)) 1331 self.assertEqual(res, ("X", (int, object), {}, {"x": 0})) 1332 1333 def test_new_class_defaults(self): 1334 # Test defaults/keywords: 1335 C = types.new_class("C", (), {}, None) 1336 self.assertEqual(C.__name__, "C") 1337 self.assertEqual(C.__bases__, (object,)) 1338 1339 def test_new_class_meta_with_base(self): 1340 Meta = self.Meta 1341 def func(ns): 1342 ns["x"] = 0 1343 C = types.new_class(name="C", 1344 bases=(int,), 1345 kwds=dict(metaclass=Meta, z=2), 1346 exec_body=func) 1347 self.assertTrue(issubclass(C, int)) 1348 self.assertIsInstance(C, Meta) 1349 self.assertEqual(C.x, 0) 1350 self.assertEqual(C.y, 1) 1351 self.assertEqual(C.z, 2) 1352 1353 def test_new_class_with_mro_entry(self): 1354 class A: pass 1355 class C: 1356 def __mro_entries__(self, bases): 1357 return (A,) 1358 c = C() 1359 D = types.new_class('D', (c,), {}) 1360 self.assertEqual(D.__bases__, (A,)) 1361 self.assertEqual(D.__orig_bases__, (c,)) 1362 self.assertEqual(D.__mro__, (D, A, object)) 1363 1364 def test_new_class_with_mro_entry_genericalias(self): 1365 L1 = types.new_class('L1', (typing.List[int],), {}) 1366 self.assertEqual(L1.__bases__, (list, typing.Generic)) 1367 self.assertEqual(L1.__orig_bases__, (typing.List[int],)) 1368 self.assertEqual(L1.__mro__, (L1, list, typing.Generic, object)) 1369 1370 L2 = types.new_class('L2', (list[int],), {}) 1371 self.assertEqual(L2.__bases__, (list,)) 1372 self.assertEqual(L2.__orig_bases__, (list[int],)) 1373 self.assertEqual(L2.__mro__, (L2, list, object)) 1374 1375 def test_new_class_with_mro_entry_none(self): 1376 class A: pass 1377 class B: pass 1378 class C: 1379 def __mro_entries__(self, bases): 1380 return () 1381 c = C() 1382 D = types.new_class('D', (A, c, B), {}) 1383 self.assertEqual(D.__bases__, (A, B)) 1384 self.assertEqual(D.__orig_bases__, (A, c, B)) 1385 self.assertEqual(D.__mro__, (D, A, B, object)) 1386 1387 def test_new_class_with_mro_entry_error(self): 1388 class A: pass 1389 class C: 1390 def __mro_entries__(self, bases): 1391 return A 1392 c = C() 1393 with self.assertRaises(TypeError): 1394 types.new_class('D', (c,), {}) 1395 1396 def test_new_class_with_mro_entry_multiple(self): 1397 class A1: pass 1398 class A2: pass 1399 class B1: pass 1400 class B2: pass 1401 class A: 1402 def __mro_entries__(self, bases): 1403 return (A1, A2) 1404 class B: 1405 def __mro_entries__(self, bases): 1406 return (B1, B2) 1407 D = types.new_class('D', (A(), B()), {}) 1408 self.assertEqual(D.__bases__, (A1, A2, B1, B2)) 1409 1410 def test_new_class_with_mro_entry_multiple_2(self): 1411 class A1: pass 1412 class A2: pass 1413 class A3: pass 1414 class B1: pass 1415 class B2: pass 1416 class A: 1417 def __mro_entries__(self, bases): 1418 return (A1, A2, A3) 1419 class B: 1420 def __mro_entries__(self, bases): 1421 return (B1, B2) 1422 class C: pass 1423 D = types.new_class('D', (A(), C, B()), {}) 1424 self.assertEqual(D.__bases__, (A1, A2, A3, C, B1, B2)) 1425 1426 def test_get_original_bases(self): 1427 T = typing.TypeVar('T') 1428 class A: pass 1429 class B(typing.Generic[T]): pass 1430 class C(B[int]): pass 1431 class D(B[str], float): pass 1432 1433 self.assertEqual(types.get_original_bases(A), (object,)) 1434 self.assertEqual(types.get_original_bases(B), (typing.Generic[T],)) 1435 self.assertEqual(types.get_original_bases(C), (B[int],)) 1436 self.assertEqual(types.get_original_bases(int), (object,)) 1437 self.assertEqual(types.get_original_bases(D), (B[str], float)) 1438 1439 class E(list[T]): pass 1440 class F(list[int]): pass 1441 1442 self.assertEqual(types.get_original_bases(E), (list[T],)) 1443 self.assertEqual(types.get_original_bases(F), (list[int],)) 1444 1445 class FirstBase(typing.Generic[T]): pass 1446 class SecondBase(typing.Generic[T]): pass 1447 class First(FirstBase[int]): pass 1448 class Second(SecondBase[int]): pass 1449 class G(First, Second): pass 1450 self.assertEqual(types.get_original_bases(G), (First, Second)) 1451 1452 class First_(typing.Generic[T]): pass 1453 class Second_(typing.Generic[T]): pass 1454 class H(First_, Second_): pass 1455 self.assertEqual(types.get_original_bases(H), (First_, Second_)) 1456 1457 class ClassBasedNamedTuple(typing.NamedTuple): 1458 x: int 1459 1460 class GenericNamedTuple(typing.NamedTuple, typing.Generic[T]): 1461 x: T 1462 1463 CallBasedNamedTuple = typing.NamedTuple("CallBasedNamedTuple", [("x", int)]) 1464 1465 self.assertIs( 1466 types.get_original_bases(ClassBasedNamedTuple)[0], typing.NamedTuple 1467 ) 1468 self.assertEqual( 1469 types.get_original_bases(GenericNamedTuple), 1470 (typing.NamedTuple, typing.Generic[T]) 1471 ) 1472 self.assertIs( 1473 types.get_original_bases(CallBasedNamedTuple)[0], typing.NamedTuple 1474 ) 1475 1476 class ClassBasedTypedDict(typing.TypedDict): 1477 x: int 1478 1479 class GenericTypedDict(typing.TypedDict, typing.Generic[T]): 1480 x: T 1481 1482 CallBasedTypedDict = typing.TypedDict("CallBasedTypedDict", {"x": int}) 1483 1484 self.assertIs( 1485 types.get_original_bases(ClassBasedTypedDict)[0], 1486 typing.TypedDict 1487 ) 1488 self.assertEqual( 1489 types.get_original_bases(GenericTypedDict), 1490 (typing.TypedDict, typing.Generic[T]) 1491 ) 1492 self.assertIs( 1493 types.get_original_bases(CallBasedTypedDict)[0], 1494 typing.TypedDict 1495 ) 1496 1497 with self.assertRaisesRegex(TypeError, "Expected an instance of type"): 1498 types.get_original_bases(object()) 1499 1500 # Many of the following tests are derived from test_descr.py 1501 def test_prepare_class(self): 1502 # Basic test of metaclass derivation 1503 expected_ns = {} 1504 class A(type): 1505 def __new__(*args, **kwargs): 1506 return type.__new__(*args, **kwargs) 1507 1508 def __prepare__(*args): 1509 return expected_ns 1510 1511 B = types.new_class("B", (object,)) 1512 C = types.new_class("C", (object,), {"metaclass": A}) 1513 1514 # The most derived metaclass of D is A rather than type. 1515 meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type}) 1516 self.assertIs(meta, A) 1517 self.assertIs(ns, expected_ns) 1518 self.assertEqual(len(kwds), 0) 1519 1520 def test_bad___prepare__(self): 1521 # __prepare__() must return a mapping. 1522 class BadMeta(type): 1523 @classmethod 1524 def __prepare__(*args): 1525 return None 1526 with self.assertRaisesRegex(TypeError, 1527 r'^BadMeta\.__prepare__\(\) must ' 1528 r'return a mapping, not NoneType$'): 1529 class Foo(metaclass=BadMeta): 1530 pass 1531 # Also test the case in which the metaclass is not a type. 1532 class BadMeta: 1533 @classmethod 1534 def __prepare__(*args): 1535 return None 1536 with self.assertRaisesRegex(TypeError, 1537 r'^<metaclass>\.__prepare__\(\) must ' 1538 r'return a mapping, not NoneType$'): 1539 class Bar(metaclass=BadMeta()): 1540 pass 1541 1542 def test_resolve_bases(self): 1543 class A: pass 1544 class B: pass 1545 class C: 1546 def __mro_entries__(self, bases): 1547 if A in bases: 1548 return () 1549 return (A,) 1550 c = C() 1551 self.assertEqual(types.resolve_bases(()), ()) 1552 self.assertEqual(types.resolve_bases((c,)), (A,)) 1553 self.assertEqual(types.resolve_bases((C,)), (C,)) 1554 self.assertEqual(types.resolve_bases((A, C)), (A, C)) 1555 self.assertEqual(types.resolve_bases((c, A)), (A,)) 1556 self.assertEqual(types.resolve_bases((A, c)), (A,)) 1557 x = (A,) 1558 y = (C,) 1559 z = (A, C) 1560 t = (A, C, B) 1561 for bases in [x, y, z, t]: 1562 self.assertIs(types.resolve_bases(bases), bases) 1563 1564 def test_resolve_bases_with_mro_entry(self): 1565 self.assertEqual(types.resolve_bases((typing.List[int],)), 1566 (list, typing.Generic)) 1567 self.assertEqual(types.resolve_bases((list[int],)), (list,)) 1568 1569 def test_metaclass_derivation(self): 1570 # issue1294232: correct metaclass calculation 1571 new_calls = [] # to check the order of __new__ calls 1572 class AMeta(type): 1573 def __new__(mcls, name, bases, ns): 1574 new_calls.append('AMeta') 1575 return super().__new__(mcls, name, bases, ns) 1576 @classmethod 1577 def __prepare__(mcls, name, bases): 1578 return {} 1579 1580 class BMeta(AMeta): 1581 def __new__(mcls, name, bases, ns): 1582 new_calls.append('BMeta') 1583 return super().__new__(mcls, name, bases, ns) 1584 @classmethod 1585 def __prepare__(mcls, name, bases): 1586 ns = super().__prepare__(name, bases) 1587 ns['BMeta_was_here'] = True 1588 return ns 1589 1590 A = types.new_class("A", (), {"metaclass": AMeta}) 1591 self.assertEqual(new_calls, ['AMeta']) 1592 new_calls.clear() 1593 1594 B = types.new_class("B", (), {"metaclass": BMeta}) 1595 # BMeta.__new__ calls AMeta.__new__ with super: 1596 self.assertEqual(new_calls, ['BMeta', 'AMeta']) 1597 new_calls.clear() 1598 1599 C = types.new_class("C", (A, B)) 1600 # The most derived metaclass is BMeta: 1601 self.assertEqual(new_calls, ['BMeta', 'AMeta']) 1602 new_calls.clear() 1603 # BMeta.__prepare__ should've been called: 1604 self.assertIn('BMeta_was_here', C.__dict__) 1605 1606 # The order of the bases shouldn't matter: 1607 C2 = types.new_class("C2", (B, A)) 1608 self.assertEqual(new_calls, ['BMeta', 'AMeta']) 1609 new_calls.clear() 1610 self.assertIn('BMeta_was_here', C2.__dict__) 1611 1612 # Check correct metaclass calculation when a metaclass is declared: 1613 D = types.new_class("D", (C,), {"metaclass": type}) 1614 self.assertEqual(new_calls, ['BMeta', 'AMeta']) 1615 new_calls.clear() 1616 self.assertIn('BMeta_was_here', D.__dict__) 1617 1618 E = types.new_class("E", (C,), {"metaclass": AMeta}) 1619 self.assertEqual(new_calls, ['BMeta', 'AMeta']) 1620 new_calls.clear() 1621 self.assertIn('BMeta_was_here', E.__dict__) 1622 1623 def test_metaclass_override_function(self): 1624 # Special case: the given metaclass isn't a class, 1625 # so there is no metaclass calculation. 1626 class A(metaclass=self.Meta): 1627 pass 1628 1629 marker = object() 1630 def func(*args, **kwargs): 1631 return marker 1632 1633 X = types.new_class("X", (), {"metaclass": func}) 1634 Y = types.new_class("Y", (object,), {"metaclass": func}) 1635 Z = types.new_class("Z", (A,), {"metaclass": func}) 1636 self.assertIs(marker, X) 1637 self.assertIs(marker, Y) 1638 self.assertIs(marker, Z) 1639 1640 def test_metaclass_override_callable(self): 1641 # The given metaclass is a class, 1642 # but not a descendant of type. 1643 new_calls = [] # to check the order of __new__ calls 1644 prepare_calls = [] # to track __prepare__ calls 1645 class ANotMeta: 1646 def __new__(mcls, *args, **kwargs): 1647 new_calls.append('ANotMeta') 1648 return super().__new__(mcls) 1649 @classmethod 1650 def __prepare__(mcls, name, bases): 1651 prepare_calls.append('ANotMeta') 1652 return {} 1653 1654 class BNotMeta(ANotMeta): 1655 def __new__(mcls, *args, **kwargs): 1656 new_calls.append('BNotMeta') 1657 return super().__new__(mcls) 1658 @classmethod 1659 def __prepare__(mcls, name, bases): 1660 prepare_calls.append('BNotMeta') 1661 return super().__prepare__(name, bases) 1662 1663 A = types.new_class("A", (), {"metaclass": ANotMeta}) 1664 self.assertIs(ANotMeta, type(A)) 1665 self.assertEqual(prepare_calls, ['ANotMeta']) 1666 prepare_calls.clear() 1667 self.assertEqual(new_calls, ['ANotMeta']) 1668 new_calls.clear() 1669 1670 B = types.new_class("B", (), {"metaclass": BNotMeta}) 1671 self.assertIs(BNotMeta, type(B)) 1672 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta']) 1673 prepare_calls.clear() 1674 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta']) 1675 new_calls.clear() 1676 1677 C = types.new_class("C", (A, B)) 1678 self.assertIs(BNotMeta, type(C)) 1679 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta']) 1680 prepare_calls.clear() 1681 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta']) 1682 new_calls.clear() 1683 1684 C2 = types.new_class("C2", (B, A)) 1685 self.assertIs(BNotMeta, type(C2)) 1686 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta']) 1687 prepare_calls.clear() 1688 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta']) 1689 new_calls.clear() 1690 1691 # This is a TypeError, because of a metaclass conflict: 1692 # BNotMeta is neither a subclass, nor a superclass of type 1693 with self.assertRaises(TypeError): 1694 D = types.new_class("D", (C,), {"metaclass": type}) 1695 1696 E = types.new_class("E", (C,), {"metaclass": ANotMeta}) 1697 self.assertIs(BNotMeta, type(E)) 1698 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta']) 1699 prepare_calls.clear() 1700 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta']) 1701 new_calls.clear() 1702 1703 F = types.new_class("F", (object(), C)) 1704 self.assertIs(BNotMeta, type(F)) 1705 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta']) 1706 prepare_calls.clear() 1707 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta']) 1708 new_calls.clear() 1709 1710 F2 = types.new_class("F2", (C, object())) 1711 self.assertIs(BNotMeta, type(F2)) 1712 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta']) 1713 prepare_calls.clear() 1714 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta']) 1715 new_calls.clear() 1716 1717 # TypeError: BNotMeta is neither a 1718 # subclass, nor a superclass of int 1719 with self.assertRaises(TypeError): 1720 X = types.new_class("X", (C, int())) 1721 with self.assertRaises(TypeError): 1722 X = types.new_class("X", (int(), C)) 1723 1724 def test_one_argument_type(self): 1725 expected_message = 'type.__new__() takes exactly 3 arguments (1 given)' 1726 1727 # Only type itself can use the one-argument form (#27157) 1728 self.assertIs(type(5), int) 1729 1730 class M(type): 1731 pass 1732 with self.assertRaises(TypeError) as cm: 1733 M(5) 1734 self.assertEqual(str(cm.exception), expected_message) 1735 1736 class N(type, metaclass=M): 1737 pass 1738 with self.assertRaises(TypeError) as cm: 1739 N(5) 1740 self.assertEqual(str(cm.exception), expected_message) 1741 1742 def test_metaclass_new_error(self): 1743 # bpo-44232: The C function type_new() must properly report the 1744 # exception when a metaclass constructor raises an exception and the 1745 # winner class is not the metaclass. 1746 class ModelBase(type): 1747 def __new__(cls, name, bases, attrs): 1748 super_new = super().__new__ 1749 new_class = super_new(cls, name, bases, {}) 1750 if name != "Model": 1751 raise RuntimeWarning(f"{name=}") 1752 return new_class 1753 1754 class Model(metaclass=ModelBase): 1755 pass 1756 1757 with self.assertRaises(RuntimeWarning): 1758 type("SouthPonies", (Model,), {}) 1759 1760 1761class SimpleNamespaceTests(unittest.TestCase): 1762 1763 def test_constructor(self): 1764 def check(ns, expected): 1765 self.assertEqual(len(ns.__dict__), len(expected)) 1766 self.assertEqual(vars(ns), expected) 1767 # check order 1768 self.assertEqual(list(vars(ns).items()), list(expected.items())) 1769 for name in expected: 1770 self.assertEqual(getattr(ns, name), expected[name]) 1771 1772 check(types.SimpleNamespace(), {}) 1773 check(types.SimpleNamespace(x=1, y=2), {'x': 1, 'y': 2}) 1774 check(types.SimpleNamespace(**dict(x=1, y=2)), {'x': 1, 'y': 2}) 1775 check(types.SimpleNamespace({'x': 1, 'y': 2}, x=4, z=3), 1776 {'x': 4, 'y': 2, 'z': 3}) 1777 check(types.SimpleNamespace([['x', 1], ['y', 2]], x=4, z=3), 1778 {'x': 4, 'y': 2, 'z': 3}) 1779 check(types.SimpleNamespace(UserDict({'x': 1, 'y': 2}), x=4, z=3), 1780 {'x': 4, 'y': 2, 'z': 3}) 1781 check(types.SimpleNamespace({'x': 1, 'y': 2}), {'x': 1, 'y': 2}) 1782 check(types.SimpleNamespace([['x', 1], ['y', 2]]), {'x': 1, 'y': 2}) 1783 check(types.SimpleNamespace([], x=4, z=3), {'x': 4, 'z': 3}) 1784 check(types.SimpleNamespace({}, x=4, z=3), {'x': 4, 'z': 3}) 1785 check(types.SimpleNamespace([]), {}) 1786 check(types.SimpleNamespace({}), {}) 1787 1788 with self.assertRaises(TypeError): 1789 types.SimpleNamespace([], []) # too many positional arguments 1790 with self.assertRaises(TypeError): 1791 types.SimpleNamespace(1) # not a mapping or iterable 1792 with self.assertRaises(TypeError): 1793 types.SimpleNamespace([1]) # non-iterable 1794 with self.assertRaises(ValueError): 1795 types.SimpleNamespace([['x']]) # not a pair 1796 with self.assertRaises(ValueError): 1797 types.SimpleNamespace([['x', 'y', 'z']]) 1798 with self.assertRaises(TypeError): 1799 types.SimpleNamespace(**{1: 2}) # non-string key 1800 with self.assertRaises(TypeError): 1801 types.SimpleNamespace({1: 2}) 1802 with self.assertRaises(TypeError): 1803 types.SimpleNamespace([[1, 2]]) 1804 with self.assertRaises(TypeError): 1805 types.SimpleNamespace(UserDict({1: 2})) 1806 with self.assertRaises(TypeError): 1807 types.SimpleNamespace([[[], 2]]) # non-hashable key 1808 1809 def test_unbound(self): 1810 ns1 = vars(types.SimpleNamespace()) 1811 ns2 = vars(types.SimpleNamespace(x=1, y=2)) 1812 1813 self.assertEqual(ns1, {}) 1814 self.assertEqual(ns2, {'y': 2, 'x': 1}) 1815 1816 def test_underlying_dict(self): 1817 ns1 = types.SimpleNamespace() 1818 ns2 = types.SimpleNamespace(x=1, y=2) 1819 ns3 = types.SimpleNamespace(a=True, b=False) 1820 mapping = ns3.__dict__ 1821 del ns3 1822 1823 self.assertEqual(ns1.__dict__, {}) 1824 self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1}) 1825 self.assertEqual(mapping, dict(a=True, b=False)) 1826 1827 def test_attrget(self): 1828 ns = types.SimpleNamespace(x=1, y=2, w=3) 1829 1830 self.assertEqual(ns.x, 1) 1831 self.assertEqual(ns.y, 2) 1832 self.assertEqual(ns.w, 3) 1833 with self.assertRaises(AttributeError): 1834 ns.z 1835 1836 def test_attrset(self): 1837 ns1 = types.SimpleNamespace() 1838 ns2 = types.SimpleNamespace(x=1, y=2, w=3) 1839 ns1.a = 'spam' 1840 ns1.b = 'ham' 1841 ns2.z = 4 1842 ns2.theta = None 1843 1844 self.assertEqual(ns1.__dict__, dict(a='spam', b='ham')) 1845 self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None)) 1846 1847 def test_attrdel(self): 1848 ns1 = types.SimpleNamespace() 1849 ns2 = types.SimpleNamespace(x=1, y=2, w=3) 1850 1851 with self.assertRaises(AttributeError): 1852 del ns1.spam 1853 with self.assertRaises(AttributeError): 1854 del ns2.spam 1855 1856 del ns2.y 1857 self.assertEqual(vars(ns2), dict(w=3, x=1)) 1858 ns2.y = 'spam' 1859 self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam')) 1860 del ns2.y 1861 self.assertEqual(vars(ns2), dict(w=3, x=1)) 1862 1863 ns1.spam = 5 1864 self.assertEqual(vars(ns1), dict(spam=5)) 1865 del ns1.spam 1866 self.assertEqual(vars(ns1), {}) 1867 1868 def test_repr(self): 1869 ns1 = types.SimpleNamespace(x=1, y=2, w=3) 1870 ns2 = types.SimpleNamespace() 1871 ns2.x = "spam" 1872 ns2._y = 5 1873 name = "namespace" 1874 1875 self.assertEqual(repr(ns1), "{name}(x=1, y=2, w=3)".format(name=name)) 1876 self.assertEqual(repr(ns2), "{name}(x='spam', _y=5)".format(name=name)) 1877 1878 def test_equal(self): 1879 ns1 = types.SimpleNamespace(x=1) 1880 ns2 = types.SimpleNamespace() 1881 ns2.x = 1 1882 1883 self.assertEqual(types.SimpleNamespace(), types.SimpleNamespace()) 1884 self.assertEqual(ns1, ns2) 1885 self.assertNotEqual(ns2, types.SimpleNamespace()) 1886 1887 def test_nested(self): 1888 ns1 = types.SimpleNamespace(a=1, b=2) 1889 ns2 = types.SimpleNamespace() 1890 ns3 = types.SimpleNamespace(x=ns1) 1891 ns2.spam = ns1 1892 ns2.ham = '?' 1893 ns2.spam = ns3 1894 1895 self.assertEqual(vars(ns1), dict(a=1, b=2)) 1896 self.assertEqual(vars(ns2), dict(spam=ns3, ham='?')) 1897 self.assertEqual(ns2.spam, ns3) 1898 self.assertEqual(vars(ns3), dict(x=ns1)) 1899 self.assertEqual(ns3.x.a, 1) 1900 1901 def test_recursive(self): 1902 ns1 = types.SimpleNamespace(c='cookie') 1903 ns2 = types.SimpleNamespace() 1904 ns3 = types.SimpleNamespace(x=1) 1905 ns1.spam = ns1 1906 ns2.spam = ns3 1907 ns3.spam = ns2 1908 1909 self.assertEqual(ns1.spam, ns1) 1910 self.assertEqual(ns1.spam.spam, ns1) 1911 self.assertEqual(ns1.spam.spam, ns1.spam) 1912 self.assertEqual(ns2.spam, ns3) 1913 self.assertEqual(ns3.spam, ns2) 1914 self.assertEqual(ns2.spam.spam, ns2) 1915 1916 def test_recursive_repr(self): 1917 ns1 = types.SimpleNamespace(c='cookie') 1918 ns2 = types.SimpleNamespace() 1919 ns3 = types.SimpleNamespace(x=1) 1920 ns1.spam = ns1 1921 ns2.spam = ns3 1922 ns3.spam = ns2 1923 name = "namespace" 1924 repr1 = "{name}(c='cookie', spam={name}(...))".format(name=name) 1925 repr2 = "{name}(spam={name}(x=1, spam={name}(...)))".format(name=name) 1926 1927 self.assertEqual(repr(ns1), repr1) 1928 self.assertEqual(repr(ns2), repr2) 1929 1930 def test_as_dict(self): 1931 ns = types.SimpleNamespace(spam='spamspamspam') 1932 1933 with self.assertRaises(TypeError): 1934 len(ns) 1935 with self.assertRaises(TypeError): 1936 iter(ns) 1937 with self.assertRaises(TypeError): 1938 'spam' in ns 1939 with self.assertRaises(TypeError): 1940 ns['spam'] 1941 1942 def test_subclass(self): 1943 class Spam(types.SimpleNamespace): 1944 pass 1945 1946 spam = Spam(ham=8, eggs=9) 1947 1948 self.assertIs(type(spam), Spam) 1949 self.assertEqual(vars(spam), {'ham': 8, 'eggs': 9}) 1950 1951 def test_pickle(self): 1952 ns = types.SimpleNamespace(breakfast="spam", lunch="spam") 1953 1954 for protocol in range(pickle.HIGHEST_PROTOCOL + 1): 1955 pname = "protocol {}".format(protocol) 1956 try: 1957 ns_pickled = pickle.dumps(ns, protocol) 1958 except TypeError as e: 1959 raise TypeError(pname) from e 1960 ns_roundtrip = pickle.loads(ns_pickled) 1961 1962 self.assertEqual(ns, ns_roundtrip, pname) 1963 1964 def test_replace(self): 1965 ns = types.SimpleNamespace(x=11, y=22) 1966 1967 ns2 = copy.replace(ns) 1968 self.assertEqual(ns2, ns) 1969 self.assertIsNot(ns2, ns) 1970 self.assertIs(type(ns2), types.SimpleNamespace) 1971 self.assertEqual(vars(ns2), {'x': 11, 'y': 22}) 1972 ns2.x = 3 1973 self.assertEqual(ns.x, 11) 1974 ns.x = 4 1975 self.assertEqual(ns2.x, 3) 1976 1977 self.assertEqual(vars(copy.replace(ns, x=1)), {'x': 1, 'y': 22}) 1978 self.assertEqual(vars(copy.replace(ns, y=2)), {'x': 4, 'y': 2}) 1979 self.assertEqual(vars(copy.replace(ns, x=1, y=2)), {'x': 1, 'y': 2}) 1980 1981 def test_replace_subclass(self): 1982 class Spam(types.SimpleNamespace): 1983 pass 1984 1985 spam = Spam(ham=8, eggs=9) 1986 spam2 = copy.replace(spam, ham=5) 1987 1988 self.assertIs(type(spam2), Spam) 1989 self.assertEqual(vars(spam2), {'ham': 5, 'eggs': 9}) 1990 1991 def test_fake_namespace_compare(self): 1992 # Issue #24257: Incorrect use of PyObject_IsInstance() caused 1993 # SystemError. 1994 class FakeSimpleNamespace(str): 1995 __class__ = types.SimpleNamespace 1996 self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace()) 1997 self.assertTrue(types.SimpleNamespace() != FakeSimpleNamespace()) 1998 with self.assertRaises(TypeError): 1999 types.SimpleNamespace() < FakeSimpleNamespace() 2000 with self.assertRaises(TypeError): 2001 types.SimpleNamespace() <= FakeSimpleNamespace() 2002 with self.assertRaises(TypeError): 2003 types.SimpleNamespace() > FakeSimpleNamespace() 2004 with self.assertRaises(TypeError): 2005 types.SimpleNamespace() >= FakeSimpleNamespace() 2006 2007 2008class CoroutineTests(unittest.TestCase): 2009 def test_wrong_args(self): 2010 samples = [None, 1, object()] 2011 for sample in samples: 2012 with self.assertRaisesRegex(TypeError, 2013 'types.coroutine.*expects a callable'): 2014 types.coroutine(sample) 2015 2016 def test_non_gen_values(self): 2017 @types.coroutine 2018 def foo(): 2019 return 'spam' 2020 self.assertEqual(foo(), 'spam') 2021 2022 class Awaitable: 2023 def __await__(self): 2024 return () 2025 aw = Awaitable() 2026 @types.coroutine 2027 def foo(): 2028 return aw 2029 self.assertIs(aw, foo()) 2030 2031 # decorate foo second time 2032 foo = types.coroutine(foo) 2033 self.assertIs(aw, foo()) 2034 2035 def test_async_def(self): 2036 # Test that types.coroutine passes 'async def' coroutines 2037 # without modification 2038 2039 async def foo(): pass 2040 foo_code = foo.__code__ 2041 foo_flags = foo.__code__.co_flags 2042 decorated_foo = types.coroutine(foo) 2043 self.assertIs(foo, decorated_foo) 2044 self.assertEqual(foo.__code__.co_flags, foo_flags) 2045 self.assertIs(decorated_foo.__code__, foo_code) 2046 2047 foo_coro = foo() 2048 def bar(): return foo_coro 2049 for _ in range(2): 2050 bar = types.coroutine(bar) 2051 coro = bar() 2052 self.assertIs(foo_coro, coro) 2053 self.assertEqual(coro.cr_code.co_flags, foo_flags) 2054 coro.close() 2055 2056 def test_duck_coro(self): 2057 class CoroLike: 2058 def send(self): pass 2059 def throw(self): pass 2060 def close(self): pass 2061 def __await__(self): return self 2062 2063 coro = CoroLike() 2064 @types.coroutine 2065 def foo(): 2066 return coro 2067 self.assertIs(foo(), coro) 2068 self.assertIs(foo().__await__(), coro) 2069 2070 def test_duck_corogen(self): 2071 class CoroGenLike: 2072 def send(self): pass 2073 def throw(self): pass 2074 def close(self): pass 2075 def __await__(self): return self 2076 def __iter__(self): return self 2077 def __next__(self): pass 2078 2079 coro = CoroGenLike() 2080 @types.coroutine 2081 def foo(): 2082 return coro 2083 self.assertIs(foo(), coro) 2084 self.assertIs(foo().__await__(), coro) 2085 2086 def test_duck_gen(self): 2087 class GenLike: 2088 def send(self): pass 2089 def throw(self): pass 2090 def close(self): pass 2091 def __iter__(self): pass 2092 def __next__(self): pass 2093 2094 # Setup generator mock object 2095 gen = unittest.mock.MagicMock(GenLike) 2096 gen.__iter__ = lambda gen: gen 2097 gen.__name__ = 'gen' 2098 gen.__qualname__ = 'test.gen' 2099 self.assertIsInstance(gen, collections.abc.Generator) 2100 self.assertIs(gen, iter(gen)) 2101 2102 @types.coroutine 2103 def foo(): return gen 2104 2105 wrapper = foo() 2106 self.assertIsInstance(wrapper, types._GeneratorWrapper) 2107 self.assertIs(wrapper.__await__(), wrapper) 2108 # Wrapper proxies duck generators completely: 2109 self.assertIs(iter(wrapper), wrapper) 2110 2111 self.assertIsInstance(wrapper, collections.abc.Coroutine) 2112 self.assertIsInstance(wrapper, collections.abc.Awaitable) 2113 2114 self.assertIs(wrapper.__qualname__, gen.__qualname__) 2115 self.assertIs(wrapper.__name__, gen.__name__) 2116 2117 # Test AttributeErrors 2118 for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom', 2119 'cr_running', 'cr_frame', 'cr_code', 'cr_await'}: 2120 with self.assertRaises(AttributeError): 2121 getattr(wrapper, name) 2122 2123 # Test attributes pass-through 2124 gen.gi_running = object() 2125 gen.gi_frame = object() 2126 gen.gi_code = object() 2127 gen.gi_yieldfrom = object() 2128 self.assertIs(wrapper.gi_running, gen.gi_running) 2129 self.assertIs(wrapper.gi_frame, gen.gi_frame) 2130 self.assertIs(wrapper.gi_code, gen.gi_code) 2131 self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom) 2132 self.assertIs(wrapper.cr_running, gen.gi_running) 2133 self.assertIs(wrapper.cr_frame, gen.gi_frame) 2134 self.assertIs(wrapper.cr_code, gen.gi_code) 2135 self.assertIs(wrapper.cr_await, gen.gi_yieldfrom) 2136 2137 wrapper.close() 2138 gen.close.assert_called_once_with() 2139 2140 wrapper.send(1) 2141 gen.send.assert_called_once_with(1) 2142 gen.reset_mock() 2143 2144 next(wrapper) 2145 gen.__next__.assert_called_once_with() 2146 gen.reset_mock() 2147 2148 wrapper.throw(1, 2, 3) 2149 gen.throw.assert_called_once_with(1, 2, 3) 2150 gen.reset_mock() 2151 2152 wrapper.throw(1, 2) 2153 gen.throw.assert_called_once_with(1, 2) 2154 gen.reset_mock() 2155 2156 wrapper.throw(1) 2157 gen.throw.assert_called_once_with(1) 2158 gen.reset_mock() 2159 2160 # Test exceptions propagation 2161 error = Exception() 2162 gen.throw.side_effect = error 2163 try: 2164 wrapper.throw(1) 2165 except Exception as ex: 2166 self.assertIs(ex, error) 2167 else: 2168 self.fail('wrapper did not propagate an exception') 2169 2170 # Test invalid args 2171 gen.reset_mock() 2172 with self.assertRaises(TypeError): 2173 wrapper.throw() 2174 self.assertFalse(gen.throw.called) 2175 with self.assertRaises(TypeError): 2176 wrapper.close(1) 2177 self.assertFalse(gen.close.called) 2178 with self.assertRaises(TypeError): 2179 wrapper.send() 2180 self.assertFalse(gen.send.called) 2181 2182 # Test that we do not double wrap 2183 @types.coroutine 2184 def bar(): return wrapper 2185 self.assertIs(wrapper, bar()) 2186 2187 # Test weakrefs support 2188 ref = weakref.ref(wrapper) 2189 self.assertIs(ref(), wrapper) 2190 2191 def test_duck_functional_gen(self): 2192 class Generator: 2193 """Emulates the following generator (very clumsy): 2194 2195 def gen(fut): 2196 result = yield fut 2197 return result * 2 2198 """ 2199 def __init__(self, fut): 2200 self._i = 0 2201 self._fut = fut 2202 def __iter__(self): 2203 return self 2204 def __next__(self): 2205 return self.send(None) 2206 def send(self, v): 2207 try: 2208 if self._i == 0: 2209 assert v is None 2210 return self._fut 2211 if self._i == 1: 2212 raise StopIteration(v * 2) 2213 if self._i > 1: 2214 raise StopIteration 2215 finally: 2216 self._i += 1 2217 def throw(self, tp, *exc): 2218 self._i = 100 2219 if tp is not GeneratorExit: 2220 raise tp 2221 def close(self): 2222 self.throw(GeneratorExit) 2223 2224 @types.coroutine 2225 def foo(): return Generator('spam') 2226 2227 wrapper = foo() 2228 self.assertIsInstance(wrapper, types._GeneratorWrapper) 2229 2230 async def corofunc(): 2231 return await foo() + 100 2232 coro = corofunc() 2233 2234 self.assertEqual(coro.send(None), 'spam') 2235 try: 2236 coro.send(20) 2237 except StopIteration as ex: 2238 self.assertEqual(ex.args[0], 140) 2239 else: 2240 self.fail('StopIteration was expected') 2241 2242 def test_gen(self): 2243 def gen_func(): 2244 yield 1 2245 return (yield 2) 2246 gen = gen_func() 2247 @types.coroutine 2248 def foo(): return gen 2249 wrapper = foo() 2250 self.assertIsInstance(wrapper, types._GeneratorWrapper) 2251 self.assertIs(wrapper.__await__(), gen) 2252 2253 for name in ('__name__', '__qualname__', 'gi_code', 2254 'gi_running', 'gi_frame'): 2255 self.assertIs(getattr(foo(), name), 2256 getattr(gen, name)) 2257 self.assertIs(foo().cr_code, gen.gi_code) 2258 2259 self.assertEqual(next(wrapper), 1) 2260 self.assertEqual(wrapper.send(None), 2) 2261 with self.assertRaisesRegex(StopIteration, 'spam'): 2262 wrapper.send('spam') 2263 2264 gen = gen_func() 2265 wrapper = foo() 2266 wrapper.send(None) 2267 with self.assertRaisesRegex(Exception, 'ham'): 2268 wrapper.throw(Exception('ham')) 2269 2270 # decorate foo second time 2271 foo = types.coroutine(foo) 2272 self.assertIs(foo().__await__(), gen) 2273 2274 def test_returning_itercoro(self): 2275 @types.coroutine 2276 def gen(): 2277 yield 2278 2279 gencoro = gen() 2280 2281 @types.coroutine 2282 def foo(): 2283 return gencoro 2284 2285 self.assertIs(foo(), gencoro) 2286 2287 # decorate foo second time 2288 foo = types.coroutine(foo) 2289 self.assertIs(foo(), gencoro) 2290 2291 def test_genfunc(self): 2292 def gen(): yield 2293 self.assertIs(types.coroutine(gen), gen) 2294 self.assertIs(types.coroutine(types.coroutine(gen)), gen) 2295 2296 self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE) 2297 self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE) 2298 2299 g = gen() 2300 self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE) 2301 self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE) 2302 2303 self.assertIs(types.coroutine(gen), gen) 2304 2305 def test_wrapper_object(self): 2306 def gen(): 2307 yield 2308 @types.coroutine 2309 def coro(): 2310 return gen() 2311 2312 wrapper = coro() 2313 self.assertIn('GeneratorWrapper', repr(wrapper)) 2314 self.assertEqual(repr(wrapper), str(wrapper)) 2315 self.assertTrue(set(dir(wrapper)).issuperset({ 2316 '__await__', '__iter__', '__next__', 'cr_code', 'cr_running', 2317 'cr_frame', 'gi_code', 'gi_frame', 'gi_running', 'send', 2318 'close', 'throw'})) 2319 2320 2321class FunctionTests(unittest.TestCase): 2322 def test_function_type_defaults(self): 2323 def ex(a, /, b, *, c): 2324 return a + b + c 2325 2326 func = types.FunctionType( 2327 ex.__code__, {}, "func", (1, 2), None, {'c': 3}, 2328 ) 2329 2330 self.assertEqual(func(), 6) 2331 self.assertEqual(func.__defaults__, (1, 2)) 2332 self.assertEqual(func.__kwdefaults__, {'c': 3}) 2333 2334 func = types.FunctionType( 2335 ex.__code__, {}, "func", None, None, None, 2336 ) 2337 self.assertEqual(func.__defaults__, None) 2338 self.assertEqual(func.__kwdefaults__, None) 2339 2340 def test_function_type_wrong_defaults(self): 2341 def ex(a, /, b, *, c): 2342 return a + b + c 2343 2344 with self.assertRaisesRegex(TypeError, 'arg 4'): 2345 types.FunctionType( 2346 ex.__code__, {}, "func", 1, None, {'c': 3}, 2347 ) 2348 with self.assertRaisesRegex(TypeError, 'arg 6'): 2349 types.FunctionType( 2350 ex.__code__, {}, "func", None, None, 3, 2351 ) 2352 2353 2354class SubinterpreterTests(unittest.TestCase): 2355 2356 @classmethod 2357 def setUpClass(cls): 2358 global interpreters 2359 try: 2360 from test.support import interpreters 2361 except ModuleNotFoundError: 2362 raise unittest.SkipTest('subinterpreters required') 2363 import test.support.interpreters.channels 2364 2365 @cpython_only 2366 @no_rerun('channels (and queues) might have a refleak; see gh-122199') 2367 def test_static_types_inherited_slots(self): 2368 rch, sch = interpreters.channels.create() 2369 2370 slots = [] 2371 script = '' 2372 for cls in iter_builtin_types(): 2373 for slot, own in iter_slot_wrappers(cls): 2374 slots.append((cls, slot, own)) 2375 script += textwrap.dedent(f""" 2376 text = repr({cls.__name__}.{slot}) 2377 sch.send_nowait(({cls.__name__!r}, {slot!r}, text)) 2378 """) 2379 2380 exec(script) 2381 all_expected = [] 2382 for cls, slot, _ in slots: 2383 result = rch.recv() 2384 assert result == (cls.__name__, slot, result[-1]), (cls, slot, result) 2385 all_expected.append(result) 2386 2387 interp = interpreters.create() 2388 interp.exec('from test.support import interpreters') 2389 interp.prepare_main(sch=sch) 2390 interp.exec(script) 2391 2392 for i, (cls, slot, _) in enumerate(slots): 2393 with self.subTest(cls=cls, slot=slot): 2394 expected = all_expected[i] 2395 result = rch.recv() 2396 self.assertEqual(result, expected) 2397 2398 2399if __name__ == '__main__': 2400 unittest.main() 2401