1import builtins 2import copyreg 3import gc 4import itertools 5import math 6import pickle 7import random 8import string 9import sys 10import types 11import unittest 12import warnings 13import weakref 14 15from copy import deepcopy 16from test import support 17 18try: 19 import _testcapi 20except ImportError: 21 _testcapi = None 22 23 24class OperatorsTest(unittest.TestCase): 25 26 def __init__(self, *args, **kwargs): 27 unittest.TestCase.__init__(self, *args, **kwargs) 28 self.binops = { 29 'add': '+', 30 'sub': '-', 31 'mul': '*', 32 'matmul': '@', 33 'truediv': '/', 34 'floordiv': '//', 35 'divmod': 'divmod', 36 'pow': '**', 37 'lshift': '<<', 38 'rshift': '>>', 39 'and': '&', 40 'xor': '^', 41 'or': '|', 42 'cmp': 'cmp', 43 'lt': '<', 44 'le': '<=', 45 'eq': '==', 46 'ne': '!=', 47 'gt': '>', 48 'ge': '>=', 49 } 50 51 for name, expr in list(self.binops.items()): 52 if expr.islower(): 53 expr = expr + "(a, b)" 54 else: 55 expr = 'a %s b' % expr 56 self.binops[name] = expr 57 58 self.unops = { 59 'pos': '+', 60 'neg': '-', 61 'abs': 'abs', 62 'invert': '~', 63 'int': 'int', 64 'float': 'float', 65 } 66 67 for name, expr in list(self.unops.items()): 68 if expr.islower(): 69 expr = expr + "(a)" 70 else: 71 expr = '%s a' % expr 72 self.unops[name] = expr 73 74 def unop_test(self, a, res, expr="len(a)", meth="__len__"): 75 d = {'a': a} 76 self.assertEqual(eval(expr, d), res) 77 t = type(a) 78 m = getattr(t, meth) 79 80 # Find method in parent class 81 while meth not in t.__dict__: 82 t = t.__bases__[0] 83 # in some implementations (e.g. PyPy), 'm' can be a regular unbound 84 # method object; the getattr() below obtains its underlying function. 85 self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 86 self.assertEqual(m(a), res) 87 bm = getattr(a, meth) 88 self.assertEqual(bm(), res) 89 90 def binop_test(self, a, b, res, expr="a+b", meth="__add__"): 91 d = {'a': a, 'b': b} 92 93 self.assertEqual(eval(expr, d), res) 94 t = type(a) 95 m = getattr(t, meth) 96 while meth not in t.__dict__: 97 t = t.__bases__[0] 98 # in some implementations (e.g. PyPy), 'm' can be a regular unbound 99 # method object; the getattr() below obtains its underlying function. 100 self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 101 self.assertEqual(m(a, b), res) 102 bm = getattr(a, meth) 103 self.assertEqual(bm(b), res) 104 105 def sliceop_test(self, a, b, c, res, expr="a[b:c]", meth="__getitem__"): 106 d = {'a': a, 'b': b, 'c': c} 107 self.assertEqual(eval(expr, d), res) 108 t = type(a) 109 m = getattr(t, meth) 110 while meth not in t.__dict__: 111 t = t.__bases__[0] 112 # in some implementations (e.g. PyPy), 'm' can be a regular unbound 113 # method object; the getattr() below obtains its underlying function. 114 self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 115 self.assertEqual(m(a, slice(b, c)), res) 116 bm = getattr(a, meth) 117 self.assertEqual(bm(slice(b, c)), res) 118 119 def setop_test(self, a, b, res, stmt="a+=b", meth="__iadd__"): 120 d = {'a': deepcopy(a), 'b': b} 121 exec(stmt, d) 122 self.assertEqual(d['a'], res) 123 t = type(a) 124 m = getattr(t, meth) 125 while meth not in t.__dict__: 126 t = t.__bases__[0] 127 # in some implementations (e.g. PyPy), 'm' can be a regular unbound 128 # method object; the getattr() below obtains its underlying function. 129 self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 130 d['a'] = deepcopy(a) 131 m(d['a'], b) 132 self.assertEqual(d['a'], res) 133 d['a'] = deepcopy(a) 134 bm = getattr(d['a'], meth) 135 bm(b) 136 self.assertEqual(d['a'], res) 137 138 def set2op_test(self, a, b, c, res, stmt="a[b]=c", meth="__setitem__"): 139 d = {'a': deepcopy(a), 'b': b, 'c': c} 140 exec(stmt, d) 141 self.assertEqual(d['a'], res) 142 t = type(a) 143 m = getattr(t, meth) 144 while meth not in t.__dict__: 145 t = t.__bases__[0] 146 # in some implementations (e.g. PyPy), 'm' can be a regular unbound 147 # method object; the getattr() below obtains its underlying function. 148 self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 149 d['a'] = deepcopy(a) 150 m(d['a'], b, c) 151 self.assertEqual(d['a'], res) 152 d['a'] = deepcopy(a) 153 bm = getattr(d['a'], meth) 154 bm(b, c) 155 self.assertEqual(d['a'], res) 156 157 def setsliceop_test(self, a, b, c, d, res, stmt="a[b:c]=d", meth="__setitem__"): 158 dictionary = {'a': deepcopy(a), 'b': b, 'c': c, 'd': d} 159 exec(stmt, dictionary) 160 self.assertEqual(dictionary['a'], res) 161 t = type(a) 162 while meth not in t.__dict__: 163 t = t.__bases__[0] 164 m = getattr(t, meth) 165 # in some implementations (e.g. PyPy), 'm' can be a regular unbound 166 # method object; the getattr() below obtains its underlying function. 167 self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 168 dictionary['a'] = deepcopy(a) 169 m(dictionary['a'], slice(b, c), d) 170 self.assertEqual(dictionary['a'], res) 171 dictionary['a'] = deepcopy(a) 172 bm = getattr(dictionary['a'], meth) 173 bm(slice(b, c), d) 174 self.assertEqual(dictionary['a'], res) 175 176 def test_lists(self): 177 # Testing list operations... 178 # Asserts are within individual test methods 179 self.binop_test([1], [2], [1,2], "a+b", "__add__") 180 self.binop_test([1,2,3], 2, 1, "b in a", "__contains__") 181 self.binop_test([1,2,3], 4, 0, "b in a", "__contains__") 182 self.binop_test([1,2,3], 1, 2, "a[b]", "__getitem__") 183 self.sliceop_test([1,2,3], 0, 2, [1,2], "a[b:c]", "__getitem__") 184 self.setop_test([1], [2], [1,2], "a+=b", "__iadd__") 185 self.setop_test([1,2], 3, [1,2,1,2,1,2], "a*=b", "__imul__") 186 self.unop_test([1,2,3], 3, "len(a)", "__len__") 187 self.binop_test([1,2], 3, [1,2,1,2,1,2], "a*b", "__mul__") 188 self.binop_test([1,2], 3, [1,2,1,2,1,2], "b*a", "__rmul__") 189 self.set2op_test([1,2], 1, 3, [1,3], "a[b]=c", "__setitem__") 190 self.setsliceop_test([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d", 191 "__setitem__") 192 193 def test_dicts(self): 194 # Testing dict operations... 195 self.binop_test({1:2,3:4}, 1, 1, "b in a", "__contains__") 196 self.binop_test({1:2,3:4}, 2, 0, "b in a", "__contains__") 197 self.binop_test({1:2,3:4}, 1, 2, "a[b]", "__getitem__") 198 199 d = {1:2, 3:4} 200 l1 = [] 201 for i in list(d.keys()): 202 l1.append(i) 203 l = [] 204 for i in iter(d): 205 l.append(i) 206 self.assertEqual(l, l1) 207 l = [] 208 for i in d.__iter__(): 209 l.append(i) 210 self.assertEqual(l, l1) 211 l = [] 212 for i in dict.__iter__(d): 213 l.append(i) 214 self.assertEqual(l, l1) 215 d = {1:2, 3:4} 216 self.unop_test(d, 2, "len(a)", "__len__") 217 self.assertEqual(eval(repr(d), {}), d) 218 self.assertEqual(eval(d.__repr__(), {}), d) 219 self.set2op_test({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", 220 "__setitem__") 221 222 # Tests for unary and binary operators 223 def number_operators(self, a, b, skip=[]): 224 dict = {'a': a, 'b': b} 225 226 for name, expr in self.binops.items(): 227 if name not in skip: 228 name = "__%s__" % name 229 if hasattr(a, name): 230 res = eval(expr, dict) 231 self.binop_test(a, b, res, expr, name) 232 233 for name, expr in list(self.unops.items()): 234 if name not in skip: 235 name = "__%s__" % name 236 if hasattr(a, name): 237 res = eval(expr, dict) 238 self.unop_test(a, res, expr, name) 239 240 def test_ints(self): 241 # Testing int operations... 242 self.number_operators(100, 3) 243 # The following crashes in Python 2.2 244 self.assertEqual((1).__bool__(), 1) 245 self.assertEqual((0).__bool__(), 0) 246 # This returns 'NotImplemented' in Python 2.2 247 class C(int): 248 def __add__(self, other): 249 return NotImplemented 250 self.assertEqual(C(5), 5) 251 try: 252 C() + "" 253 except TypeError: 254 pass 255 else: 256 self.fail("NotImplemented should have caused TypeError") 257 258 def test_floats(self): 259 # Testing float operations... 260 self.number_operators(100.0, 3.0) 261 262 def test_complexes(self): 263 # Testing complex operations... 264 self.number_operators(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge', 265 'int', 'float', 266 'floordiv', 'divmod', 'mod']) 267 268 class Number(complex): 269 __slots__ = ['prec'] 270 def __new__(cls, *args, **kwds): 271 result = complex.__new__(cls, *args) 272 result.prec = kwds.get('prec', 12) 273 return result 274 def __repr__(self): 275 prec = self.prec 276 if self.imag == 0.0: 277 return "%.*g" % (prec, self.real) 278 if self.real == 0.0: 279 return "%.*gj" % (prec, self.imag) 280 return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag) 281 __str__ = __repr__ 282 283 a = Number(3.14, prec=6) 284 self.assertEqual(repr(a), "3.14") 285 self.assertEqual(a.prec, 6) 286 287 a = Number(a, prec=2) 288 self.assertEqual(repr(a), "3.1") 289 self.assertEqual(a.prec, 2) 290 291 a = Number(234.5) 292 self.assertEqual(repr(a), "234.5") 293 self.assertEqual(a.prec, 12) 294 295 def test_explicit_reverse_methods(self): 296 # see issue 9930 297 self.assertEqual(complex.__radd__(3j, 4.0), complex(4.0, 3.0)) 298 self.assertEqual(float.__rsub__(3.0, 1), -2.0) 299 300 @support.impl_detail("the module 'xxsubtype' is internal") 301 def test_spam_lists(self): 302 # Testing spamlist operations... 303 import copy, xxsubtype as spam 304 305 def spamlist(l, memo=None): 306 import xxsubtype as spam 307 return spam.spamlist(l) 308 309 # This is an ugly hack: 310 copy._deepcopy_dispatch[spam.spamlist] = spamlist 311 312 self.binop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b", 313 "__add__") 314 self.binop_test(spamlist([1,2,3]), 2, 1, "b in a", "__contains__") 315 self.binop_test(spamlist([1,2,3]), 4, 0, "b in a", "__contains__") 316 self.binop_test(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__") 317 self.sliceop_test(spamlist([1,2,3]), 0, 2, spamlist([1,2]), "a[b:c]", 318 "__getitem__") 319 self.setop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+=b", 320 "__iadd__") 321 self.setop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b", 322 "__imul__") 323 self.unop_test(spamlist([1,2,3]), 3, "len(a)", "__len__") 324 self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b", 325 "__mul__") 326 self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a", 327 "__rmul__") 328 self.set2op_test(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c", 329 "__setitem__") 330 self.setsliceop_test(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]), 331 spamlist([1,5,6,4]), "a[b:c]=d", "__setitem__") 332 # Test subclassing 333 class C(spam.spamlist): 334 def foo(self): return 1 335 a = C() 336 self.assertEqual(a, []) 337 self.assertEqual(a.foo(), 1) 338 a.append(100) 339 self.assertEqual(a, [100]) 340 self.assertEqual(a.getstate(), 0) 341 a.setstate(42) 342 self.assertEqual(a.getstate(), 42) 343 344 @support.impl_detail("the module 'xxsubtype' is internal") 345 def test_spam_dicts(self): 346 # Testing spamdict operations... 347 import copy, xxsubtype as spam 348 def spamdict(d, memo=None): 349 import xxsubtype as spam 350 sd = spam.spamdict() 351 for k, v in list(d.items()): 352 sd[k] = v 353 return sd 354 # This is an ugly hack: 355 copy._deepcopy_dispatch[spam.spamdict] = spamdict 356 357 self.binop_test(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__") 358 self.binop_test(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__") 359 self.binop_test(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__") 360 d = spamdict({1:2,3:4}) 361 l1 = [] 362 for i in list(d.keys()): 363 l1.append(i) 364 l = [] 365 for i in iter(d): 366 l.append(i) 367 self.assertEqual(l, l1) 368 l = [] 369 for i in d.__iter__(): 370 l.append(i) 371 self.assertEqual(l, l1) 372 l = [] 373 for i in type(spamdict({})).__iter__(d): 374 l.append(i) 375 self.assertEqual(l, l1) 376 straightd = {1:2, 3:4} 377 spamd = spamdict(straightd) 378 self.unop_test(spamd, 2, "len(a)", "__len__") 379 self.unop_test(spamd, repr(straightd), "repr(a)", "__repr__") 380 self.set2op_test(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}), 381 "a[b]=c", "__setitem__") 382 # Test subclassing 383 class C(spam.spamdict): 384 def foo(self): return 1 385 a = C() 386 self.assertEqual(list(a.items()), []) 387 self.assertEqual(a.foo(), 1) 388 a['foo'] = 'bar' 389 self.assertEqual(list(a.items()), [('foo', 'bar')]) 390 self.assertEqual(a.getstate(), 0) 391 a.setstate(100) 392 self.assertEqual(a.getstate(), 100) 393 394 def test_wrap_lenfunc_bad_cast(self): 395 self.assertEqual(range(sys.maxsize).__len__(), sys.maxsize) 396 397 398class ClassPropertiesAndMethods(unittest.TestCase): 399 400 def assertHasAttr(self, obj, name): 401 self.assertTrue(hasattr(obj, name), 402 '%r has no attribute %r' % (obj, name)) 403 404 def assertNotHasAttr(self, obj, name): 405 self.assertFalse(hasattr(obj, name), 406 '%r has unexpected attribute %r' % (obj, name)) 407 408 def test_python_dicts(self): 409 # Testing Python subclass of dict... 410 self.assertTrue(issubclass(dict, dict)) 411 self.assertIsInstance({}, dict) 412 d = dict() 413 self.assertEqual(d, {}) 414 self.assertIs(d.__class__, dict) 415 self.assertIsInstance(d, dict) 416 class C(dict): 417 state = -1 418 def __init__(self_local, *a, **kw): 419 if a: 420 self.assertEqual(len(a), 1) 421 self_local.state = a[0] 422 if kw: 423 for k, v in list(kw.items()): 424 self_local[v] = k 425 def __getitem__(self, key): 426 return self.get(key, 0) 427 def __setitem__(self_local, key, value): 428 self.assertIsInstance(key, type(0)) 429 dict.__setitem__(self_local, key, value) 430 def setstate(self, state): 431 self.state = state 432 def getstate(self): 433 return self.state 434 self.assertTrue(issubclass(C, dict)) 435 a1 = C(12) 436 self.assertEqual(a1.state, 12) 437 a2 = C(foo=1, bar=2) 438 self.assertEqual(a2[1] == 'foo' and a2[2], 'bar') 439 a = C() 440 self.assertEqual(a.state, -1) 441 self.assertEqual(a.getstate(), -1) 442 a.setstate(0) 443 self.assertEqual(a.state, 0) 444 self.assertEqual(a.getstate(), 0) 445 a.setstate(10) 446 self.assertEqual(a.state, 10) 447 self.assertEqual(a.getstate(), 10) 448 self.assertEqual(a[42], 0) 449 a[42] = 24 450 self.assertEqual(a[42], 24) 451 N = 50 452 for i in range(N): 453 a[i] = C() 454 for j in range(N): 455 a[i][j] = i*j 456 for i in range(N): 457 for j in range(N): 458 self.assertEqual(a[i][j], i*j) 459 460 def test_python_lists(self): 461 # Testing Python subclass of list... 462 class C(list): 463 def __getitem__(self, i): 464 if isinstance(i, slice): 465 return i.start, i.stop 466 return list.__getitem__(self, i) + 100 467 a = C() 468 a.extend([0,1,2]) 469 self.assertEqual(a[0], 100) 470 self.assertEqual(a[1], 101) 471 self.assertEqual(a[2], 102) 472 self.assertEqual(a[100:200], (100,200)) 473 474 def test_metaclass(self): 475 # Testing metaclasses... 476 class C(metaclass=type): 477 def __init__(self): 478 self.__state = 0 479 def getstate(self): 480 return self.__state 481 def setstate(self, state): 482 self.__state = state 483 a = C() 484 self.assertEqual(a.getstate(), 0) 485 a.setstate(10) 486 self.assertEqual(a.getstate(), 10) 487 class _metaclass(type): 488 def myself(cls): return cls 489 class D(metaclass=_metaclass): 490 pass 491 self.assertEqual(D.myself(), D) 492 d = D() 493 self.assertEqual(d.__class__, D) 494 class M1(type): 495 def __new__(cls, name, bases, dict): 496 dict['__spam__'] = 1 497 return type.__new__(cls, name, bases, dict) 498 class C(metaclass=M1): 499 pass 500 self.assertEqual(C.__spam__, 1) 501 c = C() 502 self.assertEqual(c.__spam__, 1) 503 504 class _instance(object): 505 pass 506 class M2(object): 507 @staticmethod 508 def __new__(cls, name, bases, dict): 509 self = object.__new__(cls) 510 self.name = name 511 self.bases = bases 512 self.dict = dict 513 return self 514 def __call__(self): 515 it = _instance() 516 # Early binding of methods 517 for key in self.dict: 518 if key.startswith("__"): 519 continue 520 setattr(it, key, self.dict[key].__get__(it, self)) 521 return it 522 class C(metaclass=M2): 523 def spam(self): 524 return 42 525 self.assertEqual(C.name, 'C') 526 self.assertEqual(C.bases, ()) 527 self.assertIn('spam', C.dict) 528 c = C() 529 self.assertEqual(c.spam(), 42) 530 531 # More metaclass examples 532 533 class autosuper(type): 534 # Automatically add __super to the class 535 # This trick only works for dynamic classes 536 def __new__(metaclass, name, bases, dict): 537 cls = super(autosuper, metaclass).__new__(metaclass, 538 name, bases, dict) 539 # Name mangling for __super removes leading underscores 540 while name[:1] == "_": 541 name = name[1:] 542 if name: 543 name = "_%s__super" % name 544 else: 545 name = "__super" 546 setattr(cls, name, super(cls)) 547 return cls 548 class A(metaclass=autosuper): 549 def meth(self): 550 return "A" 551 class B(A): 552 def meth(self): 553 return "B" + self.__super.meth() 554 class C(A): 555 def meth(self): 556 return "C" + self.__super.meth() 557 class D(C, B): 558 def meth(self): 559 return "D" + self.__super.meth() 560 self.assertEqual(D().meth(), "DCBA") 561 class E(B, C): 562 def meth(self): 563 return "E" + self.__super.meth() 564 self.assertEqual(E().meth(), "EBCA") 565 566 class autoproperty(type): 567 # Automatically create property attributes when methods 568 # named _get_x and/or _set_x are found 569 def __new__(metaclass, name, bases, dict): 570 hits = {} 571 for key, val in dict.items(): 572 if key.startswith("_get_"): 573 key = key[5:] 574 get, set = hits.get(key, (None, None)) 575 get = val 576 hits[key] = get, set 577 elif key.startswith("_set_"): 578 key = key[5:] 579 get, set = hits.get(key, (None, None)) 580 set = val 581 hits[key] = get, set 582 for key, (get, set) in hits.items(): 583 dict[key] = property(get, set) 584 return super(autoproperty, metaclass).__new__(metaclass, 585 name, bases, dict) 586 class A(metaclass=autoproperty): 587 def _get_x(self): 588 return -self.__x 589 def _set_x(self, x): 590 self.__x = -x 591 a = A() 592 self.assertNotHasAttr(a, "x") 593 a.x = 12 594 self.assertEqual(a.x, 12) 595 self.assertEqual(a._A__x, -12) 596 597 class multimetaclass(autoproperty, autosuper): 598 # Merge of multiple cooperating metaclasses 599 pass 600 class A(metaclass=multimetaclass): 601 def _get_x(self): 602 return "A" 603 class B(A): 604 def _get_x(self): 605 return "B" + self.__super._get_x() 606 class C(A): 607 def _get_x(self): 608 return "C" + self.__super._get_x() 609 class D(C, B): 610 def _get_x(self): 611 return "D" + self.__super._get_x() 612 self.assertEqual(D().x, "DCBA") 613 614 # Make sure type(x) doesn't call x.__class__.__init__ 615 class T(type): 616 counter = 0 617 def __init__(self, *args): 618 T.counter += 1 619 class C(metaclass=T): 620 pass 621 self.assertEqual(T.counter, 1) 622 a = C() 623 self.assertEqual(type(a), C) 624 self.assertEqual(T.counter, 1) 625 626 class C(object): pass 627 c = C() 628 try: c() 629 except TypeError: pass 630 else: self.fail("calling object w/o call method should raise " 631 "TypeError") 632 633 # Testing code to find most derived baseclass 634 class A(type): 635 def __new__(*args, **kwargs): 636 return type.__new__(*args, **kwargs) 637 638 class B(object): 639 pass 640 641 class C(object, metaclass=A): 642 pass 643 644 # The most derived metaclass of D is A rather than type. 645 class D(B, C): 646 pass 647 self.assertIs(A, type(D)) 648 649 # issue1294232: correct metaclass calculation 650 new_calls = [] # to check the order of __new__ calls 651 class AMeta(type): 652 @staticmethod 653 def __new__(mcls, name, bases, ns): 654 new_calls.append('AMeta') 655 return super().__new__(mcls, name, bases, ns) 656 @classmethod 657 def __prepare__(mcls, name, bases): 658 return {} 659 660 class BMeta(AMeta): 661 @staticmethod 662 def __new__(mcls, name, bases, ns): 663 new_calls.append('BMeta') 664 return super().__new__(mcls, name, bases, ns) 665 @classmethod 666 def __prepare__(mcls, name, bases): 667 ns = super().__prepare__(name, bases) 668 ns['BMeta_was_here'] = True 669 return ns 670 671 class A(metaclass=AMeta): 672 pass 673 self.assertEqual(['AMeta'], new_calls) 674 new_calls.clear() 675 676 class B(metaclass=BMeta): 677 pass 678 # BMeta.__new__ calls AMeta.__new__ with super: 679 self.assertEqual(['BMeta', 'AMeta'], new_calls) 680 new_calls.clear() 681 682 class C(A, B): 683 pass 684 # The most derived metaclass is BMeta: 685 self.assertEqual(['BMeta', 'AMeta'], new_calls) 686 new_calls.clear() 687 # BMeta.__prepare__ should've been called: 688 self.assertIn('BMeta_was_here', C.__dict__) 689 690 # The order of the bases shouldn't matter: 691 class C2(B, A): 692 pass 693 self.assertEqual(['BMeta', 'AMeta'], new_calls) 694 new_calls.clear() 695 self.assertIn('BMeta_was_here', C2.__dict__) 696 697 # Check correct metaclass calculation when a metaclass is declared: 698 class D(C, metaclass=type): 699 pass 700 self.assertEqual(['BMeta', 'AMeta'], new_calls) 701 new_calls.clear() 702 self.assertIn('BMeta_was_here', D.__dict__) 703 704 class E(C, metaclass=AMeta): 705 pass 706 self.assertEqual(['BMeta', 'AMeta'], new_calls) 707 new_calls.clear() 708 self.assertIn('BMeta_was_here', E.__dict__) 709 710 # Special case: the given metaclass isn't a class, 711 # so there is no metaclass calculation. 712 marker = object() 713 def func(*args, **kwargs): 714 return marker 715 class X(metaclass=func): 716 pass 717 class Y(object, metaclass=func): 718 pass 719 class Z(D, metaclass=func): 720 pass 721 self.assertIs(marker, X) 722 self.assertIs(marker, Y) 723 self.assertIs(marker, Z) 724 725 # The given metaclass is a class, 726 # but not a descendant of type. 727 prepare_calls = [] # to track __prepare__ calls 728 class ANotMeta: 729 def __new__(mcls, *args, **kwargs): 730 new_calls.append('ANotMeta') 731 return super().__new__(mcls) 732 @classmethod 733 def __prepare__(mcls, name, bases): 734 prepare_calls.append('ANotMeta') 735 return {} 736 class BNotMeta(ANotMeta): 737 def __new__(mcls, *args, **kwargs): 738 new_calls.append('BNotMeta') 739 return super().__new__(mcls) 740 @classmethod 741 def __prepare__(mcls, name, bases): 742 prepare_calls.append('BNotMeta') 743 return super().__prepare__(name, bases) 744 745 class A(metaclass=ANotMeta): 746 pass 747 self.assertIs(ANotMeta, type(A)) 748 self.assertEqual(['ANotMeta'], prepare_calls) 749 prepare_calls.clear() 750 self.assertEqual(['ANotMeta'], new_calls) 751 new_calls.clear() 752 753 class B(metaclass=BNotMeta): 754 pass 755 self.assertIs(BNotMeta, type(B)) 756 self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 757 prepare_calls.clear() 758 self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 759 new_calls.clear() 760 761 class C(A, B): 762 pass 763 self.assertIs(BNotMeta, type(C)) 764 self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 765 new_calls.clear() 766 self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 767 prepare_calls.clear() 768 769 class C2(B, A): 770 pass 771 self.assertIs(BNotMeta, type(C2)) 772 self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 773 new_calls.clear() 774 self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 775 prepare_calls.clear() 776 777 # This is a TypeError, because of a metaclass conflict: 778 # BNotMeta is neither a subclass, nor a superclass of type 779 with self.assertRaises(TypeError): 780 class D(C, metaclass=type): 781 pass 782 783 class E(C, metaclass=ANotMeta): 784 pass 785 self.assertIs(BNotMeta, type(E)) 786 self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 787 new_calls.clear() 788 self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 789 prepare_calls.clear() 790 791 class F(object(), C): 792 pass 793 self.assertIs(BNotMeta, type(F)) 794 self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 795 new_calls.clear() 796 self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 797 prepare_calls.clear() 798 799 class F2(C, object()): 800 pass 801 self.assertIs(BNotMeta, type(F2)) 802 self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 803 new_calls.clear() 804 self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 805 prepare_calls.clear() 806 807 # TypeError: BNotMeta is neither a 808 # subclass, nor a superclass of int 809 with self.assertRaises(TypeError): 810 class X(C, int()): 811 pass 812 with self.assertRaises(TypeError): 813 class X(int(), C): 814 pass 815 816 def test_module_subclasses(self): 817 # Testing Python subclass of module... 818 log = [] 819 MT = type(sys) 820 class MM(MT): 821 def __init__(self, name): 822 MT.__init__(self, name) 823 def __getattribute__(self, name): 824 log.append(("getattr", name)) 825 return MT.__getattribute__(self, name) 826 def __setattr__(self, name, value): 827 log.append(("setattr", name, value)) 828 MT.__setattr__(self, name, value) 829 def __delattr__(self, name): 830 log.append(("delattr", name)) 831 MT.__delattr__(self, name) 832 a = MM("a") 833 a.foo = 12 834 x = a.foo 835 del a.foo 836 self.assertEqual(log, [("setattr", "foo", 12), 837 ("getattr", "foo"), 838 ("delattr", "foo")]) 839 840 # http://python.org/sf/1174712 841 try: 842 class Module(types.ModuleType, str): 843 pass 844 except TypeError: 845 pass 846 else: 847 self.fail("inheriting from ModuleType and str at the same time " 848 "should fail") 849 850 # Issue 34805: Verify that definition order is retained 851 def random_name(): 852 return ''.join(random.choices(string.ascii_letters, k=10)) 853 class A: 854 pass 855 subclasses = [type(random_name(), (A,), {}) for i in range(100)] 856 self.assertEqual(A.__subclasses__(), subclasses) 857 858 def test_multiple_inheritance(self): 859 # Testing multiple inheritance... 860 class C(object): 861 def __init__(self): 862 self.__state = 0 863 def getstate(self): 864 return self.__state 865 def setstate(self, state): 866 self.__state = state 867 a = C() 868 self.assertEqual(a.getstate(), 0) 869 a.setstate(10) 870 self.assertEqual(a.getstate(), 10) 871 class D(dict, C): 872 def __init__(self): 873 type({}).__init__(self) 874 C.__init__(self) 875 d = D() 876 self.assertEqual(list(d.keys()), []) 877 d["hello"] = "world" 878 self.assertEqual(list(d.items()), [("hello", "world")]) 879 self.assertEqual(d["hello"], "world") 880 self.assertEqual(d.getstate(), 0) 881 d.setstate(10) 882 self.assertEqual(d.getstate(), 10) 883 self.assertEqual(D.__mro__, (D, dict, C, object)) 884 885 # SF bug #442833 886 class Node(object): 887 def __int__(self): 888 return int(self.foo()) 889 def foo(self): 890 return "23" 891 class Frag(Node, list): 892 def foo(self): 893 return "42" 894 self.assertEqual(Node().__int__(), 23) 895 self.assertEqual(int(Node()), 23) 896 self.assertEqual(Frag().__int__(), 42) 897 self.assertEqual(int(Frag()), 42) 898 899 def test_diamond_inheritance(self): 900 # Testing multiple inheritance special cases... 901 class A(object): 902 def spam(self): return "A" 903 self.assertEqual(A().spam(), "A") 904 class B(A): 905 def boo(self): return "B" 906 def spam(self): return "B" 907 self.assertEqual(B().spam(), "B") 908 self.assertEqual(B().boo(), "B") 909 class C(A): 910 def boo(self): return "C" 911 self.assertEqual(C().spam(), "A") 912 self.assertEqual(C().boo(), "C") 913 class D(B, C): pass 914 self.assertEqual(D().spam(), "B") 915 self.assertEqual(D().boo(), "B") 916 self.assertEqual(D.__mro__, (D, B, C, A, object)) 917 class E(C, B): pass 918 self.assertEqual(E().spam(), "B") 919 self.assertEqual(E().boo(), "C") 920 self.assertEqual(E.__mro__, (E, C, B, A, object)) 921 # MRO order disagreement 922 try: 923 class F(D, E): pass 924 except TypeError: 925 pass 926 else: 927 self.fail("expected MRO order disagreement (F)") 928 try: 929 class G(E, D): pass 930 except TypeError: 931 pass 932 else: 933 self.fail("expected MRO order disagreement (G)") 934 935 # see thread python-dev/2002-October/029035.html 936 def test_ex5_from_c3_switch(self): 937 # Testing ex5 from C3 switch discussion... 938 class A(object): pass 939 class B(object): pass 940 class C(object): pass 941 class X(A): pass 942 class Y(A): pass 943 class Z(X,B,Y,C): pass 944 self.assertEqual(Z.__mro__, (Z, X, B, Y, A, C, object)) 945 946 # see "A Monotonic Superclass Linearization for Dylan", 947 # by Kim Barrett et al. (OOPSLA 1996) 948 def test_monotonicity(self): 949 # Testing MRO monotonicity... 950 class Boat(object): pass 951 class DayBoat(Boat): pass 952 class WheelBoat(Boat): pass 953 class EngineLess(DayBoat): pass 954 class SmallMultihull(DayBoat): pass 955 class PedalWheelBoat(EngineLess,WheelBoat): pass 956 class SmallCatamaran(SmallMultihull): pass 957 class Pedalo(PedalWheelBoat,SmallCatamaran): pass 958 959 self.assertEqual(PedalWheelBoat.__mro__, 960 (PedalWheelBoat, EngineLess, DayBoat, WheelBoat, Boat, object)) 961 self.assertEqual(SmallCatamaran.__mro__, 962 (SmallCatamaran, SmallMultihull, DayBoat, Boat, object)) 963 self.assertEqual(Pedalo.__mro__, 964 (Pedalo, PedalWheelBoat, EngineLess, SmallCatamaran, 965 SmallMultihull, DayBoat, WheelBoat, Boat, object)) 966 967 # see "A Monotonic Superclass Linearization for Dylan", 968 # by Kim Barrett et al. (OOPSLA 1996) 969 def test_consistency_with_epg(self): 970 # Testing consistency with EPG... 971 class Pane(object): pass 972 class ScrollingMixin(object): pass 973 class EditingMixin(object): pass 974 class ScrollablePane(Pane,ScrollingMixin): pass 975 class EditablePane(Pane,EditingMixin): pass 976 class EditableScrollablePane(ScrollablePane,EditablePane): pass 977 978 self.assertEqual(EditableScrollablePane.__mro__, 979 (EditableScrollablePane, ScrollablePane, EditablePane, Pane, 980 ScrollingMixin, EditingMixin, object)) 981 982 def test_mro_disagreement(self): 983 # Testing error messages for MRO disagreement... 984 mro_err_msg = """Cannot create a consistent method resolution 985order (MRO) for bases """ 986 987 def raises(exc, expected, callable, *args): 988 try: 989 callable(*args) 990 except exc as msg: 991 # the exact msg is generally considered an impl detail 992 if support.check_impl_detail(): 993 if not str(msg).startswith(expected): 994 self.fail("Message %r, expected %r" % 995 (str(msg), expected)) 996 else: 997 self.fail("Expected %s" % exc) 998 999 class A(object): pass 1000 class B(A): pass 1001 class C(object): pass 1002 1003 # Test some very simple errors 1004 raises(TypeError, "duplicate base class A", 1005 type, "X", (A, A), {}) 1006 raises(TypeError, mro_err_msg, 1007 type, "X", (A, B), {}) 1008 raises(TypeError, mro_err_msg, 1009 type, "X", (A, C, B), {}) 1010 # Test a slightly more complex error 1011 class GridLayout(object): pass 1012 class HorizontalGrid(GridLayout): pass 1013 class VerticalGrid(GridLayout): pass 1014 class HVGrid(HorizontalGrid, VerticalGrid): pass 1015 class VHGrid(VerticalGrid, HorizontalGrid): pass 1016 raises(TypeError, mro_err_msg, 1017 type, "ConfusedGrid", (HVGrid, VHGrid), {}) 1018 1019 def test_object_class(self): 1020 # Testing object class... 1021 a = object() 1022 self.assertEqual(a.__class__, object) 1023 self.assertEqual(type(a), object) 1024 b = object() 1025 self.assertNotEqual(a, b) 1026 self.assertNotHasAttr(a, "foo") 1027 try: 1028 a.foo = 12 1029 except (AttributeError, TypeError): 1030 pass 1031 else: 1032 self.fail("object() should not allow setting a foo attribute") 1033 self.assertNotHasAttr(object(), "__dict__") 1034 1035 class Cdict(object): 1036 pass 1037 x = Cdict() 1038 self.assertEqual(x.__dict__, {}) 1039 x.foo = 1 1040 self.assertEqual(x.foo, 1) 1041 self.assertEqual(x.__dict__, {'foo': 1}) 1042 1043 def test_object_class_assignment_between_heaptypes_and_nonheaptypes(self): 1044 class SubType(types.ModuleType): 1045 a = 1 1046 1047 m = types.ModuleType("m") 1048 self.assertTrue(m.__class__ is types.ModuleType) 1049 self.assertFalse(hasattr(m, "a")) 1050 1051 m.__class__ = SubType 1052 self.assertTrue(m.__class__ is SubType) 1053 self.assertTrue(hasattr(m, "a")) 1054 1055 m.__class__ = types.ModuleType 1056 self.assertTrue(m.__class__ is types.ModuleType) 1057 self.assertFalse(hasattr(m, "a")) 1058 1059 # Make sure that builtin immutable objects don't support __class__ 1060 # assignment, because the object instances may be interned. 1061 # We set __slots__ = () to ensure that the subclasses are 1062 # memory-layout compatible, and thus otherwise reasonable candidates 1063 # for __class__ assignment. 1064 1065 # The following types have immutable instances, but are not 1066 # subclassable and thus don't need to be checked: 1067 # NoneType, bool 1068 1069 class MyInt(int): 1070 __slots__ = () 1071 with self.assertRaises(TypeError): 1072 (1).__class__ = MyInt 1073 1074 class MyFloat(float): 1075 __slots__ = () 1076 with self.assertRaises(TypeError): 1077 (1.0).__class__ = MyFloat 1078 1079 class MyComplex(complex): 1080 __slots__ = () 1081 with self.assertRaises(TypeError): 1082 (1 + 2j).__class__ = MyComplex 1083 1084 class MyStr(str): 1085 __slots__ = () 1086 with self.assertRaises(TypeError): 1087 "a".__class__ = MyStr 1088 1089 class MyBytes(bytes): 1090 __slots__ = () 1091 with self.assertRaises(TypeError): 1092 b"a".__class__ = MyBytes 1093 1094 class MyTuple(tuple): 1095 __slots__ = () 1096 with self.assertRaises(TypeError): 1097 ().__class__ = MyTuple 1098 1099 class MyFrozenSet(frozenset): 1100 __slots__ = () 1101 with self.assertRaises(TypeError): 1102 frozenset().__class__ = MyFrozenSet 1103 1104 def test_slots(self): 1105 # Testing __slots__... 1106 class C0(object): 1107 __slots__ = [] 1108 x = C0() 1109 self.assertNotHasAttr(x, "__dict__") 1110 self.assertNotHasAttr(x, "foo") 1111 1112 class C1(object): 1113 __slots__ = ['a'] 1114 x = C1() 1115 self.assertNotHasAttr(x, "__dict__") 1116 self.assertNotHasAttr(x, "a") 1117 x.a = 1 1118 self.assertEqual(x.a, 1) 1119 x.a = None 1120 self.assertEqual(x.a, None) 1121 del x.a 1122 self.assertNotHasAttr(x, "a") 1123 1124 class C3(object): 1125 __slots__ = ['a', 'b', 'c'] 1126 x = C3() 1127 self.assertNotHasAttr(x, "__dict__") 1128 self.assertNotHasAttr(x, 'a') 1129 self.assertNotHasAttr(x, 'b') 1130 self.assertNotHasAttr(x, 'c') 1131 x.a = 1 1132 x.b = 2 1133 x.c = 3 1134 self.assertEqual(x.a, 1) 1135 self.assertEqual(x.b, 2) 1136 self.assertEqual(x.c, 3) 1137 1138 class C4(object): 1139 """Validate name mangling""" 1140 __slots__ = ['__a'] 1141 def __init__(self, value): 1142 self.__a = value 1143 def get(self): 1144 return self.__a 1145 x = C4(5) 1146 self.assertNotHasAttr(x, '__dict__') 1147 self.assertNotHasAttr(x, '__a') 1148 self.assertEqual(x.get(), 5) 1149 try: 1150 x.__a = 6 1151 except AttributeError: 1152 pass 1153 else: 1154 self.fail("Double underscored names not mangled") 1155 1156 # Make sure slot names are proper identifiers 1157 try: 1158 class C(object): 1159 __slots__ = [None] 1160 except TypeError: 1161 pass 1162 else: 1163 self.fail("[None] slots not caught") 1164 try: 1165 class C(object): 1166 __slots__ = ["foo bar"] 1167 except TypeError: 1168 pass 1169 else: 1170 self.fail("['foo bar'] slots not caught") 1171 try: 1172 class C(object): 1173 __slots__ = ["foo\0bar"] 1174 except TypeError: 1175 pass 1176 else: 1177 self.fail("['foo\\0bar'] slots not caught") 1178 try: 1179 class C(object): 1180 __slots__ = ["1"] 1181 except TypeError: 1182 pass 1183 else: 1184 self.fail("['1'] slots not caught") 1185 try: 1186 class C(object): 1187 __slots__ = [""] 1188 except TypeError: 1189 pass 1190 else: 1191 self.fail("[''] slots not caught") 1192 class C(object): 1193 __slots__ = ["a", "a_b", "_a", "A0123456789Z"] 1194 # XXX(nnorwitz): was there supposed to be something tested 1195 # from the class above? 1196 1197 # Test a single string is not expanded as a sequence. 1198 class C(object): 1199 __slots__ = "abc" 1200 c = C() 1201 c.abc = 5 1202 self.assertEqual(c.abc, 5) 1203 1204 # Test unicode slot names 1205 # Test a single unicode string is not expanded as a sequence. 1206 class C(object): 1207 __slots__ = "abc" 1208 c = C() 1209 c.abc = 5 1210 self.assertEqual(c.abc, 5) 1211 1212 # _unicode_to_string used to modify slots in certain circumstances 1213 slots = ("foo", "bar") 1214 class C(object): 1215 __slots__ = slots 1216 x = C() 1217 x.foo = 5 1218 self.assertEqual(x.foo, 5) 1219 self.assertIs(type(slots[0]), str) 1220 # this used to leak references 1221 try: 1222 class C(object): 1223 __slots__ = [chr(128)] 1224 except (TypeError, UnicodeEncodeError): 1225 pass 1226 else: 1227 self.fail("[chr(128)] slots not caught") 1228 1229 # Test leaks 1230 class Counted(object): 1231 counter = 0 # counts the number of instances alive 1232 def __init__(self): 1233 Counted.counter += 1 1234 def __del__(self): 1235 Counted.counter -= 1 1236 class C(object): 1237 __slots__ = ['a', 'b', 'c'] 1238 x = C() 1239 x.a = Counted() 1240 x.b = Counted() 1241 x.c = Counted() 1242 self.assertEqual(Counted.counter, 3) 1243 del x 1244 support.gc_collect() 1245 self.assertEqual(Counted.counter, 0) 1246 class D(C): 1247 pass 1248 x = D() 1249 x.a = Counted() 1250 x.z = Counted() 1251 self.assertEqual(Counted.counter, 2) 1252 del x 1253 support.gc_collect() 1254 self.assertEqual(Counted.counter, 0) 1255 class E(D): 1256 __slots__ = ['e'] 1257 x = E() 1258 x.a = Counted() 1259 x.z = Counted() 1260 x.e = Counted() 1261 self.assertEqual(Counted.counter, 3) 1262 del x 1263 support.gc_collect() 1264 self.assertEqual(Counted.counter, 0) 1265 1266 # Test cyclical leaks [SF bug 519621] 1267 class F(object): 1268 __slots__ = ['a', 'b'] 1269 s = F() 1270 s.a = [Counted(), s] 1271 self.assertEqual(Counted.counter, 1) 1272 s = None 1273 support.gc_collect() 1274 self.assertEqual(Counted.counter, 0) 1275 1276 # Test lookup leaks [SF bug 572567] 1277 if hasattr(gc, 'get_objects'): 1278 class G(object): 1279 def __eq__(self, other): 1280 return False 1281 g = G() 1282 orig_objects = len(gc.get_objects()) 1283 for i in range(10): 1284 g==g 1285 new_objects = len(gc.get_objects()) 1286 self.assertEqual(orig_objects, new_objects) 1287 1288 class H(object): 1289 __slots__ = ['a', 'b'] 1290 def __init__(self): 1291 self.a = 1 1292 self.b = 2 1293 def __del__(self_): 1294 self.assertEqual(self_.a, 1) 1295 self.assertEqual(self_.b, 2) 1296 with support.captured_output('stderr') as s: 1297 h = H() 1298 del h 1299 self.assertEqual(s.getvalue(), '') 1300 1301 class X(object): 1302 __slots__ = "a" 1303 with self.assertRaises(AttributeError): 1304 del X().a 1305 1306 def test_slots_special(self): 1307 # Testing __dict__ and __weakref__ in __slots__... 1308 class D(object): 1309 __slots__ = ["__dict__"] 1310 a = D() 1311 self.assertHasAttr(a, "__dict__") 1312 self.assertNotHasAttr(a, "__weakref__") 1313 a.foo = 42 1314 self.assertEqual(a.__dict__, {"foo": 42}) 1315 1316 class W(object): 1317 __slots__ = ["__weakref__"] 1318 a = W() 1319 self.assertHasAttr(a, "__weakref__") 1320 self.assertNotHasAttr(a, "__dict__") 1321 try: 1322 a.foo = 42 1323 except AttributeError: 1324 pass 1325 else: 1326 self.fail("shouldn't be allowed to set a.foo") 1327 1328 class C1(W, D): 1329 __slots__ = [] 1330 a = C1() 1331 self.assertHasAttr(a, "__dict__") 1332 self.assertHasAttr(a, "__weakref__") 1333 a.foo = 42 1334 self.assertEqual(a.__dict__, {"foo": 42}) 1335 1336 class C2(D, W): 1337 __slots__ = [] 1338 a = C2() 1339 self.assertHasAttr(a, "__dict__") 1340 self.assertHasAttr(a, "__weakref__") 1341 a.foo = 42 1342 self.assertEqual(a.__dict__, {"foo": 42}) 1343 1344 def test_slots_special2(self): 1345 # Testing __qualname__ and __classcell__ in __slots__ 1346 class Meta(type): 1347 def __new__(cls, name, bases, namespace, attr): 1348 self.assertIn(attr, namespace) 1349 return super().__new__(cls, name, bases, namespace) 1350 1351 class C1: 1352 def __init__(self): 1353 self.b = 42 1354 class C2(C1, metaclass=Meta, attr="__classcell__"): 1355 __slots__ = ["__classcell__"] 1356 def __init__(self): 1357 super().__init__() 1358 self.assertIsInstance(C2.__dict__["__classcell__"], 1359 types.MemberDescriptorType) 1360 c = C2() 1361 self.assertEqual(c.b, 42) 1362 self.assertNotHasAttr(c, "__classcell__") 1363 c.__classcell__ = 42 1364 self.assertEqual(c.__classcell__, 42) 1365 with self.assertRaises(TypeError): 1366 class C3: 1367 __classcell__ = 42 1368 __slots__ = ["__classcell__"] 1369 1370 class Q1(metaclass=Meta, attr="__qualname__"): 1371 __slots__ = ["__qualname__"] 1372 self.assertEqual(Q1.__qualname__, C1.__qualname__[:-2] + "Q1") 1373 self.assertIsInstance(Q1.__dict__["__qualname__"], 1374 types.MemberDescriptorType) 1375 q = Q1() 1376 self.assertNotHasAttr(q, "__qualname__") 1377 q.__qualname__ = "q" 1378 self.assertEqual(q.__qualname__, "q") 1379 with self.assertRaises(TypeError): 1380 class Q2: 1381 __qualname__ = object() 1382 __slots__ = ["__qualname__"] 1383 1384 def test_slots_descriptor(self): 1385 # Issue2115: slot descriptors did not correctly check 1386 # the type of the given object 1387 import abc 1388 class MyABC(metaclass=abc.ABCMeta): 1389 __slots__ = "a" 1390 1391 class Unrelated(object): 1392 pass 1393 MyABC.register(Unrelated) 1394 1395 u = Unrelated() 1396 self.assertIsInstance(u, MyABC) 1397 1398 # This used to crash 1399 self.assertRaises(TypeError, MyABC.a.__set__, u, 3) 1400 1401 def test_dynamics(self): 1402 # Testing class attribute propagation... 1403 class D(object): 1404 pass 1405 class E(D): 1406 pass 1407 class F(D): 1408 pass 1409 D.foo = 1 1410 self.assertEqual(D.foo, 1) 1411 # Test that dynamic attributes are inherited 1412 self.assertEqual(E.foo, 1) 1413 self.assertEqual(F.foo, 1) 1414 # Test dynamic instances 1415 class C(object): 1416 pass 1417 a = C() 1418 self.assertNotHasAttr(a, "foobar") 1419 C.foobar = 2 1420 self.assertEqual(a.foobar, 2) 1421 C.method = lambda self: 42 1422 self.assertEqual(a.method(), 42) 1423 C.__repr__ = lambda self: "C()" 1424 self.assertEqual(repr(a), "C()") 1425 C.__int__ = lambda self: 100 1426 self.assertEqual(int(a), 100) 1427 self.assertEqual(a.foobar, 2) 1428 self.assertNotHasAttr(a, "spam") 1429 def mygetattr(self, name): 1430 if name == "spam": 1431 return "spam" 1432 raise AttributeError 1433 C.__getattr__ = mygetattr 1434 self.assertEqual(a.spam, "spam") 1435 a.new = 12 1436 self.assertEqual(a.new, 12) 1437 def mysetattr(self, name, value): 1438 if name == "spam": 1439 raise AttributeError 1440 return object.__setattr__(self, name, value) 1441 C.__setattr__ = mysetattr 1442 try: 1443 a.spam = "not spam" 1444 except AttributeError: 1445 pass 1446 else: 1447 self.fail("expected AttributeError") 1448 self.assertEqual(a.spam, "spam") 1449 class D(C): 1450 pass 1451 d = D() 1452 d.foo = 1 1453 self.assertEqual(d.foo, 1) 1454 1455 # Test handling of int*seq and seq*int 1456 class I(int): 1457 pass 1458 self.assertEqual("a"*I(2), "aa") 1459 self.assertEqual(I(2)*"a", "aa") 1460 self.assertEqual(2*I(3), 6) 1461 self.assertEqual(I(3)*2, 6) 1462 self.assertEqual(I(3)*I(2), 6) 1463 1464 # Test comparison of classes with dynamic metaclasses 1465 class dynamicmetaclass(type): 1466 pass 1467 class someclass(metaclass=dynamicmetaclass): 1468 pass 1469 self.assertNotEqual(someclass, object) 1470 1471 def test_errors(self): 1472 # Testing errors... 1473 try: 1474 class C(list, dict): 1475 pass 1476 except TypeError: 1477 pass 1478 else: 1479 self.fail("inheritance from both list and dict should be illegal") 1480 1481 try: 1482 class C(object, None): 1483 pass 1484 except TypeError: 1485 pass 1486 else: 1487 self.fail("inheritance from non-type should be illegal") 1488 class Classic: 1489 pass 1490 1491 try: 1492 class C(type(len)): 1493 pass 1494 except TypeError: 1495 pass 1496 else: 1497 self.fail("inheritance from CFunction should be illegal") 1498 1499 try: 1500 class C(object): 1501 __slots__ = 1 1502 except TypeError: 1503 pass 1504 else: 1505 self.fail("__slots__ = 1 should be illegal") 1506 1507 try: 1508 class C(object): 1509 __slots__ = [1] 1510 except TypeError: 1511 pass 1512 else: 1513 self.fail("__slots__ = [1] should be illegal") 1514 1515 class M1(type): 1516 pass 1517 class M2(type): 1518 pass 1519 class A1(object, metaclass=M1): 1520 pass 1521 class A2(object, metaclass=M2): 1522 pass 1523 try: 1524 class B(A1, A2): 1525 pass 1526 except TypeError: 1527 pass 1528 else: 1529 self.fail("finding the most derived metaclass should have failed") 1530 1531 def test_classmethods(self): 1532 # Testing class methods... 1533 class C(object): 1534 def foo(*a): return a 1535 goo = classmethod(foo) 1536 c = C() 1537 self.assertEqual(C.goo(1), (C, 1)) 1538 self.assertEqual(c.goo(1), (C, 1)) 1539 self.assertEqual(c.foo(1), (c, 1)) 1540 class D(C): 1541 pass 1542 d = D() 1543 self.assertEqual(D.goo(1), (D, 1)) 1544 self.assertEqual(d.goo(1), (D, 1)) 1545 self.assertEqual(d.foo(1), (d, 1)) 1546 self.assertEqual(D.foo(d, 1), (d, 1)) 1547 # Test for a specific crash (SF bug 528132) 1548 def f(cls, arg): return (cls, arg) 1549 ff = classmethod(f) 1550 self.assertEqual(ff.__get__(0, int)(42), (int, 42)) 1551 self.assertEqual(ff.__get__(0)(42), (int, 42)) 1552 1553 # Test super() with classmethods (SF bug 535444) 1554 self.assertEqual(C.goo.__self__, C) 1555 self.assertEqual(D.goo.__self__, D) 1556 self.assertEqual(super(D,D).goo.__self__, D) 1557 self.assertEqual(super(D,d).goo.__self__, D) 1558 self.assertEqual(super(D,D).goo(), (D,)) 1559 self.assertEqual(super(D,d).goo(), (D,)) 1560 1561 # Verify that a non-callable will raise 1562 meth = classmethod(1).__get__(1) 1563 self.assertRaises(TypeError, meth) 1564 1565 # Verify that classmethod() doesn't allow keyword args 1566 try: 1567 classmethod(f, kw=1) 1568 except TypeError: 1569 pass 1570 else: 1571 self.fail("classmethod shouldn't accept keyword args") 1572 1573 cm = classmethod(f) 1574 self.assertEqual(cm.__dict__, {}) 1575 cm.x = 42 1576 self.assertEqual(cm.x, 42) 1577 self.assertEqual(cm.__dict__, {"x" : 42}) 1578 del cm.x 1579 self.assertNotHasAttr(cm, "x") 1580 1581 @support.refcount_test 1582 def test_refleaks_in_classmethod___init__(self): 1583 gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') 1584 cm = classmethod(None) 1585 refs_before = gettotalrefcount() 1586 for i in range(100): 1587 cm.__init__(None) 1588 self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) 1589 1590 @support.impl_detail("the module 'xxsubtype' is internal") 1591 def test_classmethods_in_c(self): 1592 # Testing C-based class methods... 1593 import xxsubtype as spam 1594 a = (1, 2, 3) 1595 d = {'abc': 123} 1596 x, a1, d1 = spam.spamlist.classmeth(*a, **d) 1597 self.assertEqual(x, spam.spamlist) 1598 self.assertEqual(a, a1) 1599 self.assertEqual(d, d1) 1600 x, a1, d1 = spam.spamlist().classmeth(*a, **d) 1601 self.assertEqual(x, spam.spamlist) 1602 self.assertEqual(a, a1) 1603 self.assertEqual(d, d1) 1604 spam_cm = spam.spamlist.__dict__['classmeth'] 1605 x2, a2, d2 = spam_cm(spam.spamlist, *a, **d) 1606 self.assertEqual(x2, spam.spamlist) 1607 self.assertEqual(a2, a1) 1608 self.assertEqual(d2, d1) 1609 class SubSpam(spam.spamlist): pass 1610 x2, a2, d2 = spam_cm(SubSpam, *a, **d) 1611 self.assertEqual(x2, SubSpam) 1612 self.assertEqual(a2, a1) 1613 self.assertEqual(d2, d1) 1614 1615 with self.assertRaises(TypeError) as cm: 1616 spam_cm() 1617 self.assertEqual( 1618 str(cm.exception), 1619 "descriptor 'classmeth' of 'xxsubtype.spamlist' " 1620 "object needs an argument") 1621 1622 with self.assertRaises(TypeError) as cm: 1623 spam_cm(spam.spamlist()) 1624 self.assertEqual( 1625 str(cm.exception), 1626 "descriptor 'classmeth' for type 'xxsubtype.spamlist' " 1627 "needs a type, not a 'xxsubtype.spamlist' as arg 2") 1628 1629 with self.assertRaises(TypeError) as cm: 1630 spam_cm(list) 1631 expected_errmsg = ( 1632 "descriptor 'classmeth' requires a subtype of 'xxsubtype.spamlist' " 1633 "but received 'list'") 1634 self.assertEqual(str(cm.exception), expected_errmsg) 1635 1636 with self.assertRaises(TypeError) as cm: 1637 spam_cm.__get__(None, list) 1638 self.assertEqual(str(cm.exception), expected_errmsg) 1639 1640 def test_staticmethods(self): 1641 # Testing static methods... 1642 class C(object): 1643 def foo(*a): return a 1644 goo = staticmethod(foo) 1645 c = C() 1646 self.assertEqual(C.goo(1), (1,)) 1647 self.assertEqual(c.goo(1), (1,)) 1648 self.assertEqual(c.foo(1), (c, 1,)) 1649 class D(C): 1650 pass 1651 d = D() 1652 self.assertEqual(D.goo(1), (1,)) 1653 self.assertEqual(d.goo(1), (1,)) 1654 self.assertEqual(d.foo(1), (d, 1)) 1655 self.assertEqual(D.foo(d, 1), (d, 1)) 1656 sm = staticmethod(None) 1657 self.assertEqual(sm.__dict__, {}) 1658 sm.x = 42 1659 self.assertEqual(sm.x, 42) 1660 self.assertEqual(sm.__dict__, {"x" : 42}) 1661 del sm.x 1662 self.assertNotHasAttr(sm, "x") 1663 1664 @support.refcount_test 1665 def test_refleaks_in_staticmethod___init__(self): 1666 gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') 1667 sm = staticmethod(None) 1668 refs_before = gettotalrefcount() 1669 for i in range(100): 1670 sm.__init__(None) 1671 self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) 1672 1673 @support.impl_detail("the module 'xxsubtype' is internal") 1674 def test_staticmethods_in_c(self): 1675 # Testing C-based static methods... 1676 import xxsubtype as spam 1677 a = (1, 2, 3) 1678 d = {"abc": 123} 1679 x, a1, d1 = spam.spamlist.staticmeth(*a, **d) 1680 self.assertEqual(x, None) 1681 self.assertEqual(a, a1) 1682 self.assertEqual(d, d1) 1683 x, a1, d2 = spam.spamlist().staticmeth(*a, **d) 1684 self.assertEqual(x, None) 1685 self.assertEqual(a, a1) 1686 self.assertEqual(d, d1) 1687 1688 def test_classic(self): 1689 # Testing classic classes... 1690 class C: 1691 def foo(*a): return a 1692 goo = classmethod(foo) 1693 c = C() 1694 self.assertEqual(C.goo(1), (C, 1)) 1695 self.assertEqual(c.goo(1), (C, 1)) 1696 self.assertEqual(c.foo(1), (c, 1)) 1697 class D(C): 1698 pass 1699 d = D() 1700 self.assertEqual(D.goo(1), (D, 1)) 1701 self.assertEqual(d.goo(1), (D, 1)) 1702 self.assertEqual(d.foo(1), (d, 1)) 1703 self.assertEqual(D.foo(d, 1), (d, 1)) 1704 class E: # *not* subclassing from C 1705 foo = C.foo 1706 self.assertEqual(E().foo.__func__, C.foo) # i.e., unbound 1707 self.assertTrue(repr(C.foo.__get__(C())).startswith("<bound method ")) 1708 1709 def test_compattr(self): 1710 # Testing computed attributes... 1711 class C(object): 1712 class computed_attribute(object): 1713 def __init__(self, get, set=None, delete=None): 1714 self.__get = get 1715 self.__set = set 1716 self.__delete = delete 1717 def __get__(self, obj, type=None): 1718 return self.__get(obj) 1719 def __set__(self, obj, value): 1720 return self.__set(obj, value) 1721 def __delete__(self, obj): 1722 return self.__delete(obj) 1723 def __init__(self): 1724 self.__x = 0 1725 def __get_x(self): 1726 x = self.__x 1727 self.__x = x+1 1728 return x 1729 def __set_x(self, x): 1730 self.__x = x 1731 def __delete_x(self): 1732 del self.__x 1733 x = computed_attribute(__get_x, __set_x, __delete_x) 1734 a = C() 1735 self.assertEqual(a.x, 0) 1736 self.assertEqual(a.x, 1) 1737 a.x = 10 1738 self.assertEqual(a.x, 10) 1739 self.assertEqual(a.x, 11) 1740 del a.x 1741 self.assertNotHasAttr(a, 'x') 1742 1743 def test_newslots(self): 1744 # Testing __new__ slot override... 1745 class C(list): 1746 def __new__(cls): 1747 self = list.__new__(cls) 1748 self.foo = 1 1749 return self 1750 def __init__(self): 1751 self.foo = self.foo + 2 1752 a = C() 1753 self.assertEqual(a.foo, 3) 1754 self.assertEqual(a.__class__, C) 1755 class D(C): 1756 pass 1757 b = D() 1758 self.assertEqual(b.foo, 3) 1759 self.assertEqual(b.__class__, D) 1760 1761 @unittest.expectedFailure 1762 def test_bad_new(self): 1763 self.assertRaises(TypeError, object.__new__) 1764 self.assertRaises(TypeError, object.__new__, '') 1765 self.assertRaises(TypeError, list.__new__, object) 1766 self.assertRaises(TypeError, object.__new__, list) 1767 class C(object): 1768 __new__ = list.__new__ 1769 self.assertRaises(TypeError, C) 1770 class C(list): 1771 __new__ = object.__new__ 1772 self.assertRaises(TypeError, C) 1773 1774 def test_object_new(self): 1775 class A(object): 1776 pass 1777 object.__new__(A) 1778 self.assertRaises(TypeError, object.__new__, A, 5) 1779 object.__init__(A()) 1780 self.assertRaises(TypeError, object.__init__, A(), 5) 1781 1782 class A(object): 1783 def __init__(self, foo): 1784 self.foo = foo 1785 object.__new__(A) 1786 object.__new__(A, 5) 1787 object.__init__(A(3)) 1788 self.assertRaises(TypeError, object.__init__, A(3), 5) 1789 1790 class A(object): 1791 def __new__(cls, foo): 1792 return object.__new__(cls) 1793 object.__new__(A) 1794 self.assertRaises(TypeError, object.__new__, A, 5) 1795 object.__init__(A(3)) 1796 object.__init__(A(3), 5) 1797 1798 class A(object): 1799 def __new__(cls, foo): 1800 return object.__new__(cls) 1801 def __init__(self, foo): 1802 self.foo = foo 1803 object.__new__(A) 1804 self.assertRaises(TypeError, object.__new__, A, 5) 1805 object.__init__(A(3)) 1806 self.assertRaises(TypeError, object.__init__, A(3), 5) 1807 1808 @unittest.expectedFailure 1809 def test_restored_object_new(self): 1810 class A(object): 1811 def __new__(cls, *args, **kwargs): 1812 raise AssertionError 1813 self.assertRaises(AssertionError, A) 1814 class B(A): 1815 __new__ = object.__new__ 1816 def __init__(self, foo): 1817 self.foo = foo 1818 with warnings.catch_warnings(): 1819 warnings.simplefilter('error', DeprecationWarning) 1820 b = B(3) 1821 self.assertEqual(b.foo, 3) 1822 self.assertEqual(b.__class__, B) 1823 del B.__new__ 1824 self.assertRaises(AssertionError, B) 1825 del A.__new__ 1826 with warnings.catch_warnings(): 1827 warnings.simplefilter('error', DeprecationWarning) 1828 b = B(3) 1829 self.assertEqual(b.foo, 3) 1830 self.assertEqual(b.__class__, B) 1831 1832 def test_altmro(self): 1833 # Testing mro() and overriding it... 1834 class A(object): 1835 def f(self): return "A" 1836 class B(A): 1837 pass 1838 class C(A): 1839 def f(self): return "C" 1840 class D(B, C): 1841 pass 1842 self.assertEqual(A.mro(), [A, object]) 1843 self.assertEqual(A.__mro__, (A, object)) 1844 self.assertEqual(B.mro(), [B, A, object]) 1845 self.assertEqual(B.__mro__, (B, A, object)) 1846 self.assertEqual(C.mro(), [C, A, object]) 1847 self.assertEqual(C.__mro__, (C, A, object)) 1848 self.assertEqual(D.mro(), [D, B, C, A, object]) 1849 self.assertEqual(D.__mro__, (D, B, C, A, object)) 1850 self.assertEqual(D().f(), "C") 1851 1852 class PerverseMetaType(type): 1853 def mro(cls): 1854 L = type.mro(cls) 1855 L.reverse() 1856 return L 1857 class X(D,B,C,A, metaclass=PerverseMetaType): 1858 pass 1859 self.assertEqual(X.__mro__, (object, A, C, B, D, X)) 1860 self.assertEqual(X().f(), "A") 1861 1862 try: 1863 class _metaclass(type): 1864 def mro(self): 1865 return [self, dict, object] 1866 class X(object, metaclass=_metaclass): 1867 pass 1868 # In CPython, the class creation above already raises 1869 # TypeError, as a protection against the fact that 1870 # instances of X would segfault it. In other Python 1871 # implementations it would be ok to let the class X 1872 # be created, but instead get a clean TypeError on the 1873 # __setitem__ below. 1874 x = object.__new__(X) 1875 x[5] = 6 1876 except TypeError: 1877 pass 1878 else: 1879 self.fail("devious mro() return not caught") 1880 1881 try: 1882 class _metaclass(type): 1883 def mro(self): 1884 return [1] 1885 class X(object, metaclass=_metaclass): 1886 pass 1887 except TypeError: 1888 pass 1889 else: 1890 self.fail("non-class mro() return not caught") 1891 1892 try: 1893 class _metaclass(type): 1894 def mro(self): 1895 return 1 1896 class X(object, metaclass=_metaclass): 1897 pass 1898 except TypeError: 1899 pass 1900 else: 1901 self.fail("non-sequence mro() return not caught") 1902 1903 def test_overloading(self): 1904 # Testing operator overloading... 1905 1906 class B(object): 1907 "Intermediate class because object doesn't have a __setattr__" 1908 1909 class C(B): 1910 def __getattr__(self, name): 1911 if name == "foo": 1912 return ("getattr", name) 1913 else: 1914 raise AttributeError 1915 def __setattr__(self, name, value): 1916 if name == "foo": 1917 self.setattr = (name, value) 1918 else: 1919 return B.__setattr__(self, name, value) 1920 def __delattr__(self, name): 1921 if name == "foo": 1922 self.delattr = name 1923 else: 1924 return B.__delattr__(self, name) 1925 1926 def __getitem__(self, key): 1927 return ("getitem", key) 1928 def __setitem__(self, key, value): 1929 self.setitem = (key, value) 1930 def __delitem__(self, key): 1931 self.delitem = key 1932 1933 a = C() 1934 self.assertEqual(a.foo, ("getattr", "foo")) 1935 a.foo = 12 1936 self.assertEqual(a.setattr, ("foo", 12)) 1937 del a.foo 1938 self.assertEqual(a.delattr, "foo") 1939 1940 self.assertEqual(a[12], ("getitem", 12)) 1941 a[12] = 21 1942 self.assertEqual(a.setitem, (12, 21)) 1943 del a[12] 1944 self.assertEqual(a.delitem, 12) 1945 1946 self.assertEqual(a[0:10], ("getitem", slice(0, 10))) 1947 a[0:10] = "foo" 1948 self.assertEqual(a.setitem, (slice(0, 10), "foo")) 1949 del a[0:10] 1950 self.assertEqual(a.delitem, (slice(0, 10))) 1951 1952 def test_methods(self): 1953 # Testing methods... 1954 class C(object): 1955 def __init__(self, x): 1956 self.x = x 1957 def foo(self): 1958 return self.x 1959 c1 = C(1) 1960 self.assertEqual(c1.foo(), 1) 1961 class D(C): 1962 boo = C.foo 1963 goo = c1.foo 1964 d2 = D(2) 1965 self.assertEqual(d2.foo(), 2) 1966 self.assertEqual(d2.boo(), 2) 1967 self.assertEqual(d2.goo(), 1) 1968 class E(object): 1969 foo = C.foo 1970 self.assertEqual(E().foo.__func__, C.foo) # i.e., unbound 1971 self.assertTrue(repr(C.foo.__get__(C(1))).startswith("<bound method ")) 1972 1973 @support.impl_detail("testing error message from implementation") 1974 def test_methods_in_c(self): 1975 # This test checks error messages in builtin method descriptor. 1976 # It is allowed that other Python implementations use 1977 # different error messages. 1978 set_add = set.add 1979 1980 expected_errmsg = "unbound method set.add() needs an argument" 1981 1982 with self.assertRaises(TypeError) as cm: 1983 set_add() 1984 self.assertEqual(cm.exception.args[0], expected_errmsg) 1985 1986 expected_errmsg = "descriptor 'add' for 'set' objects doesn't apply to a 'int' object" 1987 1988 with self.assertRaises(TypeError) as cm: 1989 set_add(0) 1990 self.assertEqual(cm.exception.args[0], expected_errmsg) 1991 1992 with self.assertRaises(TypeError) as cm: 1993 set_add.__get__(0) 1994 self.assertEqual(cm.exception.args[0], expected_errmsg) 1995 1996 def test_special_method_lookup(self): 1997 # The lookup of special methods bypasses __getattr__ and 1998 # __getattribute__, but they still can be descriptors. 1999 2000 def run_context(manager): 2001 with manager: 2002 pass 2003 def iden(self): 2004 return self 2005 def hello(self): 2006 return b"hello" 2007 def empty_seq(self): 2008 return [] 2009 def zero(self): 2010 return 0 2011 def complex_num(self): 2012 return 1j 2013 def stop(self): 2014 raise StopIteration 2015 def return_true(self, thing=None): 2016 return True 2017 def do_isinstance(obj): 2018 return isinstance(int, obj) 2019 def do_issubclass(obj): 2020 return issubclass(int, obj) 2021 def do_dict_missing(checker): 2022 class DictSub(checker.__class__, dict): 2023 pass 2024 self.assertEqual(DictSub()["hi"], 4) 2025 def some_number(self_, key): 2026 self.assertEqual(key, "hi") 2027 return 4 2028 def swallow(*args): pass 2029 def format_impl(self, spec): 2030 return "hello" 2031 2032 # It would be nice to have every special method tested here, but I'm 2033 # only listing the ones I can remember outside of typeobject.c, since it 2034 # does it right. 2035 specials = [ 2036 ("__bytes__", bytes, hello, set(), {}), 2037 ("__reversed__", reversed, empty_seq, set(), {}), 2038 ("__length_hint__", list, zero, set(), 2039 {"__iter__" : iden, "__next__" : stop}), 2040 ("__sizeof__", sys.getsizeof, zero, set(), {}), 2041 ("__instancecheck__", do_isinstance, return_true, set(), {}), 2042 ("__missing__", do_dict_missing, some_number, 2043 set(("__class__",)), {}), 2044 ("__subclasscheck__", do_issubclass, return_true, 2045 set(("__bases__",)), {}), 2046 ("__enter__", run_context, iden, set(), {"__exit__" : swallow}), 2047 ("__exit__", run_context, swallow, set(), {"__enter__" : iden}), 2048 ("__complex__", complex, complex_num, set(), {}), 2049 ("__format__", format, format_impl, set(), {}), 2050 ("__floor__", math.floor, zero, set(), {}), 2051 ("__trunc__", math.trunc, zero, set(), {}), 2052 ("__trunc__", int, zero, set(), {}), 2053 ("__ceil__", math.ceil, zero, set(), {}), 2054 ("__dir__", dir, empty_seq, set(), {}), 2055 ("__round__", round, zero, set(), {}), 2056 ] 2057 2058 class Checker(object): 2059 def __getattr__(self, attr, test=self): 2060 test.fail("__getattr__ called with {0}".format(attr)) 2061 def __getattribute__(self, attr, test=self): 2062 if attr not in ok: 2063 test.fail("__getattribute__ called with {0}".format(attr)) 2064 return object.__getattribute__(self, attr) 2065 class SpecialDescr(object): 2066 def __init__(self, impl): 2067 self.impl = impl 2068 def __get__(self, obj, owner): 2069 record.append(1) 2070 return self.impl.__get__(obj, owner) 2071 class MyException(Exception): 2072 pass 2073 class ErrDescr(object): 2074 def __get__(self, obj, owner): 2075 raise MyException 2076 2077 for name, runner, meth_impl, ok, env in specials: 2078 class X(Checker): 2079 pass 2080 for attr, obj in env.items(): 2081 setattr(X, attr, obj) 2082 setattr(X, name, meth_impl) 2083 runner(X()) 2084 2085 record = [] 2086 class X(Checker): 2087 pass 2088 for attr, obj in env.items(): 2089 setattr(X, attr, obj) 2090 setattr(X, name, SpecialDescr(meth_impl)) 2091 runner(X()) 2092 self.assertEqual(record, [1], name) 2093 2094 class X(Checker): 2095 pass 2096 for attr, obj in env.items(): 2097 setattr(X, attr, obj) 2098 setattr(X, name, ErrDescr()) 2099 self.assertRaises(MyException, runner, X()) 2100 2101 def test_specials(self): 2102 # Testing special operators... 2103 # Test operators like __hash__ for which a built-in default exists 2104 2105 # Test the default behavior for static classes 2106 class C(object): 2107 def __getitem__(self, i): 2108 if 0 <= i < 10: return i 2109 raise IndexError 2110 c1 = C() 2111 c2 = C() 2112 self.assertFalse(not c1) 2113 self.assertNotEqual(id(c1), id(c2)) 2114 hash(c1) 2115 hash(c2) 2116 self.assertEqual(c1, c1) 2117 self.assertTrue(c1 != c2) 2118 self.assertFalse(c1 != c1) 2119 self.assertFalse(c1 == c2) 2120 # Note that the module name appears in str/repr, and that varies 2121 # depending on whether this test is run standalone or from a framework. 2122 self.assertGreaterEqual(str(c1).find('C object at '), 0) 2123 self.assertEqual(str(c1), repr(c1)) 2124 self.assertNotIn(-1, c1) 2125 for i in range(10): 2126 self.assertIn(i, c1) 2127 self.assertNotIn(10, c1) 2128 # Test the default behavior for dynamic classes 2129 class D(object): 2130 def __getitem__(self, i): 2131 if 0 <= i < 10: return i 2132 raise IndexError 2133 d1 = D() 2134 d2 = D() 2135 self.assertFalse(not d1) 2136 self.assertNotEqual(id(d1), id(d2)) 2137 hash(d1) 2138 hash(d2) 2139 self.assertEqual(d1, d1) 2140 self.assertNotEqual(d1, d2) 2141 self.assertFalse(d1 != d1) 2142 self.assertFalse(d1 == d2) 2143 # Note that the module name appears in str/repr, and that varies 2144 # depending on whether this test is run standalone or from a framework. 2145 self.assertGreaterEqual(str(d1).find('D object at '), 0) 2146 self.assertEqual(str(d1), repr(d1)) 2147 self.assertNotIn(-1, d1) 2148 for i in range(10): 2149 self.assertIn(i, d1) 2150 self.assertNotIn(10, d1) 2151 # Test overridden behavior 2152 class Proxy(object): 2153 def __init__(self, x): 2154 self.x = x 2155 def __bool__(self): 2156 return not not self.x 2157 def __hash__(self): 2158 return hash(self.x) 2159 def __eq__(self, other): 2160 return self.x == other 2161 def __ne__(self, other): 2162 return self.x != other 2163 def __ge__(self, other): 2164 return self.x >= other 2165 def __gt__(self, other): 2166 return self.x > other 2167 def __le__(self, other): 2168 return self.x <= other 2169 def __lt__(self, other): 2170 return self.x < other 2171 def __str__(self): 2172 return "Proxy:%s" % self.x 2173 def __repr__(self): 2174 return "Proxy(%r)" % self.x 2175 def __contains__(self, value): 2176 return value in self.x 2177 p0 = Proxy(0) 2178 p1 = Proxy(1) 2179 p_1 = Proxy(-1) 2180 self.assertFalse(p0) 2181 self.assertFalse(not p1) 2182 self.assertEqual(hash(p0), hash(0)) 2183 self.assertEqual(p0, p0) 2184 self.assertNotEqual(p0, p1) 2185 self.assertFalse(p0 != p0) 2186 self.assertEqual(not p0, p1) 2187 self.assertTrue(p0 < p1) 2188 self.assertTrue(p0 <= p1) 2189 self.assertTrue(p1 > p0) 2190 self.assertTrue(p1 >= p0) 2191 self.assertEqual(str(p0), "Proxy:0") 2192 self.assertEqual(repr(p0), "Proxy(0)") 2193 p10 = Proxy(range(10)) 2194 self.assertNotIn(-1, p10) 2195 for i in range(10): 2196 self.assertIn(i, p10) 2197 self.assertNotIn(10, p10) 2198 2199 def test_weakrefs(self): 2200 # Testing weak references... 2201 import weakref 2202 class C(object): 2203 pass 2204 c = C() 2205 r = weakref.ref(c) 2206 self.assertEqual(r(), c) 2207 del c 2208 support.gc_collect() 2209 self.assertEqual(r(), None) 2210 del r 2211 class NoWeak(object): 2212 __slots__ = ['foo'] 2213 no = NoWeak() 2214 try: 2215 weakref.ref(no) 2216 except TypeError as msg: 2217 self.assertIn("weak reference", str(msg)) 2218 else: 2219 self.fail("weakref.ref(no) should be illegal") 2220 class Weak(object): 2221 __slots__ = ['foo', '__weakref__'] 2222 yes = Weak() 2223 r = weakref.ref(yes) 2224 self.assertEqual(r(), yes) 2225 del yes 2226 support.gc_collect() 2227 self.assertEqual(r(), None) 2228 del r 2229 2230 def test_properties(self): 2231 # Testing property... 2232 class C(object): 2233 def getx(self): 2234 return self.__x 2235 def setx(self, value): 2236 self.__x = value 2237 def delx(self): 2238 del self.__x 2239 x = property(getx, setx, delx, doc="I'm the x property.") 2240 a = C() 2241 self.assertNotHasAttr(a, "x") 2242 a.x = 42 2243 self.assertEqual(a._C__x, 42) 2244 self.assertEqual(a.x, 42) 2245 del a.x 2246 self.assertNotHasAttr(a, "x") 2247 self.assertNotHasAttr(a, "_C__x") 2248 C.x.__set__(a, 100) 2249 self.assertEqual(C.x.__get__(a), 100) 2250 C.x.__delete__(a) 2251 self.assertNotHasAttr(a, "x") 2252 2253 raw = C.__dict__['x'] 2254 self.assertIsInstance(raw, property) 2255 2256 attrs = dir(raw) 2257 self.assertIn("__doc__", attrs) 2258 self.assertIn("fget", attrs) 2259 self.assertIn("fset", attrs) 2260 self.assertIn("fdel", attrs) 2261 2262 self.assertEqual(raw.__doc__, "I'm the x property.") 2263 self.assertIs(raw.fget, C.__dict__['getx']) 2264 self.assertIs(raw.fset, C.__dict__['setx']) 2265 self.assertIs(raw.fdel, C.__dict__['delx']) 2266 2267 for attr in "fget", "fset", "fdel": 2268 try: 2269 setattr(raw, attr, 42) 2270 except AttributeError as msg: 2271 if str(msg).find('readonly') < 0: 2272 self.fail("when setting readonly attr %r on a property, " 2273 "got unexpected AttributeError msg %r" % (attr, str(msg))) 2274 else: 2275 self.fail("expected AttributeError from trying to set readonly %r " 2276 "attr on a property" % attr) 2277 2278 raw.__doc__ = 42 2279 self.assertEqual(raw.__doc__, 42) 2280 2281 class D(object): 2282 __getitem__ = property(lambda s: 1/0) 2283 2284 d = D() 2285 try: 2286 for i in d: 2287 str(i) 2288 except ZeroDivisionError: 2289 pass 2290 else: 2291 self.fail("expected ZeroDivisionError from bad property") 2292 2293 @unittest.skipIf(sys.flags.optimize >= 2, 2294 "Docstrings are omitted with -O2 and above") 2295 def test_properties_doc_attrib(self): 2296 class E(object): 2297 def getter(self): 2298 "getter method" 2299 return 0 2300 def setter(self_, value): 2301 "setter method" 2302 pass 2303 prop = property(getter) 2304 self.assertEqual(prop.__doc__, "getter method") 2305 prop2 = property(fset=setter) 2306 self.assertEqual(prop2.__doc__, None) 2307 2308 @support.cpython_only 2309 def test_testcapi_no_segfault(self): 2310 # this segfaulted in 2.5b2 2311 try: 2312 import _testcapi 2313 except ImportError: 2314 pass 2315 else: 2316 class X(object): 2317 p = property(_testcapi.test_with_docstring) 2318 2319 def test_properties_plus(self): 2320 class C(object): 2321 foo = property(doc="hello") 2322 @foo.getter 2323 def foo(self): 2324 return self._foo 2325 @foo.setter 2326 def foo(self, value): 2327 self._foo = abs(value) 2328 @foo.deleter 2329 def foo(self): 2330 del self._foo 2331 c = C() 2332 self.assertEqual(C.foo.__doc__, "hello") 2333 self.assertNotHasAttr(c, "foo") 2334 c.foo = -42 2335 self.assertHasAttr(c, '_foo') 2336 self.assertEqual(c._foo, 42) 2337 self.assertEqual(c.foo, 42) 2338 del c.foo 2339 self.assertNotHasAttr(c, '_foo') 2340 self.assertNotHasAttr(c, "foo") 2341 2342 class D(C): 2343 @C.foo.deleter 2344 def foo(self): 2345 try: 2346 del self._foo 2347 except AttributeError: 2348 pass 2349 d = D() 2350 d.foo = 24 2351 self.assertEqual(d.foo, 24) 2352 del d.foo 2353 del d.foo 2354 2355 class E(object): 2356 @property 2357 def foo(self): 2358 return self._foo 2359 @foo.setter 2360 def foo(self, value): 2361 raise RuntimeError 2362 @foo.setter 2363 def foo(self, value): 2364 self._foo = abs(value) 2365 @foo.deleter 2366 def foo(self, value=None): 2367 del self._foo 2368 2369 e = E() 2370 e.foo = -42 2371 self.assertEqual(e.foo, 42) 2372 del e.foo 2373 2374 class F(E): 2375 @E.foo.deleter 2376 def foo(self): 2377 del self._foo 2378 @foo.setter 2379 def foo(self, value): 2380 self._foo = max(0, value) 2381 f = F() 2382 f.foo = -10 2383 self.assertEqual(f.foo, 0) 2384 del f.foo 2385 2386 def test_dict_constructors(self): 2387 # Testing dict constructor ... 2388 d = dict() 2389 self.assertEqual(d, {}) 2390 d = dict({}) 2391 self.assertEqual(d, {}) 2392 d = dict({1: 2, 'a': 'b'}) 2393 self.assertEqual(d, {1: 2, 'a': 'b'}) 2394 self.assertEqual(d, dict(list(d.items()))) 2395 self.assertEqual(d, dict(iter(d.items()))) 2396 d = dict({'one':1, 'two':2}) 2397 self.assertEqual(d, dict(one=1, two=2)) 2398 self.assertEqual(d, dict(**d)) 2399 self.assertEqual(d, dict({"one": 1}, two=2)) 2400 self.assertEqual(d, dict([("two", 2)], one=1)) 2401 self.assertEqual(d, dict([("one", 100), ("two", 200)], **d)) 2402 self.assertEqual(d, dict(**d)) 2403 2404 for badarg in 0, 0, 0j, "0", [0], (0,): 2405 try: 2406 dict(badarg) 2407 except TypeError: 2408 pass 2409 except ValueError: 2410 if badarg == "0": 2411 # It's a sequence, and its elements are also sequences (gotta 2412 # love strings <wink>), but they aren't of length 2, so this 2413 # one seemed better as a ValueError than a TypeError. 2414 pass 2415 else: 2416 self.fail("no TypeError from dict(%r)" % badarg) 2417 else: 2418 self.fail("no TypeError from dict(%r)" % badarg) 2419 2420 try: 2421 dict({}, {}) 2422 except TypeError: 2423 pass 2424 else: 2425 self.fail("no TypeError from dict({}, {})") 2426 2427 class Mapping: 2428 # Lacks a .keys() method; will be added later. 2429 dict = {1:2, 3:4, 'a':1j} 2430 2431 try: 2432 dict(Mapping()) 2433 except TypeError: 2434 pass 2435 else: 2436 self.fail("no TypeError from dict(incomplete mapping)") 2437 2438 Mapping.keys = lambda self: list(self.dict.keys()) 2439 Mapping.__getitem__ = lambda self, i: self.dict[i] 2440 d = dict(Mapping()) 2441 self.assertEqual(d, Mapping.dict) 2442 2443 # Init from sequence of iterable objects, each producing a 2-sequence. 2444 class AddressBookEntry: 2445 def __init__(self, first, last): 2446 self.first = first 2447 self.last = last 2448 def __iter__(self): 2449 return iter([self.first, self.last]) 2450 2451 d = dict([AddressBookEntry('Tim', 'Warsaw'), 2452 AddressBookEntry('Barry', 'Peters'), 2453 AddressBookEntry('Tim', 'Peters'), 2454 AddressBookEntry('Barry', 'Warsaw')]) 2455 self.assertEqual(d, {'Barry': 'Warsaw', 'Tim': 'Peters'}) 2456 2457 d = dict(zip(range(4), range(1, 5))) 2458 self.assertEqual(d, dict([(i, i+1) for i in range(4)])) 2459 2460 # Bad sequence lengths. 2461 for bad in [('tooshort',)], [('too', 'long', 'by 1')]: 2462 try: 2463 dict(bad) 2464 except ValueError: 2465 pass 2466 else: 2467 self.fail("no ValueError from dict(%r)" % bad) 2468 2469 def test_dir(self): 2470 # Testing dir() ... 2471 junk = 12 2472 self.assertEqual(dir(), ['junk', 'self']) 2473 del junk 2474 2475 # Just make sure these don't blow up! 2476 for arg in 2, 2, 2j, 2e0, [2], "2", b"2", (2,), {2:2}, type, self.test_dir: 2477 dir(arg) 2478 2479 # Test dir on new-style classes. Since these have object as a 2480 # base class, a lot more gets sucked in. 2481 def interesting(strings): 2482 return [s for s in strings if not s.startswith('_')] 2483 2484 class C(object): 2485 Cdata = 1 2486 def Cmethod(self): pass 2487 2488 cstuff = ['Cdata', 'Cmethod'] 2489 self.assertEqual(interesting(dir(C)), cstuff) 2490 2491 c = C() 2492 self.assertEqual(interesting(dir(c)), cstuff) 2493 ## self.assertIn('__self__', dir(C.Cmethod)) 2494 2495 c.cdata = 2 2496 c.cmethod = lambda self: 0 2497 self.assertEqual(interesting(dir(c)), cstuff + ['cdata', 'cmethod']) 2498 ## self.assertIn('__self__', dir(c.Cmethod)) 2499 2500 class A(C): 2501 Adata = 1 2502 def Amethod(self): pass 2503 2504 astuff = ['Adata', 'Amethod'] + cstuff 2505 self.assertEqual(interesting(dir(A)), astuff) 2506 ## self.assertIn('__self__', dir(A.Amethod)) 2507 a = A() 2508 self.assertEqual(interesting(dir(a)), astuff) 2509 a.adata = 42 2510 a.amethod = lambda self: 3 2511 self.assertEqual(interesting(dir(a)), astuff + ['adata', 'amethod']) 2512 ## self.assertIn('__self__', dir(a.Amethod)) 2513 2514 # Try a module subclass. 2515 class M(type(sys)): 2516 pass 2517 minstance = M("m") 2518 minstance.b = 2 2519 minstance.a = 1 2520 default_attributes = ['__name__', '__doc__', '__package__', 2521 '__loader__', '__spec__'] 2522 names = [x for x in dir(minstance) if x not in default_attributes] 2523 self.assertEqual(names, ['a', 'b']) 2524 2525 class M2(M): 2526 def getdict(self): 2527 return "Not a dict!" 2528 __dict__ = property(getdict) 2529 2530 m2instance = M2("m2") 2531 m2instance.b = 2 2532 m2instance.a = 1 2533 self.assertEqual(m2instance.__dict__, "Not a dict!") 2534 try: 2535 dir(m2instance) 2536 except TypeError: 2537 pass 2538 2539 # Two essentially featureless objects, (Ellipsis just inherits stuff 2540 # from object. 2541 self.assertEqual(dir(object()), dir(Ellipsis)) 2542 2543 # Nasty test case for proxied objects 2544 class Wrapper(object): 2545 def __init__(self, obj): 2546 self.__obj = obj 2547 def __repr__(self): 2548 return "Wrapper(%s)" % repr(self.__obj) 2549 def __getitem__(self, key): 2550 return Wrapper(self.__obj[key]) 2551 def __len__(self): 2552 return len(self.__obj) 2553 def __getattr__(self, name): 2554 return Wrapper(getattr(self.__obj, name)) 2555 2556 class C(object): 2557 def __getclass(self): 2558 return Wrapper(type(self)) 2559 __class__ = property(__getclass) 2560 2561 dir(C()) # This used to segfault 2562 2563 def test_supers(self): 2564 # Testing super... 2565 2566 class A(object): 2567 def meth(self, a): 2568 return "A(%r)" % a 2569 2570 self.assertEqual(A().meth(1), "A(1)") 2571 2572 class B(A): 2573 def __init__(self): 2574 self.__super = super(B, self) 2575 def meth(self, a): 2576 return "B(%r)" % a + self.__super.meth(a) 2577 2578 self.assertEqual(B().meth(2), "B(2)A(2)") 2579 2580 class C(A): 2581 def meth(self, a): 2582 return "C(%r)" % a + self.__super.meth(a) 2583 C._C__super = super(C) 2584 2585 self.assertEqual(C().meth(3), "C(3)A(3)") 2586 2587 class D(C, B): 2588 def meth(self, a): 2589 return "D(%r)" % a + super(D, self).meth(a) 2590 2591 self.assertEqual(D().meth(4), "D(4)C(4)B(4)A(4)") 2592 2593 # Test for subclassing super 2594 2595 class mysuper(super): 2596 def __init__(self, *args): 2597 return super(mysuper, self).__init__(*args) 2598 2599 class E(D): 2600 def meth(self, a): 2601 return "E(%r)" % a + mysuper(E, self).meth(a) 2602 2603 self.assertEqual(E().meth(5), "E(5)D(5)C(5)B(5)A(5)") 2604 2605 class F(E): 2606 def meth(self, a): 2607 s = self.__super # == mysuper(F, self) 2608 return "F(%r)[%s]" % (a, s.__class__.__name__) + s.meth(a) 2609 F._F__super = mysuper(F) 2610 2611 self.assertEqual(F().meth(6), "F(6)[mysuper]E(6)D(6)C(6)B(6)A(6)") 2612 2613 # Make sure certain errors are raised 2614 2615 try: 2616 super(D, 42) 2617 except TypeError: 2618 pass 2619 else: 2620 self.fail("shouldn't allow super(D, 42)") 2621 2622 try: 2623 super(D, C()) 2624 except TypeError: 2625 pass 2626 else: 2627 self.fail("shouldn't allow super(D, C())") 2628 2629 try: 2630 super(D).__get__(12) 2631 except TypeError: 2632 pass 2633 else: 2634 self.fail("shouldn't allow super(D).__get__(12)") 2635 2636 try: 2637 super(D).__get__(C()) 2638 except TypeError: 2639 pass 2640 else: 2641 self.fail("shouldn't allow super(D).__get__(C())") 2642 2643 # Make sure data descriptors can be overridden and accessed via super 2644 # (new feature in Python 2.3) 2645 2646 class DDbase(object): 2647 def getx(self): return 42 2648 x = property(getx) 2649 2650 class DDsub(DDbase): 2651 def getx(self): return "hello" 2652 x = property(getx) 2653 2654 dd = DDsub() 2655 self.assertEqual(dd.x, "hello") 2656 self.assertEqual(super(DDsub, dd).x, 42) 2657 2658 # Ensure that super() lookup of descriptor from classmethod 2659 # works (SF ID# 743627) 2660 2661 class Base(object): 2662 aProp = property(lambda self: "foo") 2663 2664 class Sub(Base): 2665 @classmethod 2666 def test(klass): 2667 return super(Sub,klass).aProp 2668 2669 self.assertEqual(Sub.test(), Base.aProp) 2670 2671 # Verify that super() doesn't allow keyword args 2672 with self.assertRaises(TypeError): 2673 super(Base, kw=1) 2674 2675 def test_basic_inheritance(self): 2676 # Testing inheritance from basic types... 2677 2678 class hexint(int): 2679 def __repr__(self): 2680 return hex(self) 2681 def __add__(self, other): 2682 return hexint(int.__add__(self, other)) 2683 # (Note that overriding __radd__ doesn't work, 2684 # because the int type gets first dibs.) 2685 self.assertEqual(repr(hexint(7) + 9), "0x10") 2686 self.assertEqual(repr(hexint(1000) + 7), "0x3ef") 2687 a = hexint(12345) 2688 self.assertEqual(a, 12345) 2689 self.assertEqual(int(a), 12345) 2690 self.assertIs(int(a).__class__, int) 2691 self.assertEqual(hash(a), hash(12345)) 2692 self.assertIs((+a).__class__, int) 2693 self.assertIs((a >> 0).__class__, int) 2694 self.assertIs((a << 0).__class__, int) 2695 self.assertIs((hexint(0) << 12).__class__, int) 2696 self.assertIs((hexint(0) >> 12).__class__, int) 2697 2698 class octlong(int): 2699 __slots__ = [] 2700 def __str__(self): 2701 return oct(self) 2702 def __add__(self, other): 2703 return self.__class__(super(octlong, self).__add__(other)) 2704 __radd__ = __add__ 2705 self.assertEqual(str(octlong(3) + 5), "0o10") 2706 # (Note that overriding __radd__ here only seems to work 2707 # because the example uses a short int left argument.) 2708 self.assertEqual(str(5 + octlong(3000)), "0o5675") 2709 a = octlong(12345) 2710 self.assertEqual(a, 12345) 2711 self.assertEqual(int(a), 12345) 2712 self.assertEqual(hash(a), hash(12345)) 2713 self.assertIs(int(a).__class__, int) 2714 self.assertIs((+a).__class__, int) 2715 self.assertIs((-a).__class__, int) 2716 self.assertIs((-octlong(0)).__class__, int) 2717 self.assertIs((a >> 0).__class__, int) 2718 self.assertIs((a << 0).__class__, int) 2719 self.assertIs((a - 0).__class__, int) 2720 self.assertIs((a * 1).__class__, int) 2721 self.assertIs((a ** 1).__class__, int) 2722 self.assertIs((a // 1).__class__, int) 2723 self.assertIs((1 * a).__class__, int) 2724 self.assertIs((a | 0).__class__, int) 2725 self.assertIs((a ^ 0).__class__, int) 2726 self.assertIs((a & -1).__class__, int) 2727 self.assertIs((octlong(0) << 12).__class__, int) 2728 self.assertIs((octlong(0) >> 12).__class__, int) 2729 self.assertIs(abs(octlong(0)).__class__, int) 2730 2731 # Because octlong overrides __add__, we can't check the absence of +0 2732 # optimizations using octlong. 2733 class longclone(int): 2734 pass 2735 a = longclone(1) 2736 self.assertIs((a + 0).__class__, int) 2737 self.assertIs((0 + a).__class__, int) 2738 2739 # Check that negative clones don't segfault 2740 a = longclone(-1) 2741 self.assertEqual(a.__dict__, {}) 2742 self.assertEqual(int(a), -1) # self.assertTrue PyNumber_Long() copies the sign bit 2743 2744 class precfloat(float): 2745 __slots__ = ['prec'] 2746 def __init__(self, value=0.0, prec=12): 2747 self.prec = int(prec) 2748 def __repr__(self): 2749 return "%.*g" % (self.prec, self) 2750 self.assertEqual(repr(precfloat(1.1)), "1.1") 2751 a = precfloat(12345) 2752 self.assertEqual(a, 12345.0) 2753 self.assertEqual(float(a), 12345.0) 2754 self.assertIs(float(a).__class__, float) 2755 self.assertEqual(hash(a), hash(12345.0)) 2756 self.assertIs((+a).__class__, float) 2757 2758 class madcomplex(complex): 2759 def __repr__(self): 2760 return "%.17gj%+.17g" % (self.imag, self.real) 2761 a = madcomplex(-3, 4) 2762 self.assertEqual(repr(a), "4j-3") 2763 base = complex(-3, 4) 2764 self.assertEqual(base.__class__, complex) 2765 self.assertEqual(a, base) 2766 self.assertEqual(complex(a), base) 2767 self.assertEqual(complex(a).__class__, complex) 2768 a = madcomplex(a) # just trying another form of the constructor 2769 self.assertEqual(repr(a), "4j-3") 2770 self.assertEqual(a, base) 2771 self.assertEqual(complex(a), base) 2772 self.assertEqual(complex(a).__class__, complex) 2773 self.assertEqual(hash(a), hash(base)) 2774 self.assertEqual((+a).__class__, complex) 2775 self.assertEqual((a + 0).__class__, complex) 2776 self.assertEqual(a + 0, base) 2777 self.assertEqual((a - 0).__class__, complex) 2778 self.assertEqual(a - 0, base) 2779 self.assertEqual((a * 1).__class__, complex) 2780 self.assertEqual(a * 1, base) 2781 self.assertEqual((a / 1).__class__, complex) 2782 self.assertEqual(a / 1, base) 2783 2784 class madtuple(tuple): 2785 _rev = None 2786 def rev(self): 2787 if self._rev is not None: 2788 return self._rev 2789 L = list(self) 2790 L.reverse() 2791 self._rev = self.__class__(L) 2792 return self._rev 2793 a = madtuple((1,2,3,4,5,6,7,8,9,0)) 2794 self.assertEqual(a, (1,2,3,4,5,6,7,8,9,0)) 2795 self.assertEqual(a.rev(), madtuple((0,9,8,7,6,5,4,3,2,1))) 2796 self.assertEqual(a.rev().rev(), madtuple((1,2,3,4,5,6,7,8,9,0))) 2797 for i in range(512): 2798 t = madtuple(range(i)) 2799 u = t.rev() 2800 v = u.rev() 2801 self.assertEqual(v, t) 2802 a = madtuple((1,2,3,4,5)) 2803 self.assertEqual(tuple(a), (1,2,3,4,5)) 2804 self.assertIs(tuple(a).__class__, tuple) 2805 self.assertEqual(hash(a), hash((1,2,3,4,5))) 2806 self.assertIs(a[:].__class__, tuple) 2807 self.assertIs((a * 1).__class__, tuple) 2808 self.assertIs((a * 0).__class__, tuple) 2809 self.assertIs((a + ()).__class__, tuple) 2810 a = madtuple(()) 2811 self.assertEqual(tuple(a), ()) 2812 self.assertIs(tuple(a).__class__, tuple) 2813 self.assertIs((a + a).__class__, tuple) 2814 self.assertIs((a * 0).__class__, tuple) 2815 self.assertIs((a * 1).__class__, tuple) 2816 self.assertIs((a * 2).__class__, tuple) 2817 self.assertIs(a[:].__class__, tuple) 2818 2819 class madstring(str): 2820 _rev = None 2821 def rev(self): 2822 if self._rev is not None: 2823 return self._rev 2824 L = list(self) 2825 L.reverse() 2826 self._rev = self.__class__("".join(L)) 2827 return self._rev 2828 s = madstring("abcdefghijklmnopqrstuvwxyz") 2829 self.assertEqual(s, "abcdefghijklmnopqrstuvwxyz") 2830 self.assertEqual(s.rev(), madstring("zyxwvutsrqponmlkjihgfedcba")) 2831 self.assertEqual(s.rev().rev(), madstring("abcdefghijklmnopqrstuvwxyz")) 2832 for i in range(256): 2833 s = madstring("".join(map(chr, range(i)))) 2834 t = s.rev() 2835 u = t.rev() 2836 self.assertEqual(u, s) 2837 s = madstring("12345") 2838 self.assertEqual(str(s), "12345") 2839 self.assertIs(str(s).__class__, str) 2840 2841 base = "\x00" * 5 2842 s = madstring(base) 2843 self.assertEqual(s, base) 2844 self.assertEqual(str(s), base) 2845 self.assertIs(str(s).__class__, str) 2846 self.assertEqual(hash(s), hash(base)) 2847 self.assertEqual({s: 1}[base], 1) 2848 self.assertEqual({base: 1}[s], 1) 2849 self.assertIs((s + "").__class__, str) 2850 self.assertEqual(s + "", base) 2851 self.assertIs(("" + s).__class__, str) 2852 self.assertEqual("" + s, base) 2853 self.assertIs((s * 0).__class__, str) 2854 self.assertEqual(s * 0, "") 2855 self.assertIs((s * 1).__class__, str) 2856 self.assertEqual(s * 1, base) 2857 self.assertIs((s * 2).__class__, str) 2858 self.assertEqual(s * 2, base + base) 2859 self.assertIs(s[:].__class__, str) 2860 self.assertEqual(s[:], base) 2861 self.assertIs(s[0:0].__class__, str) 2862 self.assertEqual(s[0:0], "") 2863 self.assertIs(s.strip().__class__, str) 2864 self.assertEqual(s.strip(), base) 2865 self.assertIs(s.lstrip().__class__, str) 2866 self.assertEqual(s.lstrip(), base) 2867 self.assertIs(s.rstrip().__class__, str) 2868 self.assertEqual(s.rstrip(), base) 2869 identitytab = {} 2870 self.assertIs(s.translate(identitytab).__class__, str) 2871 self.assertEqual(s.translate(identitytab), base) 2872 self.assertIs(s.replace("x", "x").__class__, str) 2873 self.assertEqual(s.replace("x", "x"), base) 2874 self.assertIs(s.ljust(len(s)).__class__, str) 2875 self.assertEqual(s.ljust(len(s)), base) 2876 self.assertIs(s.rjust(len(s)).__class__, str) 2877 self.assertEqual(s.rjust(len(s)), base) 2878 self.assertIs(s.center(len(s)).__class__, str) 2879 self.assertEqual(s.center(len(s)), base) 2880 self.assertIs(s.lower().__class__, str) 2881 self.assertEqual(s.lower(), base) 2882 2883 class madunicode(str): 2884 _rev = None 2885 def rev(self): 2886 if self._rev is not None: 2887 return self._rev 2888 L = list(self) 2889 L.reverse() 2890 self._rev = self.__class__("".join(L)) 2891 return self._rev 2892 u = madunicode("ABCDEF") 2893 self.assertEqual(u, "ABCDEF") 2894 self.assertEqual(u.rev(), madunicode("FEDCBA")) 2895 self.assertEqual(u.rev().rev(), madunicode("ABCDEF")) 2896 base = "12345" 2897 u = madunicode(base) 2898 self.assertEqual(str(u), base) 2899 self.assertIs(str(u).__class__, str) 2900 self.assertEqual(hash(u), hash(base)) 2901 self.assertEqual({u: 1}[base], 1) 2902 self.assertEqual({base: 1}[u], 1) 2903 self.assertIs(u.strip().__class__, str) 2904 self.assertEqual(u.strip(), base) 2905 self.assertIs(u.lstrip().__class__, str) 2906 self.assertEqual(u.lstrip(), base) 2907 self.assertIs(u.rstrip().__class__, str) 2908 self.assertEqual(u.rstrip(), base) 2909 self.assertIs(u.replace("x", "x").__class__, str) 2910 self.assertEqual(u.replace("x", "x"), base) 2911 self.assertIs(u.replace("xy", "xy").__class__, str) 2912 self.assertEqual(u.replace("xy", "xy"), base) 2913 self.assertIs(u.center(len(u)).__class__, str) 2914 self.assertEqual(u.center(len(u)), base) 2915 self.assertIs(u.ljust(len(u)).__class__, str) 2916 self.assertEqual(u.ljust(len(u)), base) 2917 self.assertIs(u.rjust(len(u)).__class__, str) 2918 self.assertEqual(u.rjust(len(u)), base) 2919 self.assertIs(u.lower().__class__, str) 2920 self.assertEqual(u.lower(), base) 2921 self.assertIs(u.upper().__class__, str) 2922 self.assertEqual(u.upper(), base) 2923 self.assertIs(u.capitalize().__class__, str) 2924 self.assertEqual(u.capitalize(), base) 2925 self.assertIs(u.title().__class__, str) 2926 self.assertEqual(u.title(), base) 2927 self.assertIs((u + "").__class__, str) 2928 self.assertEqual(u + "", base) 2929 self.assertIs(("" + u).__class__, str) 2930 self.assertEqual("" + u, base) 2931 self.assertIs((u * 0).__class__, str) 2932 self.assertEqual(u * 0, "") 2933 self.assertIs((u * 1).__class__, str) 2934 self.assertEqual(u * 1, base) 2935 self.assertIs((u * 2).__class__, str) 2936 self.assertEqual(u * 2, base + base) 2937 self.assertIs(u[:].__class__, str) 2938 self.assertEqual(u[:], base) 2939 self.assertIs(u[0:0].__class__, str) 2940 self.assertEqual(u[0:0], "") 2941 2942 class sublist(list): 2943 pass 2944 a = sublist(range(5)) 2945 self.assertEqual(a, list(range(5))) 2946 a.append("hello") 2947 self.assertEqual(a, list(range(5)) + ["hello"]) 2948 a[5] = 5 2949 self.assertEqual(a, list(range(6))) 2950 a.extend(range(6, 20)) 2951 self.assertEqual(a, list(range(20))) 2952 a[-5:] = [] 2953 self.assertEqual(a, list(range(15))) 2954 del a[10:15] 2955 self.assertEqual(len(a), 10) 2956 self.assertEqual(a, list(range(10))) 2957 self.assertEqual(list(a), list(range(10))) 2958 self.assertEqual(a[0], 0) 2959 self.assertEqual(a[9], 9) 2960 self.assertEqual(a[-10], 0) 2961 self.assertEqual(a[-1], 9) 2962 self.assertEqual(a[:5], list(range(5))) 2963 2964 ## class CountedInput(file): 2965 ## """Counts lines read by self.readline(). 2966 ## 2967 ## self.lineno is the 0-based ordinal of the last line read, up to 2968 ## a maximum of one greater than the number of lines in the file. 2969 ## 2970 ## self.ateof is true if and only if the final "" line has been read, 2971 ## at which point self.lineno stops incrementing, and further calls 2972 ## to readline() continue to return "". 2973 ## """ 2974 ## 2975 ## lineno = 0 2976 ## ateof = 0 2977 ## def readline(self): 2978 ## if self.ateof: 2979 ## return "" 2980 ## s = file.readline(self) 2981 ## # Next line works too. 2982 ## # s = super(CountedInput, self).readline() 2983 ## self.lineno += 1 2984 ## if s == "": 2985 ## self.ateof = 1 2986 ## return s 2987 ## 2988 ## f = file(name=support.TESTFN, mode='w') 2989 ## lines = ['a\n', 'b\n', 'c\n'] 2990 ## try: 2991 ## f.writelines(lines) 2992 ## f.close() 2993 ## f = CountedInput(support.TESTFN) 2994 ## for (i, expected) in zip(range(1, 5) + [4], lines + 2 * [""]): 2995 ## got = f.readline() 2996 ## self.assertEqual(expected, got) 2997 ## self.assertEqual(f.lineno, i) 2998 ## self.assertEqual(f.ateof, (i > len(lines))) 2999 ## f.close() 3000 ## finally: 3001 ## try: 3002 ## f.close() 3003 ## except: 3004 ## pass 3005 ## support.unlink(support.TESTFN) 3006 3007 def test_keywords(self): 3008 # Testing keyword args to basic type constructors ... 3009 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3010 int(x=1) 3011 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3012 float(x=2) 3013 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3014 bool(x=2) 3015 self.assertEqual(complex(imag=42, real=666), complex(666, 42)) 3016 self.assertEqual(str(object=500), '500') 3017 self.assertEqual(str(object=b'abc', errors='strict'), 'abc') 3018 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3019 tuple(sequence=range(3)) 3020 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3021 list(sequence=(0, 1, 2)) 3022 # note: as of Python 2.3, dict() no longer has an "items" keyword arg 3023 3024 for constructor in (int, float, int, complex, str, str, 3025 tuple, list): 3026 try: 3027 constructor(bogus_keyword_arg=1) 3028 except TypeError: 3029 pass 3030 else: 3031 self.fail("expected TypeError from bogus keyword argument to %r" 3032 % constructor) 3033 3034 def test_str_subclass_as_dict_key(self): 3035 # Testing a str subclass used as dict key .. 3036 3037 class cistr(str): 3038 """Subclass of str that computes __eq__ case-insensitively. 3039 3040 Also computes a hash code of the string in canonical form. 3041 """ 3042 3043 def __init__(self, value): 3044 self.canonical = value.lower() 3045 self.hashcode = hash(self.canonical) 3046 3047 def __eq__(self, other): 3048 if not isinstance(other, cistr): 3049 other = cistr(other) 3050 return self.canonical == other.canonical 3051 3052 def __hash__(self): 3053 return self.hashcode 3054 3055 self.assertEqual(cistr('ABC'), 'abc') 3056 self.assertEqual('aBc', cistr('ABC')) 3057 self.assertEqual(str(cistr('ABC')), 'ABC') 3058 3059 d = {cistr('one'): 1, cistr('two'): 2, cistr('tHree'): 3} 3060 self.assertEqual(d[cistr('one')], 1) 3061 self.assertEqual(d[cistr('tWo')], 2) 3062 self.assertEqual(d[cistr('THrEE')], 3) 3063 self.assertIn(cistr('ONe'), d) 3064 self.assertEqual(d.get(cistr('thrEE')), 3) 3065 3066 def test_classic_comparisons(self): 3067 # Testing classic comparisons... 3068 class classic: 3069 pass 3070 3071 for base in (classic, int, object): 3072 class C(base): 3073 def __init__(self, value): 3074 self.value = int(value) 3075 def __eq__(self, other): 3076 if isinstance(other, C): 3077 return self.value == other.value 3078 if isinstance(other, int) or isinstance(other, int): 3079 return self.value == other 3080 return NotImplemented 3081 def __ne__(self, other): 3082 if isinstance(other, C): 3083 return self.value != other.value 3084 if isinstance(other, int) or isinstance(other, int): 3085 return self.value != other 3086 return NotImplemented 3087 def __lt__(self, other): 3088 if isinstance(other, C): 3089 return self.value < other.value 3090 if isinstance(other, int) or isinstance(other, int): 3091 return self.value < other 3092 return NotImplemented 3093 def __le__(self, other): 3094 if isinstance(other, C): 3095 return self.value <= other.value 3096 if isinstance(other, int) or isinstance(other, int): 3097 return self.value <= other 3098 return NotImplemented 3099 def __gt__(self, other): 3100 if isinstance(other, C): 3101 return self.value > other.value 3102 if isinstance(other, int) or isinstance(other, int): 3103 return self.value > other 3104 return NotImplemented 3105 def __ge__(self, other): 3106 if isinstance(other, C): 3107 return self.value >= other.value 3108 if isinstance(other, int) or isinstance(other, int): 3109 return self.value >= other 3110 return NotImplemented 3111 3112 c1 = C(1) 3113 c2 = C(2) 3114 c3 = C(3) 3115 self.assertEqual(c1, 1) 3116 c = {1: c1, 2: c2, 3: c3} 3117 for x in 1, 2, 3: 3118 for y in 1, 2, 3: 3119 for op in "<", "<=", "==", "!=", ">", ">=": 3120 self.assertEqual(eval("c[x] %s c[y]" % op), 3121 eval("x %s y" % op), 3122 "x=%d, y=%d" % (x, y)) 3123 self.assertEqual(eval("c[x] %s y" % op), 3124 eval("x %s y" % op), 3125 "x=%d, y=%d" % (x, y)) 3126 self.assertEqual(eval("x %s c[y]" % op), 3127 eval("x %s y" % op), 3128 "x=%d, y=%d" % (x, y)) 3129 3130 def test_rich_comparisons(self): 3131 # Testing rich comparisons... 3132 class Z(complex): 3133 pass 3134 z = Z(1) 3135 self.assertEqual(z, 1+0j) 3136 self.assertEqual(1+0j, z) 3137 class ZZ(complex): 3138 def __eq__(self, other): 3139 try: 3140 return abs(self - other) <= 1e-6 3141 except: 3142 return NotImplemented 3143 zz = ZZ(1.0000003) 3144 self.assertEqual(zz, 1+0j) 3145 self.assertEqual(1+0j, zz) 3146 3147 class classic: 3148 pass 3149 for base in (classic, int, object, list): 3150 class C(base): 3151 def __init__(self, value): 3152 self.value = int(value) 3153 def __cmp__(self_, other): 3154 self.fail("shouldn't call __cmp__") 3155 def __eq__(self, other): 3156 if isinstance(other, C): 3157 return self.value == other.value 3158 if isinstance(other, int) or isinstance(other, int): 3159 return self.value == other 3160 return NotImplemented 3161 def __ne__(self, other): 3162 if isinstance(other, C): 3163 return self.value != other.value 3164 if isinstance(other, int) or isinstance(other, int): 3165 return self.value != other 3166 return NotImplemented 3167 def __lt__(self, other): 3168 if isinstance(other, C): 3169 return self.value < other.value 3170 if isinstance(other, int) or isinstance(other, int): 3171 return self.value < other 3172 return NotImplemented 3173 def __le__(self, other): 3174 if isinstance(other, C): 3175 return self.value <= other.value 3176 if isinstance(other, int) or isinstance(other, int): 3177 return self.value <= other 3178 return NotImplemented 3179 def __gt__(self, other): 3180 if isinstance(other, C): 3181 return self.value > other.value 3182 if isinstance(other, int) or isinstance(other, int): 3183 return self.value > other 3184 return NotImplemented 3185 def __ge__(self, other): 3186 if isinstance(other, C): 3187 return self.value >= other.value 3188 if isinstance(other, int) or isinstance(other, int): 3189 return self.value >= other 3190 return NotImplemented 3191 c1 = C(1) 3192 c2 = C(2) 3193 c3 = C(3) 3194 self.assertEqual(c1, 1) 3195 c = {1: c1, 2: c2, 3: c3} 3196 for x in 1, 2, 3: 3197 for y in 1, 2, 3: 3198 for op in "<", "<=", "==", "!=", ">", ">=": 3199 self.assertEqual(eval("c[x] %s c[y]" % op), 3200 eval("x %s y" % op), 3201 "x=%d, y=%d" % (x, y)) 3202 self.assertEqual(eval("c[x] %s y" % op), 3203 eval("x %s y" % op), 3204 "x=%d, y=%d" % (x, y)) 3205 self.assertEqual(eval("x %s c[y]" % op), 3206 eval("x %s y" % op), 3207 "x=%d, y=%d" % (x, y)) 3208 3209 def test_descrdoc(self): 3210 # Testing descriptor doc strings... 3211 from _io import FileIO 3212 def check(descr, what): 3213 self.assertEqual(descr.__doc__, what) 3214 check(FileIO.closed, "True if the file is closed") # getset descriptor 3215 check(complex.real, "the real part of a complex number") # member descriptor 3216 3217 def test_doc_descriptor(self): 3218 # Testing __doc__ descriptor... 3219 # SF bug 542984 3220 class DocDescr(object): 3221 def __get__(self, object, otype): 3222 if object: 3223 object = object.__class__.__name__ + ' instance' 3224 if otype: 3225 otype = otype.__name__ 3226 return 'object=%s; type=%s' % (object, otype) 3227 class OldClass: 3228 __doc__ = DocDescr() 3229 class NewClass(object): 3230 __doc__ = DocDescr() 3231 self.assertEqual(OldClass.__doc__, 'object=None; type=OldClass') 3232 self.assertEqual(OldClass().__doc__, 'object=OldClass instance; type=OldClass') 3233 self.assertEqual(NewClass.__doc__, 'object=None; type=NewClass') 3234 self.assertEqual(NewClass().__doc__, 'object=NewClass instance; type=NewClass') 3235 3236 def test_set_class(self): 3237 # Testing __class__ assignment... 3238 class C(object): pass 3239 class D(object): pass 3240 class E(object): pass 3241 class F(D, E): pass 3242 for cls in C, D, E, F: 3243 for cls2 in C, D, E, F: 3244 x = cls() 3245 x.__class__ = cls2 3246 self.assertIs(x.__class__, cls2) 3247 x.__class__ = cls 3248 self.assertIs(x.__class__, cls) 3249 def cant(x, C): 3250 try: 3251 x.__class__ = C 3252 except TypeError: 3253 pass 3254 else: 3255 self.fail("shouldn't allow %r.__class__ = %r" % (x, C)) 3256 try: 3257 delattr(x, "__class__") 3258 except (TypeError, AttributeError): 3259 pass 3260 else: 3261 self.fail("shouldn't allow del %r.__class__" % x) 3262 cant(C(), list) 3263 cant(list(), C) 3264 cant(C(), 1) 3265 cant(C(), object) 3266 cant(object(), list) 3267 cant(list(), object) 3268 class Int(int): __slots__ = [] 3269 cant(True, int) 3270 cant(2, bool) 3271 o = object() 3272 cant(o, type(1)) 3273 cant(o, type(None)) 3274 del o 3275 class G(object): 3276 __slots__ = ["a", "b"] 3277 class H(object): 3278 __slots__ = ["b", "a"] 3279 class I(object): 3280 __slots__ = ["a", "b"] 3281 class J(object): 3282 __slots__ = ["c", "b"] 3283 class K(object): 3284 __slots__ = ["a", "b", "d"] 3285 class L(H): 3286 __slots__ = ["e"] 3287 class M(I): 3288 __slots__ = ["e"] 3289 class N(J): 3290 __slots__ = ["__weakref__"] 3291 class P(J): 3292 __slots__ = ["__dict__"] 3293 class Q(J): 3294 pass 3295 class R(J): 3296 __slots__ = ["__dict__", "__weakref__"] 3297 3298 for cls, cls2 in ((G, H), (G, I), (I, H), (Q, R), (R, Q)): 3299 x = cls() 3300 x.a = 1 3301 x.__class__ = cls2 3302 self.assertIs(x.__class__, cls2, 3303 "assigning %r as __class__ for %r silently failed" % (cls2, x)) 3304 self.assertEqual(x.a, 1) 3305 x.__class__ = cls 3306 self.assertIs(x.__class__, cls, 3307 "assigning %r as __class__ for %r silently failed" % (cls, x)) 3308 self.assertEqual(x.a, 1) 3309 for cls in G, J, K, L, M, N, P, R, list, Int: 3310 for cls2 in G, J, K, L, M, N, P, R, list, Int: 3311 if cls is cls2: 3312 continue 3313 cant(cls(), cls2) 3314 3315 # Issue5283: when __class__ changes in __del__, the wrong 3316 # type gets DECREF'd. 3317 class O(object): 3318 pass 3319 class A(object): 3320 def __del__(self): 3321 self.__class__ = O 3322 l = [A() for x in range(100)] 3323 del l 3324 3325 def test_set_dict(self): 3326 # Testing __dict__ assignment... 3327 class C(object): pass 3328 a = C() 3329 a.__dict__ = {'b': 1} 3330 self.assertEqual(a.b, 1) 3331 def cant(x, dict): 3332 try: 3333 x.__dict__ = dict 3334 except (AttributeError, TypeError): 3335 pass 3336 else: 3337 self.fail("shouldn't allow %r.__dict__ = %r" % (x, dict)) 3338 cant(a, None) 3339 cant(a, []) 3340 cant(a, 1) 3341 del a.__dict__ # Deleting __dict__ is allowed 3342 3343 class Base(object): 3344 pass 3345 def verify_dict_readonly(x): 3346 """ 3347 x has to be an instance of a class inheriting from Base. 3348 """ 3349 cant(x, {}) 3350 try: 3351 del x.__dict__ 3352 except (AttributeError, TypeError): 3353 pass 3354 else: 3355 self.fail("shouldn't allow del %r.__dict__" % x) 3356 dict_descr = Base.__dict__["__dict__"] 3357 try: 3358 dict_descr.__set__(x, {}) 3359 except (AttributeError, TypeError): 3360 pass 3361 else: 3362 self.fail("dict_descr allowed access to %r's dict" % x) 3363 3364 # Classes don't allow __dict__ assignment and have readonly dicts 3365 class Meta1(type, Base): 3366 pass 3367 class Meta2(Base, type): 3368 pass 3369 class D(object, metaclass=Meta1): 3370 pass 3371 class E(object, metaclass=Meta2): 3372 pass 3373 for cls in C, D, E: 3374 verify_dict_readonly(cls) 3375 class_dict = cls.__dict__ 3376 try: 3377 class_dict["spam"] = "eggs" 3378 except TypeError: 3379 pass 3380 else: 3381 self.fail("%r's __dict__ can be modified" % cls) 3382 3383 # Modules also disallow __dict__ assignment 3384 class Module1(types.ModuleType, Base): 3385 pass 3386 class Module2(Base, types.ModuleType): 3387 pass 3388 for ModuleType in Module1, Module2: 3389 mod = ModuleType("spam") 3390 verify_dict_readonly(mod) 3391 mod.__dict__["spam"] = "eggs" 3392 3393 # Exception's __dict__ can be replaced, but not deleted 3394 # (at least not any more than regular exception's __dict__ can 3395 # be deleted; on CPython it is not the case, whereas on PyPy they 3396 # can, just like any other new-style instance's __dict__.) 3397 def can_delete_dict(e): 3398 try: 3399 del e.__dict__ 3400 except (TypeError, AttributeError): 3401 return False 3402 else: 3403 return True 3404 class Exception1(Exception, Base): 3405 pass 3406 class Exception2(Base, Exception): 3407 pass 3408 for ExceptionType in Exception, Exception1, Exception2: 3409 e = ExceptionType() 3410 e.__dict__ = {"a": 1} 3411 self.assertEqual(e.a, 1) 3412 self.assertEqual(can_delete_dict(e), can_delete_dict(ValueError())) 3413 3414 def test_binary_operator_override(self): 3415 # Testing overrides of binary operations... 3416 class I(int): 3417 def __repr__(self): 3418 return "I(%r)" % int(self) 3419 def __add__(self, other): 3420 return I(int(self) + int(other)) 3421 __radd__ = __add__ 3422 def __pow__(self, other, mod=None): 3423 if mod is None: 3424 return I(pow(int(self), int(other))) 3425 else: 3426 return I(pow(int(self), int(other), int(mod))) 3427 def __rpow__(self, other, mod=None): 3428 if mod is None: 3429 return I(pow(int(other), int(self), mod)) 3430 else: 3431 return I(pow(int(other), int(self), int(mod))) 3432 3433 self.assertEqual(repr(I(1) + I(2)), "I(3)") 3434 self.assertEqual(repr(I(1) + 2), "I(3)") 3435 self.assertEqual(repr(1 + I(2)), "I(3)") 3436 self.assertEqual(repr(I(2) ** I(3)), "I(8)") 3437 self.assertEqual(repr(2 ** I(3)), "I(8)") 3438 self.assertEqual(repr(I(2) ** 3), "I(8)") 3439 self.assertEqual(repr(pow(I(2), I(3), I(5))), "I(3)") 3440 class S(str): 3441 def __eq__(self, other): 3442 return self.lower() == other.lower() 3443 3444 def test_subclass_propagation(self): 3445 # Testing propagation of slot functions to subclasses... 3446 class A(object): 3447 pass 3448 class B(A): 3449 pass 3450 class C(A): 3451 pass 3452 class D(B, C): 3453 pass 3454 d = D() 3455 orig_hash = hash(d) # related to id(d) in platform-dependent ways 3456 A.__hash__ = lambda self: 42 3457 self.assertEqual(hash(d), 42) 3458 C.__hash__ = lambda self: 314 3459 self.assertEqual(hash(d), 314) 3460 B.__hash__ = lambda self: 144 3461 self.assertEqual(hash(d), 144) 3462 D.__hash__ = lambda self: 100 3463 self.assertEqual(hash(d), 100) 3464 D.__hash__ = None 3465 self.assertRaises(TypeError, hash, d) 3466 del D.__hash__ 3467 self.assertEqual(hash(d), 144) 3468 B.__hash__ = None 3469 self.assertRaises(TypeError, hash, d) 3470 del B.__hash__ 3471 self.assertEqual(hash(d), 314) 3472 C.__hash__ = None 3473 self.assertRaises(TypeError, hash, d) 3474 del C.__hash__ 3475 self.assertEqual(hash(d), 42) 3476 A.__hash__ = None 3477 self.assertRaises(TypeError, hash, d) 3478 del A.__hash__ 3479 self.assertEqual(hash(d), orig_hash) 3480 d.foo = 42 3481 d.bar = 42 3482 self.assertEqual(d.foo, 42) 3483 self.assertEqual(d.bar, 42) 3484 def __getattribute__(self, name): 3485 if name == "foo": 3486 return 24 3487 return object.__getattribute__(self, name) 3488 A.__getattribute__ = __getattribute__ 3489 self.assertEqual(d.foo, 24) 3490 self.assertEqual(d.bar, 42) 3491 def __getattr__(self, name): 3492 if name in ("spam", "foo", "bar"): 3493 return "hello" 3494 raise AttributeError(name) 3495 B.__getattr__ = __getattr__ 3496 self.assertEqual(d.spam, "hello") 3497 self.assertEqual(d.foo, 24) 3498 self.assertEqual(d.bar, 42) 3499 del A.__getattribute__ 3500 self.assertEqual(d.foo, 42) 3501 del d.foo 3502 self.assertEqual(d.foo, "hello") 3503 self.assertEqual(d.bar, 42) 3504 del B.__getattr__ 3505 try: 3506 d.foo 3507 except AttributeError: 3508 pass 3509 else: 3510 self.fail("d.foo should be undefined now") 3511 3512 # Test a nasty bug in recurse_down_subclasses() 3513 class A(object): 3514 pass 3515 class B(A): 3516 pass 3517 del B 3518 support.gc_collect() 3519 A.__setitem__ = lambda *a: None # crash 3520 3521 def test_buffer_inheritance(self): 3522 # Testing that buffer interface is inherited ... 3523 3524 import binascii 3525 # SF bug [#470040] ParseTuple t# vs subclasses. 3526 3527 class MyBytes(bytes): 3528 pass 3529 base = b'abc' 3530 m = MyBytes(base) 3531 # b2a_hex uses the buffer interface to get its argument's value, via 3532 # PyArg_ParseTuple 't#' code. 3533 self.assertEqual(binascii.b2a_hex(m), binascii.b2a_hex(base)) 3534 3535 class MyInt(int): 3536 pass 3537 m = MyInt(42) 3538 try: 3539 binascii.b2a_hex(m) 3540 self.fail('subclass of int should not have a buffer interface') 3541 except TypeError: 3542 pass 3543 3544 def test_str_of_str_subclass(self): 3545 # Testing __str__ defined in subclass of str ... 3546 import binascii 3547 import io 3548 3549 class octetstring(str): 3550 def __str__(self): 3551 return binascii.b2a_hex(self.encode('ascii')).decode("ascii") 3552 def __repr__(self): 3553 return self + " repr" 3554 3555 o = octetstring('A') 3556 self.assertEqual(type(o), octetstring) 3557 self.assertEqual(type(str(o)), str) 3558 self.assertEqual(type(repr(o)), str) 3559 self.assertEqual(ord(o), 0x41) 3560 self.assertEqual(str(o), '41') 3561 self.assertEqual(repr(o), 'A repr') 3562 self.assertEqual(o.__str__(), '41') 3563 self.assertEqual(o.__repr__(), 'A repr') 3564 3565 capture = io.StringIO() 3566 # Calling str() or not exercises different internal paths. 3567 print(o, file=capture) 3568 print(str(o), file=capture) 3569 self.assertEqual(capture.getvalue(), '41\n41\n') 3570 capture.close() 3571 3572 def test_keyword_arguments(self): 3573 # Testing keyword arguments to __init__, __call__... 3574 def f(a): return a 3575 self.assertEqual(f.__call__(a=42), 42) 3576 ba = bytearray() 3577 bytearray.__init__(ba, 'abc\xbd\u20ac', 3578 encoding='latin1', errors='replace') 3579 self.assertEqual(ba, b'abc\xbd?') 3580 3581 def test_recursive_call(self): 3582 # Testing recursive __call__() by setting to instance of class... 3583 class A(object): 3584 pass 3585 3586 A.__call__ = A() 3587 try: 3588 A()() 3589 except RecursionError: 3590 pass 3591 else: 3592 self.fail("Recursion limit should have been reached for __call__()") 3593 3594 def test_delete_hook(self): 3595 # Testing __del__ hook... 3596 log = [] 3597 class C(object): 3598 def __del__(self): 3599 log.append(1) 3600 c = C() 3601 self.assertEqual(log, []) 3602 del c 3603 support.gc_collect() 3604 self.assertEqual(log, [1]) 3605 3606 class D(object): pass 3607 d = D() 3608 try: del d[0] 3609 except TypeError: pass 3610 else: self.fail("invalid del() didn't raise TypeError") 3611 3612 def test_hash_inheritance(self): 3613 # Testing hash of mutable subclasses... 3614 3615 class mydict(dict): 3616 pass 3617 d = mydict() 3618 try: 3619 hash(d) 3620 except TypeError: 3621 pass 3622 else: 3623 self.fail("hash() of dict subclass should fail") 3624 3625 class mylist(list): 3626 pass 3627 d = mylist() 3628 try: 3629 hash(d) 3630 except TypeError: 3631 pass 3632 else: 3633 self.fail("hash() of list subclass should fail") 3634 3635 def test_str_operations(self): 3636 try: 'a' + 5 3637 except TypeError: pass 3638 else: self.fail("'' + 5 doesn't raise TypeError") 3639 3640 try: ''.split('') 3641 except ValueError: pass 3642 else: self.fail("''.split('') doesn't raise ValueError") 3643 3644 try: ''.join([0]) 3645 except TypeError: pass 3646 else: self.fail("''.join([0]) doesn't raise TypeError") 3647 3648 try: ''.rindex('5') 3649 except ValueError: pass 3650 else: self.fail("''.rindex('5') doesn't raise ValueError") 3651 3652 try: '%(n)s' % None 3653 except TypeError: pass 3654 else: self.fail("'%(n)s' % None doesn't raise TypeError") 3655 3656 try: '%(n' % {} 3657 except ValueError: pass 3658 else: self.fail("'%(n' % {} '' doesn't raise ValueError") 3659 3660 try: '%*s' % ('abc') 3661 except TypeError: pass 3662 else: self.fail("'%*s' % ('abc') doesn't raise TypeError") 3663 3664 try: '%*.*s' % ('abc', 5) 3665 except TypeError: pass 3666 else: self.fail("'%*.*s' % ('abc', 5) doesn't raise TypeError") 3667 3668 try: '%s' % (1, 2) 3669 except TypeError: pass 3670 else: self.fail("'%s' % (1, 2) doesn't raise TypeError") 3671 3672 try: '%' % None 3673 except ValueError: pass 3674 else: self.fail("'%' % None doesn't raise ValueError") 3675 3676 self.assertEqual('534253'.isdigit(), 1) 3677 self.assertEqual('534253x'.isdigit(), 0) 3678 self.assertEqual('%c' % 5, '\x05') 3679 self.assertEqual('%c' % '5', '5') 3680 3681 def test_deepcopy_recursive(self): 3682 # Testing deepcopy of recursive objects... 3683 class Node: 3684 pass 3685 a = Node() 3686 b = Node() 3687 a.b = b 3688 b.a = a 3689 z = deepcopy(a) # This blew up before 3690 3691 def test_uninitialized_modules(self): 3692 # Testing uninitialized module objects... 3693 from types import ModuleType as M 3694 m = M.__new__(M) 3695 str(m) 3696 self.assertNotHasAttr(m, "__name__") 3697 self.assertNotHasAttr(m, "__file__") 3698 self.assertNotHasAttr(m, "foo") 3699 self.assertFalse(m.__dict__) # None or {} are both reasonable answers 3700 m.foo = 1 3701 self.assertEqual(m.__dict__, {"foo": 1}) 3702 3703 def test_funny_new(self): 3704 # Testing __new__ returning something unexpected... 3705 class C(object): 3706 def __new__(cls, arg): 3707 if isinstance(arg, str): return [1, 2, 3] 3708 elif isinstance(arg, int): return object.__new__(D) 3709 else: return object.__new__(cls) 3710 class D(C): 3711 def __init__(self, arg): 3712 self.foo = arg 3713 self.assertEqual(C("1"), [1, 2, 3]) 3714 self.assertEqual(D("1"), [1, 2, 3]) 3715 d = D(None) 3716 self.assertEqual(d.foo, None) 3717 d = C(1) 3718 self.assertIsInstance(d, D) 3719 self.assertEqual(d.foo, 1) 3720 d = D(1) 3721 self.assertIsInstance(d, D) 3722 self.assertEqual(d.foo, 1) 3723 3724 class C(object): 3725 @staticmethod 3726 def __new__(*args): 3727 return args 3728 self.assertEqual(C(1, 2), (C, 1, 2)) 3729 class D(C): 3730 pass 3731 self.assertEqual(D(1, 2), (D, 1, 2)) 3732 3733 class C(object): 3734 @classmethod 3735 def __new__(*args): 3736 return args 3737 self.assertEqual(C(1, 2), (C, C, 1, 2)) 3738 class D(C): 3739 pass 3740 self.assertEqual(D(1, 2), (D, D, 1, 2)) 3741 3742 def test_imul_bug(self): 3743 # Testing for __imul__ problems... 3744 # SF bug 544647 3745 class C(object): 3746 def __imul__(self, other): 3747 return (self, other) 3748 x = C() 3749 y = x 3750 y *= 1.0 3751 self.assertEqual(y, (x, 1.0)) 3752 y = x 3753 y *= 2 3754 self.assertEqual(y, (x, 2)) 3755 y = x 3756 y *= 3 3757 self.assertEqual(y, (x, 3)) 3758 y = x 3759 y *= 1<<100 3760 self.assertEqual(y, (x, 1<<100)) 3761 y = x 3762 y *= None 3763 self.assertEqual(y, (x, None)) 3764 y = x 3765 y *= "foo" 3766 self.assertEqual(y, (x, "foo")) 3767 3768 def test_copy_setstate(self): 3769 # Testing that copy.*copy() correctly uses __setstate__... 3770 import copy 3771 class C(object): 3772 def __init__(self, foo=None): 3773 self.foo = foo 3774 self.__foo = foo 3775 def setfoo(self, foo=None): 3776 self.foo = foo 3777 def getfoo(self): 3778 return self.__foo 3779 def __getstate__(self): 3780 return [self.foo] 3781 def __setstate__(self_, lst): 3782 self.assertEqual(len(lst), 1) 3783 self_.__foo = self_.foo = lst[0] 3784 a = C(42) 3785 a.setfoo(24) 3786 self.assertEqual(a.foo, 24) 3787 self.assertEqual(a.getfoo(), 42) 3788 b = copy.copy(a) 3789 self.assertEqual(b.foo, 24) 3790 self.assertEqual(b.getfoo(), 24) 3791 b = copy.deepcopy(a) 3792 self.assertEqual(b.foo, 24) 3793 self.assertEqual(b.getfoo(), 24) 3794 3795 def test_slices(self): 3796 # Testing cases with slices and overridden __getitem__ ... 3797 3798 # Strings 3799 self.assertEqual("hello"[:4], "hell") 3800 self.assertEqual("hello"[slice(4)], "hell") 3801 self.assertEqual(str.__getitem__("hello", slice(4)), "hell") 3802 class S(str): 3803 def __getitem__(self, x): 3804 return str.__getitem__(self, x) 3805 self.assertEqual(S("hello")[:4], "hell") 3806 self.assertEqual(S("hello")[slice(4)], "hell") 3807 self.assertEqual(S("hello").__getitem__(slice(4)), "hell") 3808 # Tuples 3809 self.assertEqual((1,2,3)[:2], (1,2)) 3810 self.assertEqual((1,2,3)[slice(2)], (1,2)) 3811 self.assertEqual(tuple.__getitem__((1,2,3), slice(2)), (1,2)) 3812 class T(tuple): 3813 def __getitem__(self, x): 3814 return tuple.__getitem__(self, x) 3815 self.assertEqual(T((1,2,3))[:2], (1,2)) 3816 self.assertEqual(T((1,2,3))[slice(2)], (1,2)) 3817 self.assertEqual(T((1,2,3)).__getitem__(slice(2)), (1,2)) 3818 # Lists 3819 self.assertEqual([1,2,3][:2], [1,2]) 3820 self.assertEqual([1,2,3][slice(2)], [1,2]) 3821 self.assertEqual(list.__getitem__([1,2,3], slice(2)), [1,2]) 3822 class L(list): 3823 def __getitem__(self, x): 3824 return list.__getitem__(self, x) 3825 self.assertEqual(L([1,2,3])[:2], [1,2]) 3826 self.assertEqual(L([1,2,3])[slice(2)], [1,2]) 3827 self.assertEqual(L([1,2,3]).__getitem__(slice(2)), [1,2]) 3828 # Now do lists and __setitem__ 3829 a = L([1,2,3]) 3830 a[slice(1, 3)] = [3,2] 3831 self.assertEqual(a, [1,3,2]) 3832 a[slice(0, 2, 1)] = [3,1] 3833 self.assertEqual(a, [3,1,2]) 3834 a.__setitem__(slice(1, 3), [2,1]) 3835 self.assertEqual(a, [3,2,1]) 3836 a.__setitem__(slice(0, 2, 1), [2,3]) 3837 self.assertEqual(a, [2,3,1]) 3838 3839 def test_subtype_resurrection(self): 3840 # Testing resurrection of new-style instance... 3841 3842 class C(object): 3843 container = [] 3844 3845 def __del__(self): 3846 # resurrect the instance 3847 C.container.append(self) 3848 3849 c = C() 3850 c.attr = 42 3851 3852 # The most interesting thing here is whether this blows up, due to 3853 # flawed GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 3854 # bug). 3855 del c 3856 3857 support.gc_collect() 3858 self.assertEqual(len(C.container), 1) 3859 3860 # Make c mortal again, so that the test framework with -l doesn't report 3861 # it as a leak. 3862 del C.__del__ 3863 3864 def test_slots_trash(self): 3865 # Testing slot trash... 3866 # Deallocating deeply nested slotted trash caused stack overflows 3867 class trash(object): 3868 __slots__ = ['x'] 3869 def __init__(self, x): 3870 self.x = x 3871 o = None 3872 for i in range(50000): 3873 o = trash(o) 3874 del o 3875 3876 def test_slots_multiple_inheritance(self): 3877 # SF bug 575229, multiple inheritance w/ slots dumps core 3878 class A(object): 3879 __slots__=() 3880 class B(object): 3881 pass 3882 class C(A,B) : 3883 __slots__=() 3884 if support.check_impl_detail(): 3885 self.assertEqual(C.__basicsize__, B.__basicsize__) 3886 self.assertHasAttr(C, '__dict__') 3887 self.assertHasAttr(C, '__weakref__') 3888 C().x = 2 3889 3890 def test_rmul(self): 3891 # Testing correct invocation of __rmul__... 3892 # SF patch 592646 3893 class C(object): 3894 def __mul__(self, other): 3895 return "mul" 3896 def __rmul__(self, other): 3897 return "rmul" 3898 a = C() 3899 self.assertEqual(a*2, "mul") 3900 self.assertEqual(a*2.2, "mul") 3901 self.assertEqual(2*a, "rmul") 3902 self.assertEqual(2.2*a, "rmul") 3903 3904 def test_ipow(self): 3905 # Testing correct invocation of __ipow__... 3906 # [SF bug 620179] 3907 class C(object): 3908 def __ipow__(self, other): 3909 pass 3910 a = C() 3911 a **= 2 3912 3913 def test_mutable_bases(self): 3914 # Testing mutable bases... 3915 3916 # stuff that should work: 3917 class C(object): 3918 pass 3919 class C2(object): 3920 def __getattribute__(self, attr): 3921 if attr == 'a': 3922 return 2 3923 else: 3924 return super(C2, self).__getattribute__(attr) 3925 def meth(self): 3926 return 1 3927 class D(C): 3928 pass 3929 class E(D): 3930 pass 3931 d = D() 3932 e = E() 3933 D.__bases__ = (C,) 3934 D.__bases__ = (C2,) 3935 self.assertEqual(d.meth(), 1) 3936 self.assertEqual(e.meth(), 1) 3937 self.assertEqual(d.a, 2) 3938 self.assertEqual(e.a, 2) 3939 self.assertEqual(C2.__subclasses__(), [D]) 3940 3941 try: 3942 del D.__bases__ 3943 except (TypeError, AttributeError): 3944 pass 3945 else: 3946 self.fail("shouldn't be able to delete .__bases__") 3947 3948 try: 3949 D.__bases__ = () 3950 except TypeError as msg: 3951 if str(msg) == "a new-style class can't have only classic bases": 3952 self.fail("wrong error message for .__bases__ = ()") 3953 else: 3954 self.fail("shouldn't be able to set .__bases__ to ()") 3955 3956 try: 3957 D.__bases__ = (D,) 3958 except TypeError: 3959 pass 3960 else: 3961 # actually, we'll have crashed by here... 3962 self.fail("shouldn't be able to create inheritance cycles") 3963 3964 try: 3965 D.__bases__ = (C, C) 3966 except TypeError: 3967 pass 3968 else: 3969 self.fail("didn't detect repeated base classes") 3970 3971 try: 3972 D.__bases__ = (E,) 3973 except TypeError: 3974 pass 3975 else: 3976 self.fail("shouldn't be able to create inheritance cycles") 3977 3978 def test_builtin_bases(self): 3979 # Make sure all the builtin types can have their base queried without 3980 # segfaulting. See issue #5787. 3981 builtin_types = [tp for tp in builtins.__dict__.values() 3982 if isinstance(tp, type)] 3983 for tp in builtin_types: 3984 object.__getattribute__(tp, "__bases__") 3985 if tp is not object: 3986 self.assertEqual(len(tp.__bases__), 1, tp) 3987 3988 class L(list): 3989 pass 3990 3991 class C(object): 3992 pass 3993 3994 class D(C): 3995 pass 3996 3997 try: 3998 L.__bases__ = (dict,) 3999 except TypeError: 4000 pass 4001 else: 4002 self.fail("shouldn't turn list subclass into dict subclass") 4003 4004 try: 4005 list.__bases__ = (dict,) 4006 except TypeError: 4007 pass 4008 else: 4009 self.fail("shouldn't be able to assign to list.__bases__") 4010 4011 try: 4012 D.__bases__ = (C, list) 4013 except TypeError: 4014 pass 4015 else: 4016 assert 0, "best_base calculation found wanting" 4017 4018 def test_unsubclassable_types(self): 4019 with self.assertRaises(TypeError): 4020 class X(type(None)): 4021 pass 4022 with self.assertRaises(TypeError): 4023 class X(object, type(None)): 4024 pass 4025 with self.assertRaises(TypeError): 4026 class X(type(None), object): 4027 pass 4028 class O(object): 4029 pass 4030 with self.assertRaises(TypeError): 4031 class X(O, type(None)): 4032 pass 4033 with self.assertRaises(TypeError): 4034 class X(type(None), O): 4035 pass 4036 4037 class X(object): 4038 pass 4039 with self.assertRaises(TypeError): 4040 X.__bases__ = type(None), 4041 with self.assertRaises(TypeError): 4042 X.__bases__ = object, type(None) 4043 with self.assertRaises(TypeError): 4044 X.__bases__ = type(None), object 4045 with self.assertRaises(TypeError): 4046 X.__bases__ = O, type(None) 4047 with self.assertRaises(TypeError): 4048 X.__bases__ = type(None), O 4049 4050 def test_mutable_bases_with_failing_mro(self): 4051 # Testing mutable bases with failing mro... 4052 class WorkOnce(type): 4053 def __new__(self, name, bases, ns): 4054 self.flag = 0 4055 return super(WorkOnce, self).__new__(WorkOnce, name, bases, ns) 4056 def mro(self): 4057 if self.flag > 0: 4058 raise RuntimeError("bozo") 4059 else: 4060 self.flag += 1 4061 return type.mro(self) 4062 4063 class WorkAlways(type): 4064 def mro(self): 4065 # this is here to make sure that .mro()s aren't called 4066 # with an exception set (which was possible at one point). 4067 # An error message will be printed in a debug build. 4068 # What's a good way to test for this? 4069 return type.mro(self) 4070 4071 class C(object): 4072 pass 4073 4074 class C2(object): 4075 pass 4076 4077 class D(C): 4078 pass 4079 4080 class E(D): 4081 pass 4082 4083 class F(D, metaclass=WorkOnce): 4084 pass 4085 4086 class G(D, metaclass=WorkAlways): 4087 pass 4088 4089 # Immediate subclasses have their mro's adjusted in alphabetical 4090 # order, so E's will get adjusted before adjusting F's fails. We 4091 # check here that E's gets restored. 4092 4093 E_mro_before = E.__mro__ 4094 D_mro_before = D.__mro__ 4095 4096 try: 4097 D.__bases__ = (C2,) 4098 except RuntimeError: 4099 self.assertEqual(E.__mro__, E_mro_before) 4100 self.assertEqual(D.__mro__, D_mro_before) 4101 else: 4102 self.fail("exception not propagated") 4103 4104 def test_mutable_bases_catch_mro_conflict(self): 4105 # Testing mutable bases catch mro conflict... 4106 class A(object): 4107 pass 4108 4109 class B(object): 4110 pass 4111 4112 class C(A, B): 4113 pass 4114 4115 class D(A, B): 4116 pass 4117 4118 class E(C, D): 4119 pass 4120 4121 try: 4122 C.__bases__ = (B, A) 4123 except TypeError: 4124 pass 4125 else: 4126 self.fail("didn't catch MRO conflict") 4127 4128 def test_mutable_names(self): 4129 # Testing mutable names... 4130 class C(object): 4131 pass 4132 4133 # C.__module__ could be 'test_descr' or '__main__' 4134 mod = C.__module__ 4135 4136 C.__name__ = 'D' 4137 self.assertEqual((C.__module__, C.__name__), (mod, 'D')) 4138 4139 C.__name__ = 'D.E' 4140 self.assertEqual((C.__module__, C.__name__), (mod, 'D.E')) 4141 4142 def test_evil_type_name(self): 4143 # A badly placed Py_DECREF in type_set_name led to arbitrary code 4144 # execution while the type structure was not in a sane state, and a 4145 # possible segmentation fault as a result. See bug #16447. 4146 class Nasty(str): 4147 def __del__(self): 4148 C.__name__ = "other" 4149 4150 class C: 4151 pass 4152 4153 C.__name__ = Nasty("abc") 4154 C.__name__ = "normal" 4155 4156 def test_subclass_right_op(self): 4157 # Testing correct dispatch of subclass overloading __r<op>__... 4158 4159 # This code tests various cases where right-dispatch of a subclass 4160 # should be preferred over left-dispatch of a base class. 4161 4162 # Case 1: subclass of int; this tests code in abstract.c::binary_op1() 4163 4164 class B(int): 4165 def __floordiv__(self, other): 4166 return "B.__floordiv__" 4167 def __rfloordiv__(self, other): 4168 return "B.__rfloordiv__" 4169 4170 self.assertEqual(B(1) // 1, "B.__floordiv__") 4171 self.assertEqual(1 // B(1), "B.__rfloordiv__") 4172 4173 # Case 2: subclass of object; this is just the baseline for case 3 4174 4175 class C(object): 4176 def __floordiv__(self, other): 4177 return "C.__floordiv__" 4178 def __rfloordiv__(self, other): 4179 return "C.__rfloordiv__" 4180 4181 self.assertEqual(C() // 1, "C.__floordiv__") 4182 self.assertEqual(1 // C(), "C.__rfloordiv__") 4183 4184 # Case 3: subclass of new-style class; here it gets interesting 4185 4186 class D(C): 4187 def __floordiv__(self, other): 4188 return "D.__floordiv__" 4189 def __rfloordiv__(self, other): 4190 return "D.__rfloordiv__" 4191 4192 self.assertEqual(D() // C(), "D.__floordiv__") 4193 self.assertEqual(C() // D(), "D.__rfloordiv__") 4194 4195 # Case 4: this didn't work right in 2.2.2 and 2.3a1 4196 4197 class E(C): 4198 pass 4199 4200 self.assertEqual(E.__rfloordiv__, C.__rfloordiv__) 4201 4202 self.assertEqual(E() // 1, "C.__floordiv__") 4203 self.assertEqual(1 // E(), "C.__rfloordiv__") 4204 self.assertEqual(E() // C(), "C.__floordiv__") 4205 self.assertEqual(C() // E(), "C.__floordiv__") # This one would fail 4206 4207 @support.impl_detail("testing an internal kind of method object") 4208 def test_meth_class_get(self): 4209 # Testing __get__ method of METH_CLASS C methods... 4210 # Full coverage of descrobject.c::classmethod_get() 4211 4212 # Baseline 4213 arg = [1, 2, 3] 4214 res = {1: None, 2: None, 3: None} 4215 self.assertEqual(dict.fromkeys(arg), res) 4216 self.assertEqual({}.fromkeys(arg), res) 4217 4218 # Now get the descriptor 4219 descr = dict.__dict__["fromkeys"] 4220 4221 # More baseline using the descriptor directly 4222 self.assertEqual(descr.__get__(None, dict)(arg), res) 4223 self.assertEqual(descr.__get__({})(arg), res) 4224 4225 # Now check various error cases 4226 try: 4227 descr.__get__(None, None) 4228 except TypeError: 4229 pass 4230 else: 4231 self.fail("shouldn't have allowed descr.__get__(None, None)") 4232 try: 4233 descr.__get__(42) 4234 except TypeError: 4235 pass 4236 else: 4237 self.fail("shouldn't have allowed descr.__get__(42)") 4238 try: 4239 descr.__get__(None, 42) 4240 except TypeError: 4241 pass 4242 else: 4243 self.fail("shouldn't have allowed descr.__get__(None, 42)") 4244 try: 4245 descr.__get__(None, int) 4246 except TypeError: 4247 pass 4248 else: 4249 self.fail("shouldn't have allowed descr.__get__(None, int)") 4250 4251 def test_isinst_isclass(self): 4252 # Testing proxy isinstance() and isclass()... 4253 class Proxy(object): 4254 def __init__(self, obj): 4255 self.__obj = obj 4256 def __getattribute__(self, name): 4257 if name.startswith("_Proxy__"): 4258 return object.__getattribute__(self, name) 4259 else: 4260 return getattr(self.__obj, name) 4261 # Test with a classic class 4262 class C: 4263 pass 4264 a = C() 4265 pa = Proxy(a) 4266 self.assertIsInstance(a, C) # Baseline 4267 self.assertIsInstance(pa, C) # Test 4268 # Test with a classic subclass 4269 class D(C): 4270 pass 4271 a = D() 4272 pa = Proxy(a) 4273 self.assertIsInstance(a, C) # Baseline 4274 self.assertIsInstance(pa, C) # Test 4275 # Test with a new-style class 4276 class C(object): 4277 pass 4278 a = C() 4279 pa = Proxy(a) 4280 self.assertIsInstance(a, C) # Baseline 4281 self.assertIsInstance(pa, C) # Test 4282 # Test with a new-style subclass 4283 class D(C): 4284 pass 4285 a = D() 4286 pa = Proxy(a) 4287 self.assertIsInstance(a, C) # Baseline 4288 self.assertIsInstance(pa, C) # Test 4289 4290 def test_proxy_super(self): 4291 # Testing super() for a proxy object... 4292 class Proxy(object): 4293 def __init__(self, obj): 4294 self.__obj = obj 4295 def __getattribute__(self, name): 4296 if name.startswith("_Proxy__"): 4297 return object.__getattribute__(self, name) 4298 else: 4299 return getattr(self.__obj, name) 4300 4301 class B(object): 4302 def f(self): 4303 return "B.f" 4304 4305 class C(B): 4306 def f(self): 4307 return super(C, self).f() + "->C.f" 4308 4309 obj = C() 4310 p = Proxy(obj) 4311 self.assertEqual(C.__dict__["f"](p), "B.f->C.f") 4312 4313 def test_carloverre(self): 4314 # Testing prohibition of Carlo Verre's hack... 4315 try: 4316 object.__setattr__(str, "foo", 42) 4317 except TypeError: 4318 pass 4319 else: 4320 self.fail("Carlo Verre __setattr__ succeeded!") 4321 try: 4322 object.__delattr__(str, "lower") 4323 except TypeError: 4324 pass 4325 else: 4326 self.fail("Carlo Verre __delattr__ succeeded!") 4327 4328 def test_carloverre_multi_inherit_valid(self): 4329 class A(type): 4330 def __setattr__(cls, key, value): 4331 type.__setattr__(cls, key, value) 4332 4333 class B: 4334 pass 4335 4336 class C(B, A): 4337 pass 4338 4339 obj = C('D', (object,), {}) 4340 try: 4341 obj.test = True 4342 except TypeError: 4343 self.fail("setattr through direct base types should be legal") 4344 4345 def test_carloverre_multi_inherit_invalid(self): 4346 class A(type): 4347 def __setattr__(cls, key, value): 4348 object.__setattr__(cls, key, value) # this should fail! 4349 4350 class B: 4351 pass 4352 4353 class C(B, A): 4354 pass 4355 4356 obj = C('D', (object,), {}) 4357 try: 4358 obj.test = True 4359 except TypeError: 4360 pass 4361 else: 4362 self.fail("setattr through indirect base types should be rejected") 4363 4364 def test_weakref_segfault(self): 4365 # Testing weakref segfault... 4366 # SF 742911 4367 import weakref 4368 4369 class Provoker: 4370 def __init__(self, referrent): 4371 self.ref = weakref.ref(referrent) 4372 4373 def __del__(self): 4374 x = self.ref() 4375 4376 class Oops(object): 4377 pass 4378 4379 o = Oops() 4380 o.whatever = Provoker(o) 4381 del o 4382 4383 def test_wrapper_segfault(self): 4384 # SF 927248: deeply nested wrappers could cause stack overflow 4385 f = lambda:None 4386 for i in range(1000000): 4387 f = f.__call__ 4388 f = None 4389 4390 def test_file_fault(self): 4391 # Testing sys.stdout is changed in getattr... 4392 test_stdout = sys.stdout 4393 class StdoutGuard: 4394 def __getattr__(self, attr): 4395 sys.stdout = sys.__stdout__ 4396 raise RuntimeError("Premature access to sys.stdout.%s" % attr) 4397 sys.stdout = StdoutGuard() 4398 try: 4399 print("Oops!") 4400 except RuntimeError: 4401 pass 4402 finally: 4403 sys.stdout = test_stdout 4404 4405 def test_vicious_descriptor_nonsense(self): 4406 # Testing vicious_descriptor_nonsense... 4407 4408 # A potential segfault spotted by Thomas Wouters in mail to 4409 # python-dev 2003-04-17, turned into an example & fixed by Michael 4410 # Hudson just less than four months later... 4411 4412 class Evil(object): 4413 def __hash__(self): 4414 return hash('attr') 4415 def __eq__(self, other): 4416 try: 4417 del C.attr 4418 except AttributeError: 4419 # possible race condition 4420 pass 4421 return 0 4422 4423 class Descr(object): 4424 def __get__(self, ob, type=None): 4425 return 1 4426 4427 class C(object): 4428 attr = Descr() 4429 4430 c = C() 4431 c.__dict__[Evil()] = 0 4432 4433 self.assertEqual(c.attr, 1) 4434 # this makes a crash more likely: 4435 support.gc_collect() 4436 self.assertNotHasAttr(c, 'attr') 4437 4438 def test_init(self): 4439 # SF 1155938 4440 class Foo(object): 4441 def __init__(self): 4442 return 10 4443 try: 4444 Foo() 4445 except TypeError: 4446 pass 4447 else: 4448 self.fail("did not test __init__() for None return") 4449 4450 def assertNotOrderable(self, a, b): 4451 with self.assertRaises(TypeError): 4452 a < b 4453 with self.assertRaises(TypeError): 4454 a > b 4455 with self.assertRaises(TypeError): 4456 a <= b 4457 with self.assertRaises(TypeError): 4458 a >= b 4459 4460 def test_method_wrapper(self): 4461 # Testing method-wrapper objects... 4462 # <type 'method-wrapper'> did not support any reflection before 2.5 4463 l = [] 4464 self.assertTrue(l.__add__ == l.__add__) 4465 self.assertFalse(l.__add__ != l.__add__) 4466 self.assertFalse(l.__add__ == [].__add__) 4467 self.assertTrue(l.__add__ != [].__add__) 4468 self.assertFalse(l.__add__ == l.__mul__) 4469 self.assertTrue(l.__add__ != l.__mul__) 4470 self.assertNotOrderable(l.__add__, l.__add__) 4471 self.assertEqual(l.__add__.__name__, '__add__') 4472 self.assertIs(l.__add__.__self__, l) 4473 self.assertIs(l.__add__.__objclass__, list) 4474 self.assertEqual(l.__add__.__doc__, list.__add__.__doc__) 4475 # hash([].__add__) should not be based on hash([]) 4476 hash(l.__add__) 4477 4478 def test_builtin_function_or_method(self): 4479 # Not really belonging to test_descr, but introspection and 4480 # comparison on <type 'builtin_function_or_method'> seems not 4481 # to be tested elsewhere 4482 l = [] 4483 self.assertTrue(l.append == l.append) 4484 self.assertFalse(l.append != l.append) 4485 self.assertFalse(l.append == [].append) 4486 self.assertTrue(l.append != [].append) 4487 self.assertFalse(l.append == l.pop) 4488 self.assertTrue(l.append != l.pop) 4489 self.assertNotOrderable(l.append, l.append) 4490 self.assertEqual(l.append.__name__, 'append') 4491 self.assertIs(l.append.__self__, l) 4492 # self.assertIs(l.append.__objclass__, list) --- could be added? 4493 self.assertEqual(l.append.__doc__, list.append.__doc__) 4494 # hash([].append) should not be based on hash([]) 4495 hash(l.append) 4496 4497 def test_special_unbound_method_types(self): 4498 # Testing objects of <type 'wrapper_descriptor'>... 4499 self.assertTrue(list.__add__ == list.__add__) 4500 self.assertFalse(list.__add__ != list.__add__) 4501 self.assertFalse(list.__add__ == list.__mul__) 4502 self.assertTrue(list.__add__ != list.__mul__) 4503 self.assertNotOrderable(list.__add__, list.__add__) 4504 self.assertEqual(list.__add__.__name__, '__add__') 4505 self.assertIs(list.__add__.__objclass__, list) 4506 4507 # Testing objects of <type 'method_descriptor'>... 4508 self.assertTrue(list.append == list.append) 4509 self.assertFalse(list.append != list.append) 4510 self.assertFalse(list.append == list.pop) 4511 self.assertTrue(list.append != list.pop) 4512 self.assertNotOrderable(list.append, list.append) 4513 self.assertEqual(list.append.__name__, 'append') 4514 self.assertIs(list.append.__objclass__, list) 4515 4516 def test_not_implemented(self): 4517 # Testing NotImplemented... 4518 # all binary methods should be able to return a NotImplemented 4519 import operator 4520 4521 def specialmethod(self, other): 4522 return NotImplemented 4523 4524 def check(expr, x, y): 4525 try: 4526 exec(expr, {'x': x, 'y': y, 'operator': operator}) 4527 except TypeError: 4528 pass 4529 else: 4530 self.fail("no TypeError from %r" % (expr,)) 4531 4532 N1 = sys.maxsize + 1 # might trigger OverflowErrors instead of 4533 # TypeErrors 4534 N2 = sys.maxsize # if sizeof(int) < sizeof(long), might trigger 4535 # ValueErrors instead of TypeErrors 4536 for name, expr, iexpr in [ 4537 ('__add__', 'x + y', 'x += y'), 4538 ('__sub__', 'x - y', 'x -= y'), 4539 ('__mul__', 'x * y', 'x *= y'), 4540 ('__matmul__', 'x @ y', 'x @= y'), 4541 ('__truediv__', 'x / y', 'x /= y'), 4542 ('__floordiv__', 'x // y', 'x //= y'), 4543 ('__mod__', 'x % y', 'x %= y'), 4544 ('__divmod__', 'divmod(x, y)', None), 4545 ('__pow__', 'x ** y', 'x **= y'), 4546 ('__lshift__', 'x << y', 'x <<= y'), 4547 ('__rshift__', 'x >> y', 'x >>= y'), 4548 ('__and__', 'x & y', 'x &= y'), 4549 ('__or__', 'x | y', 'x |= y'), 4550 ('__xor__', 'x ^ y', 'x ^= y')]: 4551 rname = '__r' + name[2:] 4552 A = type('A', (), {name: specialmethod}) 4553 a = A() 4554 check(expr, a, a) 4555 check(expr, a, N1) 4556 check(expr, a, N2) 4557 if iexpr: 4558 check(iexpr, a, a) 4559 check(iexpr, a, N1) 4560 check(iexpr, a, N2) 4561 iname = '__i' + name[2:] 4562 C = type('C', (), {iname: specialmethod}) 4563 c = C() 4564 check(iexpr, c, a) 4565 check(iexpr, c, N1) 4566 check(iexpr, c, N2) 4567 4568 def test_assign_slice(self): 4569 # ceval.c's assign_slice used to check for 4570 # tp->tp_as_sequence->sq_slice instead of 4571 # tp->tp_as_sequence->sq_ass_slice 4572 4573 class C(object): 4574 def __setitem__(self, idx, value): 4575 self.value = value 4576 4577 c = C() 4578 c[1:2] = 3 4579 self.assertEqual(c.value, 3) 4580 4581 def test_set_and_no_get(self): 4582 # See 4583 # http://mail.python.org/pipermail/python-dev/2010-January/095637.html 4584 class Descr(object): 4585 4586 def __init__(self, name): 4587 self.name = name 4588 4589 def __set__(self, obj, value): 4590 obj.__dict__[self.name] = value 4591 descr = Descr("a") 4592 4593 class X(object): 4594 a = descr 4595 4596 x = X() 4597 self.assertIs(x.a, descr) 4598 x.a = 42 4599 self.assertEqual(x.a, 42) 4600 4601 # Also check type_getattro for correctness. 4602 class Meta(type): 4603 pass 4604 class X(metaclass=Meta): 4605 pass 4606 X.a = 42 4607 Meta.a = Descr("a") 4608 self.assertEqual(X.a, 42) 4609 4610 def test_getattr_hooks(self): 4611 # issue 4230 4612 4613 class Descriptor(object): 4614 counter = 0 4615 def __get__(self, obj, objtype=None): 4616 def getter(name): 4617 self.counter += 1 4618 raise AttributeError(name) 4619 return getter 4620 4621 descr = Descriptor() 4622 class A(object): 4623 __getattribute__ = descr 4624 class B(object): 4625 __getattr__ = descr 4626 class C(object): 4627 __getattribute__ = descr 4628 __getattr__ = descr 4629 4630 self.assertRaises(AttributeError, getattr, A(), "attr") 4631 self.assertEqual(descr.counter, 1) 4632 self.assertRaises(AttributeError, getattr, B(), "attr") 4633 self.assertEqual(descr.counter, 2) 4634 self.assertRaises(AttributeError, getattr, C(), "attr") 4635 self.assertEqual(descr.counter, 4) 4636 4637 class EvilGetattribute(object): 4638 # This used to segfault 4639 def __getattr__(self, name): 4640 raise AttributeError(name) 4641 def __getattribute__(self, name): 4642 del EvilGetattribute.__getattr__ 4643 for i in range(5): 4644 gc.collect() 4645 raise AttributeError(name) 4646 4647 self.assertRaises(AttributeError, getattr, EvilGetattribute(), "attr") 4648 4649 def test_type___getattribute__(self): 4650 self.assertRaises(TypeError, type.__getattribute__, list, type) 4651 4652 def test_abstractmethods(self): 4653 # type pretends not to have __abstractmethods__. 4654 self.assertRaises(AttributeError, getattr, type, "__abstractmethods__") 4655 class meta(type): 4656 pass 4657 self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__") 4658 class X(object): 4659 pass 4660 with self.assertRaises(AttributeError): 4661 del X.__abstractmethods__ 4662 4663 def test_proxy_call(self): 4664 class FakeStr: 4665 __class__ = str 4666 4667 fake_str = FakeStr() 4668 # isinstance() reads __class__ 4669 self.assertIsInstance(fake_str, str) 4670 4671 # call a method descriptor 4672 with self.assertRaises(TypeError): 4673 str.split(fake_str) 4674 4675 # call a slot wrapper descriptor 4676 with self.assertRaises(TypeError): 4677 str.__add__(fake_str, "abc") 4678 4679 def test_repr_as_str(self): 4680 # Issue #11603: crash or infinite loop when rebinding __str__ as 4681 # __repr__. 4682 class Foo: 4683 pass 4684 Foo.__repr__ = Foo.__str__ 4685 foo = Foo() 4686 self.assertRaises(RecursionError, str, foo) 4687 self.assertRaises(RecursionError, repr, foo) 4688 4689 def test_mixing_slot_wrappers(self): 4690 class X(dict): 4691 __setattr__ = dict.__setitem__ 4692 __neg__ = dict.copy 4693 x = X() 4694 x.y = 42 4695 self.assertEqual(x["y"], 42) 4696 self.assertEqual(x, -x) 4697 4698 def test_wrong_class_slot_wrapper(self): 4699 # Check bpo-37619: a wrapper descriptor taken from the wrong class 4700 # should raise an exception instead of silently being ignored 4701 class A(int): 4702 __eq__ = str.__eq__ 4703 __add__ = str.__add__ 4704 a = A() 4705 with self.assertRaises(TypeError): 4706 a == a 4707 with self.assertRaises(TypeError): 4708 a + a 4709 4710 def test_slot_shadows_class_variable(self): 4711 with self.assertRaises(ValueError) as cm: 4712 class X: 4713 __slots__ = ["foo"] 4714 foo = None 4715 m = str(cm.exception) 4716 self.assertEqual("'foo' in __slots__ conflicts with class variable", m) 4717 4718 def test_set_doc(self): 4719 class X: 4720 "elephant" 4721 X.__doc__ = "banana" 4722 self.assertEqual(X.__doc__, "banana") 4723 with self.assertRaises(TypeError) as cm: 4724 type(list).__dict__["__doc__"].__set__(list, "blah") 4725 self.assertIn("can't set list.__doc__", str(cm.exception)) 4726 with self.assertRaises(TypeError) as cm: 4727 type(X).__dict__["__doc__"].__delete__(X) 4728 self.assertIn("can't delete X.__doc__", str(cm.exception)) 4729 self.assertEqual(X.__doc__, "banana") 4730 4731 def test_qualname(self): 4732 descriptors = [str.lower, complex.real, float.real, int.__add__] 4733 types = ['method', 'member', 'getset', 'wrapper'] 4734 4735 # make sure we have an example of each type of descriptor 4736 for d, n in zip(descriptors, types): 4737 self.assertEqual(type(d).__name__, n + '_descriptor') 4738 4739 for d in descriptors: 4740 qualname = d.__objclass__.__qualname__ + '.' + d.__name__ 4741 self.assertEqual(d.__qualname__, qualname) 4742 4743 self.assertEqual(str.lower.__qualname__, 'str.lower') 4744 self.assertEqual(complex.real.__qualname__, 'complex.real') 4745 self.assertEqual(float.real.__qualname__, 'float.real') 4746 self.assertEqual(int.__add__.__qualname__, 'int.__add__') 4747 4748 class X: 4749 pass 4750 with self.assertRaises(TypeError): 4751 del X.__qualname__ 4752 4753 self.assertRaises(TypeError, type.__dict__['__qualname__'].__set__, 4754 str, 'Oink') 4755 4756 global Y 4757 class Y: 4758 class Inside: 4759 pass 4760 self.assertEqual(Y.__qualname__, 'Y') 4761 self.assertEqual(Y.Inside.__qualname__, 'Y.Inside') 4762 4763 def test_qualname_dict(self): 4764 ns = {'__qualname__': 'some.name'} 4765 tp = type('Foo', (), ns) 4766 self.assertEqual(tp.__qualname__, 'some.name') 4767 self.assertNotIn('__qualname__', tp.__dict__) 4768 self.assertEqual(ns, {'__qualname__': 'some.name'}) 4769 4770 ns = {'__qualname__': 1} 4771 self.assertRaises(TypeError, type, 'Foo', (), ns) 4772 4773 def test_cycle_through_dict(self): 4774 # See bug #1469629 4775 class X(dict): 4776 def __init__(self): 4777 dict.__init__(self) 4778 self.__dict__ = self 4779 x = X() 4780 x.attr = 42 4781 wr = weakref.ref(x) 4782 del x 4783 support.gc_collect() 4784 self.assertIsNone(wr()) 4785 for o in gc.get_objects(): 4786 self.assertIsNot(type(o), X) 4787 4788 def test_object_new_and_init_with_parameters(self): 4789 # See issue #1683368 4790 class OverrideNeither: 4791 pass 4792 self.assertRaises(TypeError, OverrideNeither, 1) 4793 self.assertRaises(TypeError, OverrideNeither, kw=1) 4794 class OverrideNew: 4795 def __new__(cls, foo, kw=0, *args, **kwds): 4796 return object.__new__(cls, *args, **kwds) 4797 class OverrideInit: 4798 def __init__(self, foo, kw=0, *args, **kwargs): 4799 return object.__init__(self, *args, **kwargs) 4800 class OverrideBoth(OverrideNew, OverrideInit): 4801 pass 4802 for case in OverrideNew, OverrideInit, OverrideBoth: 4803 case(1) 4804 case(1, kw=2) 4805 self.assertRaises(TypeError, case, 1, 2, 3) 4806 self.assertRaises(TypeError, case, 1, 2, foo=3) 4807 4808 def test_subclassing_does_not_duplicate_dict_descriptors(self): 4809 class Base: 4810 pass 4811 class Sub(Base): 4812 pass 4813 self.assertIn("__dict__", Base.__dict__) 4814 self.assertNotIn("__dict__", Sub.__dict__) 4815 4816 def test_bound_method_repr(self): 4817 class Foo: 4818 def method(self): 4819 pass 4820 self.assertRegex(repr(Foo().method), 4821 r"<bound method .*Foo\.method of <.*Foo object at .*>>") 4822 4823 4824 class Base: 4825 def method(self): 4826 pass 4827 class Derived1(Base): 4828 pass 4829 class Derived2(Base): 4830 def method(self): 4831 pass 4832 base = Base() 4833 derived1 = Derived1() 4834 derived2 = Derived2() 4835 super_d2 = super(Derived2, derived2) 4836 self.assertRegex(repr(base.method), 4837 r"<bound method .*Base\.method of <.*Base object at .*>>") 4838 self.assertRegex(repr(derived1.method), 4839 r"<bound method .*Base\.method of <.*Derived1 object at .*>>") 4840 self.assertRegex(repr(derived2.method), 4841 r"<bound method .*Derived2\.method of <.*Derived2 object at .*>>") 4842 self.assertRegex(repr(super_d2.method), 4843 r"<bound method .*Base\.method of <.*Derived2 object at .*>>") 4844 4845 class Foo: 4846 @classmethod 4847 def method(cls): 4848 pass 4849 foo = Foo() 4850 self.assertRegex(repr(foo.method), # access via instance 4851 r"<bound method .*Foo\.method of <class '.*Foo'>>") 4852 self.assertRegex(repr(Foo.method), # access via the class 4853 r"<bound method .*Foo\.method of <class '.*Foo'>>") 4854 4855 4856 class MyCallable: 4857 def __call__(self, arg): 4858 pass 4859 func = MyCallable() # func has no __name__ or __qualname__ attributes 4860 instance = object() 4861 method = types.MethodType(func, instance) 4862 self.assertRegex(repr(method), 4863 r"<bound method \? of <object object at .*>>") 4864 func.__name__ = "name" 4865 self.assertRegex(repr(method), 4866 r"<bound method name of <object object at .*>>") 4867 func.__qualname__ = "qualname" 4868 self.assertRegex(repr(method), 4869 r"<bound method qualname of <object object at .*>>") 4870 4871 @unittest.skipIf(_testcapi is None, 'need the _testcapi module') 4872 def test_bpo25750(self): 4873 # bpo-25750: calling a descriptor (implemented as built-in 4874 # function with METH_FASTCALL) should not crash CPython if the 4875 # descriptor deletes itself from the class. 4876 class Descr: 4877 __get__ = _testcapi.bad_get 4878 4879 class X: 4880 descr = Descr() 4881 def __new__(cls): 4882 cls.descr = None 4883 # Create this large list to corrupt some unused memory 4884 cls.lst = [2**i for i in range(10000)] 4885 X.descr 4886 4887 4888class DictProxyTests(unittest.TestCase): 4889 def setUp(self): 4890 class C(object): 4891 def meth(self): 4892 pass 4893 self.C = C 4894 4895 @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 4896 'trace function introduces __local__') 4897 def test_iter_keys(self): 4898 # Testing dict-proxy keys... 4899 it = self.C.__dict__.keys() 4900 self.assertNotIsInstance(it, list) 4901 keys = list(it) 4902 keys.sort() 4903 self.assertEqual(keys, ['__dict__', '__doc__', '__module__', 4904 '__weakref__', 'meth']) 4905 4906 @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 4907 'trace function introduces __local__') 4908 def test_iter_values(self): 4909 # Testing dict-proxy values... 4910 it = self.C.__dict__.values() 4911 self.assertNotIsInstance(it, list) 4912 values = list(it) 4913 self.assertEqual(len(values), 5) 4914 4915 @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 4916 'trace function introduces __local__') 4917 def test_iter_items(self): 4918 # Testing dict-proxy iteritems... 4919 it = self.C.__dict__.items() 4920 self.assertNotIsInstance(it, list) 4921 keys = [item[0] for item in it] 4922 keys.sort() 4923 self.assertEqual(keys, ['__dict__', '__doc__', '__module__', 4924 '__weakref__', 'meth']) 4925 4926 def test_dict_type_with_metaclass(self): 4927 # Testing type of __dict__ when metaclass set... 4928 class B(object): 4929 pass 4930 class M(type): 4931 pass 4932 class C(metaclass=M): 4933 # In 2.3a1, C.__dict__ was a real dict rather than a dict proxy 4934 pass 4935 self.assertEqual(type(C.__dict__), type(B.__dict__)) 4936 4937 def test_repr(self): 4938 # Testing mappingproxy.__repr__. 4939 # We can't blindly compare with the repr of another dict as ordering 4940 # of keys and values is arbitrary and may differ. 4941 r = repr(self.C.__dict__) 4942 self.assertTrue(r.startswith('mappingproxy('), r) 4943 self.assertTrue(r.endswith(')'), r) 4944 for k, v in self.C.__dict__.items(): 4945 self.assertIn('{!r}: {!r}'.format(k, v), r) 4946 4947 4948class AAAPTypesLongInitTest(unittest.TestCase): 4949 # This is in its own TestCase so that it can be run before any other tests. 4950 # (Hence the 'AAA' in the test class name: to make it the first 4951 # item in a list sorted by name, like 4952 # unittest.TestLoader.getTestCaseNames() does.) 4953 def test_pytype_long_ready(self): 4954 # Testing SF bug 551412 ... 4955 4956 # This dumps core when SF bug 551412 isn't fixed -- 4957 # but only when test_descr.py is run separately. 4958 # (That can't be helped -- as soon as PyType_Ready() 4959 # is called for PyLong_Type, the bug is gone.) 4960 class UserLong(object): 4961 def __pow__(self, *args): 4962 pass 4963 try: 4964 pow(0, UserLong(), 0) 4965 except: 4966 pass 4967 4968 # Another segfault only when run early 4969 # (before PyType_Ready(tuple) is called) 4970 type.mro(tuple) 4971 4972 4973class MiscTests(unittest.TestCase): 4974 def test_type_lookup_mro_reference(self): 4975 # Issue #14199: _PyType_Lookup() has to keep a strong reference to 4976 # the type MRO because it may be modified during the lookup, if 4977 # __bases__ is set during the lookup for example. 4978 class MyKey(object): 4979 def __hash__(self): 4980 return hash('mykey') 4981 4982 def __eq__(self, other): 4983 X.__bases__ = (Base2,) 4984 4985 class Base(object): 4986 mykey = 'from Base' 4987 mykey2 = 'from Base' 4988 4989 class Base2(object): 4990 mykey = 'from Base2' 4991 mykey2 = 'from Base2' 4992 4993 X = type('X', (Base,), {MyKey(): 5}) 4994 # mykey is read from Base 4995 self.assertEqual(X.mykey, 'from Base') 4996 # mykey2 is read from Base2 because MyKey.__eq__ has set __bases__ 4997 self.assertEqual(X.mykey2, 'from Base2') 4998 4999 5000class PicklingTests(unittest.TestCase): 5001 5002 def _check_reduce(self, proto, obj, args=(), kwargs={}, state=None, 5003 listitems=None, dictitems=None): 5004 if proto >= 2: 5005 reduce_value = obj.__reduce_ex__(proto) 5006 if kwargs: 5007 self.assertEqual(reduce_value[0], copyreg.__newobj_ex__) 5008 self.assertEqual(reduce_value[1], (type(obj), args, kwargs)) 5009 else: 5010 self.assertEqual(reduce_value[0], copyreg.__newobj__) 5011 self.assertEqual(reduce_value[1], (type(obj),) + args) 5012 self.assertEqual(reduce_value[2], state) 5013 if listitems is not None: 5014 self.assertListEqual(list(reduce_value[3]), listitems) 5015 else: 5016 self.assertIsNone(reduce_value[3]) 5017 if dictitems is not None: 5018 self.assertDictEqual(dict(reduce_value[4]), dictitems) 5019 else: 5020 self.assertIsNone(reduce_value[4]) 5021 else: 5022 base_type = type(obj).__base__ 5023 reduce_value = (copyreg._reconstructor, 5024 (type(obj), 5025 base_type, 5026 None if base_type is object else base_type(obj))) 5027 if state is not None: 5028 reduce_value += (state,) 5029 self.assertEqual(obj.__reduce_ex__(proto), reduce_value) 5030 self.assertEqual(obj.__reduce__(), reduce_value) 5031 5032 def test_reduce(self): 5033 protocols = range(pickle.HIGHEST_PROTOCOL + 1) 5034 args = (-101, "spam") 5035 kwargs = {'bacon': -201, 'fish': -301} 5036 state = {'cheese': -401} 5037 5038 class C1: 5039 def __getnewargs__(self): 5040 return args 5041 obj = C1() 5042 for proto in protocols: 5043 self._check_reduce(proto, obj, args) 5044 5045 for name, value in state.items(): 5046 setattr(obj, name, value) 5047 for proto in protocols: 5048 self._check_reduce(proto, obj, args, state=state) 5049 5050 class C2: 5051 def __getnewargs__(self): 5052 return "bad args" 5053 obj = C2() 5054 for proto in protocols: 5055 if proto >= 2: 5056 with self.assertRaises(TypeError): 5057 obj.__reduce_ex__(proto) 5058 5059 class C3: 5060 def __getnewargs_ex__(self): 5061 return (args, kwargs) 5062 obj = C3() 5063 for proto in protocols: 5064 if proto >= 2: 5065 self._check_reduce(proto, obj, args, kwargs) 5066 5067 class C4: 5068 def __getnewargs_ex__(self): 5069 return (args, "bad dict") 5070 class C5: 5071 def __getnewargs_ex__(self): 5072 return ("bad tuple", kwargs) 5073 class C6: 5074 def __getnewargs_ex__(self): 5075 return () 5076 class C7: 5077 def __getnewargs_ex__(self): 5078 return "bad args" 5079 for proto in protocols: 5080 for cls in C4, C5, C6, C7: 5081 obj = cls() 5082 if proto >= 2: 5083 with self.assertRaises((TypeError, ValueError)): 5084 obj.__reduce_ex__(proto) 5085 5086 class C9: 5087 def __getnewargs_ex__(self): 5088 return (args, {}) 5089 obj = C9() 5090 for proto in protocols: 5091 self._check_reduce(proto, obj, args) 5092 5093 class C10: 5094 def __getnewargs_ex__(self): 5095 raise IndexError 5096 obj = C10() 5097 for proto in protocols: 5098 if proto >= 2: 5099 with self.assertRaises(IndexError): 5100 obj.__reduce_ex__(proto) 5101 5102 class C11: 5103 def __getstate__(self): 5104 return state 5105 obj = C11() 5106 for proto in protocols: 5107 self._check_reduce(proto, obj, state=state) 5108 5109 class C12: 5110 def __getstate__(self): 5111 return "not dict" 5112 obj = C12() 5113 for proto in protocols: 5114 self._check_reduce(proto, obj, state="not dict") 5115 5116 class C13: 5117 def __getstate__(self): 5118 raise IndexError 5119 obj = C13() 5120 for proto in protocols: 5121 with self.assertRaises(IndexError): 5122 obj.__reduce_ex__(proto) 5123 if proto < 2: 5124 with self.assertRaises(IndexError): 5125 obj.__reduce__() 5126 5127 class C14: 5128 __slots__ = tuple(state) 5129 def __init__(self): 5130 for name, value in state.items(): 5131 setattr(self, name, value) 5132 5133 obj = C14() 5134 for proto in protocols: 5135 if proto >= 2: 5136 self._check_reduce(proto, obj, state=(None, state)) 5137 else: 5138 with self.assertRaises(TypeError): 5139 obj.__reduce_ex__(proto) 5140 with self.assertRaises(TypeError): 5141 obj.__reduce__() 5142 5143 class C15(dict): 5144 pass 5145 obj = C15({"quebec": -601}) 5146 for proto in protocols: 5147 self._check_reduce(proto, obj, dictitems=dict(obj)) 5148 5149 class C16(list): 5150 pass 5151 obj = C16(["yukon"]) 5152 for proto in protocols: 5153 self._check_reduce(proto, obj, listitems=list(obj)) 5154 5155 def test_special_method_lookup(self): 5156 protocols = range(pickle.HIGHEST_PROTOCOL + 1) 5157 class Picky: 5158 def __getstate__(self): 5159 return {} 5160 5161 def __getattr__(self, attr): 5162 if attr in ("__getnewargs__", "__getnewargs_ex__"): 5163 raise AssertionError(attr) 5164 return None 5165 for protocol in protocols: 5166 state = {} if protocol >= 2 else None 5167 self._check_reduce(protocol, Picky(), state=state) 5168 5169 def _assert_is_copy(self, obj, objcopy, msg=None): 5170 """Utility method to verify if two objects are copies of each others. 5171 """ 5172 if msg is None: 5173 msg = "{!r} is not a copy of {!r}".format(obj, objcopy) 5174 if type(obj).__repr__ is object.__repr__: 5175 # We have this limitation for now because we use the object's repr 5176 # to help us verify that the two objects are copies. This allows 5177 # us to delegate the non-generic verification logic to the objects 5178 # themselves. 5179 raise ValueError("object passed to _assert_is_copy must " + 5180 "override the __repr__ method.") 5181 self.assertIsNot(obj, objcopy, msg=msg) 5182 self.assertIs(type(obj), type(objcopy), msg=msg) 5183 if hasattr(obj, '__dict__'): 5184 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg) 5185 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg) 5186 if hasattr(obj, '__slots__'): 5187 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg) 5188 for slot in obj.__slots__: 5189 self.assertEqual( 5190 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg) 5191 self.assertEqual(getattr(obj, slot, None), 5192 getattr(objcopy, slot, None), msg=msg) 5193 self.assertEqual(repr(obj), repr(objcopy), msg=msg) 5194 5195 @staticmethod 5196 def _generate_pickle_copiers(): 5197 """Utility method to generate the many possible pickle configurations. 5198 """ 5199 class PickleCopier: 5200 "This class copies object using pickle." 5201 def __init__(self, proto, dumps, loads): 5202 self.proto = proto 5203 self.dumps = dumps 5204 self.loads = loads 5205 def copy(self, obj): 5206 return self.loads(self.dumps(obj, self.proto)) 5207 def __repr__(self): 5208 # We try to be as descriptive as possible here since this is 5209 # the string which we will allow us to tell the pickle 5210 # configuration we are using during debugging. 5211 return ("PickleCopier(proto={}, dumps={}.{}, loads={}.{})" 5212 .format(self.proto, 5213 self.dumps.__module__, self.dumps.__qualname__, 5214 self.loads.__module__, self.loads.__qualname__)) 5215 return (PickleCopier(*args) for args in 5216 itertools.product(range(pickle.HIGHEST_PROTOCOL + 1), 5217 {pickle.dumps, pickle._dumps}, 5218 {pickle.loads, pickle._loads})) 5219 5220 def test_pickle_slots(self): 5221 # Tests pickling of classes with __slots__. 5222 5223 # Pickling of classes with __slots__ but without __getstate__ should 5224 # fail (if using protocol 0 or 1) 5225 global C 5226 class C: 5227 __slots__ = ['a'] 5228 with self.assertRaises(TypeError): 5229 pickle.dumps(C(), 0) 5230 5231 global D 5232 class D(C): 5233 pass 5234 with self.assertRaises(TypeError): 5235 pickle.dumps(D(), 0) 5236 5237 class C: 5238 "A class with __getstate__ and __setstate__ implemented." 5239 __slots__ = ['a'] 5240 def __getstate__(self): 5241 state = getattr(self, '__dict__', {}).copy() 5242 for cls in type(self).__mro__: 5243 for slot in cls.__dict__.get('__slots__', ()): 5244 try: 5245 state[slot] = getattr(self, slot) 5246 except AttributeError: 5247 pass 5248 return state 5249 def __setstate__(self, state): 5250 for k, v in state.items(): 5251 setattr(self, k, v) 5252 def __repr__(self): 5253 return "%s()<%r>" % (type(self).__name__, self.__getstate__()) 5254 5255 class D(C): 5256 "A subclass of a class with slots." 5257 pass 5258 5259 global E 5260 class E(C): 5261 "A subclass with an extra slot." 5262 __slots__ = ['b'] 5263 5264 # Now it should work 5265 for pickle_copier in self._generate_pickle_copiers(): 5266 with self.subTest(pickle_copier=pickle_copier): 5267 x = C() 5268 y = pickle_copier.copy(x) 5269 self._assert_is_copy(x, y) 5270 5271 x.a = 42 5272 y = pickle_copier.copy(x) 5273 self._assert_is_copy(x, y) 5274 5275 x = D() 5276 x.a = 42 5277 x.b = 100 5278 y = pickle_copier.copy(x) 5279 self._assert_is_copy(x, y) 5280 5281 x = E() 5282 x.a = 42 5283 x.b = "foo" 5284 y = pickle_copier.copy(x) 5285 self._assert_is_copy(x, y) 5286 5287 def test_reduce_copying(self): 5288 # Tests pickling and copying new-style classes and objects. 5289 global C1 5290 class C1: 5291 "The state of this class is copyable via its instance dict." 5292 ARGS = (1, 2) 5293 NEED_DICT_COPYING = True 5294 def __init__(self, a, b): 5295 super().__init__() 5296 self.a = a 5297 self.b = b 5298 def __repr__(self): 5299 return "C1(%r, %r)" % (self.a, self.b) 5300 5301 global C2 5302 class C2(list): 5303 "A list subclass copyable via __getnewargs__." 5304 ARGS = (1, 2) 5305 NEED_DICT_COPYING = False 5306 def __new__(cls, a, b): 5307 self = super().__new__(cls) 5308 self.a = a 5309 self.b = b 5310 return self 5311 def __init__(self, *args): 5312 super().__init__() 5313 # This helps testing that __init__ is not called during the 5314 # unpickling process, which would cause extra appends. 5315 self.append("cheese") 5316 @classmethod 5317 def __getnewargs__(cls): 5318 return cls.ARGS 5319 def __repr__(self): 5320 return "C2(%r, %r)<%r>" % (self.a, self.b, list(self)) 5321 5322 global C3 5323 class C3(list): 5324 "A list subclass copyable via __getstate__." 5325 ARGS = (1, 2) 5326 NEED_DICT_COPYING = False 5327 def __init__(self, a, b): 5328 self.a = a 5329 self.b = b 5330 # This helps testing that __init__ is not called during the 5331 # unpickling process, which would cause extra appends. 5332 self.append("cheese") 5333 @classmethod 5334 def __getstate__(cls): 5335 return cls.ARGS 5336 def __setstate__(self, state): 5337 a, b = state 5338 self.a = a 5339 self.b = b 5340 def __repr__(self): 5341 return "C3(%r, %r)<%r>" % (self.a, self.b, list(self)) 5342 5343 global C4 5344 class C4(int): 5345 "An int subclass copyable via __getnewargs__." 5346 ARGS = ("hello", "world", 1) 5347 NEED_DICT_COPYING = False 5348 def __new__(cls, a, b, value): 5349 self = super().__new__(cls, value) 5350 self.a = a 5351 self.b = b 5352 return self 5353 @classmethod 5354 def __getnewargs__(cls): 5355 return cls.ARGS 5356 def __repr__(self): 5357 return "C4(%r, %r)<%r>" % (self.a, self.b, int(self)) 5358 5359 global C5 5360 class C5(int): 5361 "An int subclass copyable via __getnewargs_ex__." 5362 ARGS = (1, 2) 5363 KWARGS = {'value': 3} 5364 NEED_DICT_COPYING = False 5365 def __new__(cls, a, b, *, value=0): 5366 self = super().__new__(cls, value) 5367 self.a = a 5368 self.b = b 5369 return self 5370 @classmethod 5371 def __getnewargs_ex__(cls): 5372 return (cls.ARGS, cls.KWARGS) 5373 def __repr__(self): 5374 return "C5(%r, %r)<%r>" % (self.a, self.b, int(self)) 5375 5376 test_classes = (C1, C2, C3, C4, C5) 5377 # Testing copying through pickle 5378 pickle_copiers = self._generate_pickle_copiers() 5379 for cls, pickle_copier in itertools.product(test_classes, pickle_copiers): 5380 with self.subTest(cls=cls, pickle_copier=pickle_copier): 5381 kwargs = getattr(cls, 'KWARGS', {}) 5382 obj = cls(*cls.ARGS, **kwargs) 5383 proto = pickle_copier.proto 5384 objcopy = pickle_copier.copy(obj) 5385 self._assert_is_copy(obj, objcopy) 5386 # For test classes that supports this, make sure we didn't go 5387 # around the reduce protocol by simply copying the attribute 5388 # dictionary. We clear attributes using the previous copy to 5389 # not mutate the original argument. 5390 if proto >= 2 and not cls.NEED_DICT_COPYING: 5391 objcopy.__dict__.clear() 5392 objcopy2 = pickle_copier.copy(objcopy) 5393 self._assert_is_copy(obj, objcopy2) 5394 5395 # Testing copying through copy.deepcopy() 5396 for cls in test_classes: 5397 with self.subTest(cls=cls): 5398 kwargs = getattr(cls, 'KWARGS', {}) 5399 obj = cls(*cls.ARGS, **kwargs) 5400 objcopy = deepcopy(obj) 5401 self._assert_is_copy(obj, objcopy) 5402 # For test classes that supports this, make sure we didn't go 5403 # around the reduce protocol by simply copying the attribute 5404 # dictionary. We clear attributes using the previous copy to 5405 # not mutate the original argument. 5406 if not cls.NEED_DICT_COPYING: 5407 objcopy.__dict__.clear() 5408 objcopy2 = deepcopy(objcopy) 5409 self._assert_is_copy(obj, objcopy2) 5410 5411 def test_issue24097(self): 5412 # Slot name is freed inside __getattr__ and is later used. 5413 class S(str): # Not interned 5414 pass 5415 class A: 5416 __slotnames__ = [S('spam')] 5417 def __getattr__(self, attr): 5418 if attr == 'spam': 5419 A.__slotnames__[:] = [S('spam')] 5420 return 42 5421 else: 5422 raise AttributeError 5423 5424 import copyreg 5425 expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None) 5426 self.assertEqual(A().__reduce_ex__(2), expected) # Shouldn't crash 5427 5428 def test_object_reduce(self): 5429 # Issue #29914 5430 # __reduce__() takes no arguments 5431 object().__reduce__() 5432 with self.assertRaises(TypeError): 5433 object().__reduce__(0) 5434 # __reduce_ex__() takes one integer argument 5435 object().__reduce_ex__(0) 5436 with self.assertRaises(TypeError): 5437 object().__reduce_ex__() 5438 with self.assertRaises(TypeError): 5439 object().__reduce_ex__(None) 5440 5441 5442class SharedKeyTests(unittest.TestCase): 5443 5444 @support.cpython_only 5445 def test_subclasses(self): 5446 # Verify that subclasses can share keys (per PEP 412) 5447 class A: 5448 pass 5449 class B(A): 5450 pass 5451 5452 a, b = A(), B() 5453 self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) 5454 self.assertLess(sys.getsizeof(vars(a)), sys.getsizeof({"a":1})) 5455 # Initial hash table can contain at most 5 elements. 5456 # Set 6 attributes to cause internal resizing. 5457 a.x, a.y, a.z, a.w, a.v, a.u = range(6) 5458 self.assertNotEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) 5459 a2 = A() 5460 self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(a2))) 5461 self.assertLess(sys.getsizeof(vars(a)), sys.getsizeof({"a":1})) 5462 b.u, b.v, b.w, b.t, b.s, b.r = range(6) 5463 self.assertLess(sys.getsizeof(vars(b)), sys.getsizeof({"a":1})) 5464 5465 5466class DebugHelperMeta(type): 5467 """ 5468 Sets default __doc__ and simplifies repr() output. 5469 """ 5470 def __new__(mcls, name, bases, attrs): 5471 if attrs.get('__doc__') is None: 5472 attrs['__doc__'] = name # helps when debugging with gdb 5473 return type.__new__(mcls, name, bases, attrs) 5474 def __repr__(cls): 5475 return repr(cls.__name__) 5476 5477 5478class MroTest(unittest.TestCase): 5479 """ 5480 Regressions for some bugs revealed through 5481 mcsl.mro() customization (typeobject.c: mro_internal()) and 5482 cls.__bases__ assignment (typeobject.c: type_set_bases()). 5483 """ 5484 5485 def setUp(self): 5486 self.step = 0 5487 self.ready = False 5488 5489 def step_until(self, limit): 5490 ret = (self.step < limit) 5491 if ret: 5492 self.step += 1 5493 return ret 5494 5495 def test_incomplete_set_bases_on_self(self): 5496 """ 5497 type_set_bases must be aware that type->tp_mro can be NULL. 5498 """ 5499 class M(DebugHelperMeta): 5500 def mro(cls): 5501 if self.step_until(1): 5502 assert cls.__mro__ is None 5503 cls.__bases__ += () 5504 5505 return type.mro(cls) 5506 5507 class A(metaclass=M): 5508 pass 5509 5510 def test_reent_set_bases_on_base(self): 5511 """ 5512 Deep reentrancy must not over-decref old_mro. 5513 """ 5514 class M(DebugHelperMeta): 5515 def mro(cls): 5516 if cls.__mro__ is not None and cls.__name__ == 'B': 5517 # 4-5 steps are usually enough to make it crash somewhere 5518 if self.step_until(10): 5519 A.__bases__ += () 5520 5521 return type.mro(cls) 5522 5523 class A(metaclass=M): 5524 pass 5525 class B(A): 5526 pass 5527 B.__bases__ += () 5528 5529 def test_reent_set_bases_on_direct_base(self): 5530 """ 5531 Similar to test_reent_set_bases_on_base, but may crash differently. 5532 """ 5533 class M(DebugHelperMeta): 5534 def mro(cls): 5535 base = cls.__bases__[0] 5536 if base is not object: 5537 if self.step_until(5): 5538 base.__bases__ += () 5539 5540 return type.mro(cls) 5541 5542 class A(metaclass=M): 5543 pass 5544 class B(A): 5545 pass 5546 class C(B): 5547 pass 5548 5549 def test_reent_set_bases_tp_base_cycle(self): 5550 """ 5551 type_set_bases must check for an inheritance cycle not only through 5552 MRO of the type, which may be not yet updated in case of reentrance, 5553 but also through tp_base chain, which is assigned before diving into 5554 inner calls to mro(). 5555 5556 Otherwise, the following snippet can loop forever: 5557 do { 5558 // ... 5559 type = type->tp_base; 5560 } while (type != NULL); 5561 5562 Functions that rely on tp_base (like solid_base and PyType_IsSubtype) 5563 would not be happy in that case, causing a stack overflow. 5564 """ 5565 class M(DebugHelperMeta): 5566 def mro(cls): 5567 if self.ready: 5568 if cls.__name__ == 'B1': 5569 B2.__bases__ = (B1,) 5570 if cls.__name__ == 'B2': 5571 B1.__bases__ = (B2,) 5572 return type.mro(cls) 5573 5574 class A(metaclass=M): 5575 pass 5576 class B1(A): 5577 pass 5578 class B2(A): 5579 pass 5580 5581 self.ready = True 5582 with self.assertRaises(TypeError): 5583 B1.__bases__ += () 5584 5585 def test_tp_subclasses_cycle_in_update_slots(self): 5586 """ 5587 type_set_bases must check for reentrancy upon finishing its job 5588 by updating tp_subclasses of old/new bases of the type. 5589 Otherwise, an implicit inheritance cycle through tp_subclasses 5590 can break functions that recurse on elements of that field 5591 (like recurse_down_subclasses and mro_hierarchy) eventually 5592 leading to a stack overflow. 5593 """ 5594 class M(DebugHelperMeta): 5595 def mro(cls): 5596 if self.ready and cls.__name__ == 'C': 5597 self.ready = False 5598 C.__bases__ = (B2,) 5599 return type.mro(cls) 5600 5601 class A(metaclass=M): 5602 pass 5603 class B1(A): 5604 pass 5605 class B2(A): 5606 pass 5607 class C(A): 5608 pass 5609 5610 self.ready = True 5611 C.__bases__ = (B1,) 5612 B1.__bases__ = (C,) 5613 5614 self.assertEqual(C.__bases__, (B2,)) 5615 self.assertEqual(B2.__subclasses__(), [C]) 5616 self.assertEqual(B1.__subclasses__(), []) 5617 5618 self.assertEqual(B1.__bases__, (C,)) 5619 self.assertEqual(C.__subclasses__(), [B1]) 5620 5621 def test_tp_subclasses_cycle_error_return_path(self): 5622 """ 5623 The same as test_tp_subclasses_cycle_in_update_slots, but tests 5624 a code path executed on error (goto bail). 5625 """ 5626 class E(Exception): 5627 pass 5628 class M(DebugHelperMeta): 5629 def mro(cls): 5630 if self.ready and cls.__name__ == 'C': 5631 if C.__bases__ == (B2,): 5632 self.ready = False 5633 else: 5634 C.__bases__ = (B2,) 5635 raise E 5636 return type.mro(cls) 5637 5638 class A(metaclass=M): 5639 pass 5640 class B1(A): 5641 pass 5642 class B2(A): 5643 pass 5644 class C(A): 5645 pass 5646 5647 self.ready = True 5648 with self.assertRaises(E): 5649 C.__bases__ = (B1,) 5650 B1.__bases__ = (C,) 5651 5652 self.assertEqual(C.__bases__, (B2,)) 5653 self.assertEqual(C.__mro__, tuple(type.mro(C))) 5654 5655 def test_incomplete_extend(self): 5656 """ 5657 Extending an unitialized type with type->tp_mro == NULL must 5658 throw a reasonable TypeError exception, instead of failing 5659 with PyErr_BadInternalCall. 5660 """ 5661 class M(DebugHelperMeta): 5662 def mro(cls): 5663 if cls.__mro__ is None and cls.__name__ != 'X': 5664 with self.assertRaises(TypeError): 5665 class X(cls): 5666 pass 5667 5668 return type.mro(cls) 5669 5670 class A(metaclass=M): 5671 pass 5672 5673 def test_incomplete_super(self): 5674 """ 5675 Attribute lookup on a super object must be aware that 5676 its target type can be uninitialized (type->tp_mro == NULL). 5677 """ 5678 class M(DebugHelperMeta): 5679 def mro(cls): 5680 if cls.__mro__ is None: 5681 with self.assertRaises(AttributeError): 5682 super(cls, cls).xxx 5683 5684 return type.mro(cls) 5685 5686 class A(metaclass=M): 5687 pass 5688 5689 5690if __name__ == "__main__": 5691 unittest.main() 5692