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 # Inherit from object on purpose to check some backwards compatibility paths 1307 class X(object): 1308 __slots__ = "a" 1309 with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"): 1310 X().a 1311 1312 def test_slots_special(self): 1313 # Testing __dict__ and __weakref__ in __slots__... 1314 class D(object): 1315 __slots__ = ["__dict__"] 1316 a = D() 1317 self.assertHasAttr(a, "__dict__") 1318 self.assertNotHasAttr(a, "__weakref__") 1319 a.foo = 42 1320 self.assertEqual(a.__dict__, {"foo": 42}) 1321 1322 class W(object): 1323 __slots__ = ["__weakref__"] 1324 a = W() 1325 self.assertHasAttr(a, "__weakref__") 1326 self.assertNotHasAttr(a, "__dict__") 1327 try: 1328 a.foo = 42 1329 except AttributeError: 1330 pass 1331 else: 1332 self.fail("shouldn't be allowed to set a.foo") 1333 1334 class C1(W, D): 1335 __slots__ = [] 1336 a = C1() 1337 self.assertHasAttr(a, "__dict__") 1338 self.assertHasAttr(a, "__weakref__") 1339 a.foo = 42 1340 self.assertEqual(a.__dict__, {"foo": 42}) 1341 1342 class C2(D, W): 1343 __slots__ = [] 1344 a = C2() 1345 self.assertHasAttr(a, "__dict__") 1346 self.assertHasAttr(a, "__weakref__") 1347 a.foo = 42 1348 self.assertEqual(a.__dict__, {"foo": 42}) 1349 1350 def test_slots_special2(self): 1351 # Testing __qualname__ and __classcell__ in __slots__ 1352 class Meta(type): 1353 def __new__(cls, name, bases, namespace, attr): 1354 self.assertIn(attr, namespace) 1355 return super().__new__(cls, name, bases, namespace) 1356 1357 class C1: 1358 def __init__(self): 1359 self.b = 42 1360 class C2(C1, metaclass=Meta, attr="__classcell__"): 1361 __slots__ = ["__classcell__"] 1362 def __init__(self): 1363 super().__init__() 1364 self.assertIsInstance(C2.__dict__["__classcell__"], 1365 types.MemberDescriptorType) 1366 c = C2() 1367 self.assertEqual(c.b, 42) 1368 self.assertNotHasAttr(c, "__classcell__") 1369 c.__classcell__ = 42 1370 self.assertEqual(c.__classcell__, 42) 1371 with self.assertRaises(TypeError): 1372 class C3: 1373 __classcell__ = 42 1374 __slots__ = ["__classcell__"] 1375 1376 class Q1(metaclass=Meta, attr="__qualname__"): 1377 __slots__ = ["__qualname__"] 1378 self.assertEqual(Q1.__qualname__, C1.__qualname__[:-2] + "Q1") 1379 self.assertIsInstance(Q1.__dict__["__qualname__"], 1380 types.MemberDescriptorType) 1381 q = Q1() 1382 self.assertNotHasAttr(q, "__qualname__") 1383 q.__qualname__ = "q" 1384 self.assertEqual(q.__qualname__, "q") 1385 with self.assertRaises(TypeError): 1386 class Q2: 1387 __qualname__ = object() 1388 __slots__ = ["__qualname__"] 1389 1390 def test_slots_descriptor(self): 1391 # Issue2115: slot descriptors did not correctly check 1392 # the type of the given object 1393 import abc 1394 class MyABC(metaclass=abc.ABCMeta): 1395 __slots__ = "a" 1396 1397 class Unrelated(object): 1398 pass 1399 MyABC.register(Unrelated) 1400 1401 u = Unrelated() 1402 self.assertIsInstance(u, MyABC) 1403 1404 # This used to crash 1405 self.assertRaises(TypeError, MyABC.a.__set__, u, 3) 1406 1407 def test_dynamics(self): 1408 # Testing class attribute propagation... 1409 class D(object): 1410 pass 1411 class E(D): 1412 pass 1413 class F(D): 1414 pass 1415 D.foo = 1 1416 self.assertEqual(D.foo, 1) 1417 # Test that dynamic attributes are inherited 1418 self.assertEqual(E.foo, 1) 1419 self.assertEqual(F.foo, 1) 1420 # Test dynamic instances 1421 class C(object): 1422 pass 1423 a = C() 1424 self.assertNotHasAttr(a, "foobar") 1425 C.foobar = 2 1426 self.assertEqual(a.foobar, 2) 1427 C.method = lambda self: 42 1428 self.assertEqual(a.method(), 42) 1429 C.__repr__ = lambda self: "C()" 1430 self.assertEqual(repr(a), "C()") 1431 C.__int__ = lambda self: 100 1432 self.assertEqual(int(a), 100) 1433 self.assertEqual(a.foobar, 2) 1434 self.assertNotHasAttr(a, "spam") 1435 def mygetattr(self, name): 1436 if name == "spam": 1437 return "spam" 1438 raise AttributeError 1439 C.__getattr__ = mygetattr 1440 self.assertEqual(a.spam, "spam") 1441 a.new = 12 1442 self.assertEqual(a.new, 12) 1443 def mysetattr(self, name, value): 1444 if name == "spam": 1445 raise AttributeError 1446 return object.__setattr__(self, name, value) 1447 C.__setattr__ = mysetattr 1448 try: 1449 a.spam = "not spam" 1450 except AttributeError: 1451 pass 1452 else: 1453 self.fail("expected AttributeError") 1454 self.assertEqual(a.spam, "spam") 1455 class D(C): 1456 pass 1457 d = D() 1458 d.foo = 1 1459 self.assertEqual(d.foo, 1) 1460 1461 # Test handling of int*seq and seq*int 1462 class I(int): 1463 pass 1464 self.assertEqual("a"*I(2), "aa") 1465 self.assertEqual(I(2)*"a", "aa") 1466 self.assertEqual(2*I(3), 6) 1467 self.assertEqual(I(3)*2, 6) 1468 self.assertEqual(I(3)*I(2), 6) 1469 1470 # Test comparison of classes with dynamic metaclasses 1471 class dynamicmetaclass(type): 1472 pass 1473 class someclass(metaclass=dynamicmetaclass): 1474 pass 1475 self.assertNotEqual(someclass, object) 1476 1477 def test_errors(self): 1478 # Testing errors... 1479 try: 1480 class C(list, dict): 1481 pass 1482 except TypeError: 1483 pass 1484 else: 1485 self.fail("inheritance from both list and dict should be illegal") 1486 1487 try: 1488 class C(object, None): 1489 pass 1490 except TypeError: 1491 pass 1492 else: 1493 self.fail("inheritance from non-type should be illegal") 1494 class Classic: 1495 pass 1496 1497 try: 1498 class C(type(len)): 1499 pass 1500 except TypeError: 1501 pass 1502 else: 1503 self.fail("inheritance from CFunction should be illegal") 1504 1505 try: 1506 class C(object): 1507 __slots__ = 1 1508 except TypeError: 1509 pass 1510 else: 1511 self.fail("__slots__ = 1 should be illegal") 1512 1513 try: 1514 class C(object): 1515 __slots__ = [1] 1516 except TypeError: 1517 pass 1518 else: 1519 self.fail("__slots__ = [1] should be illegal") 1520 1521 class M1(type): 1522 pass 1523 class M2(type): 1524 pass 1525 class A1(object, metaclass=M1): 1526 pass 1527 class A2(object, metaclass=M2): 1528 pass 1529 try: 1530 class B(A1, A2): 1531 pass 1532 except TypeError: 1533 pass 1534 else: 1535 self.fail("finding the most derived metaclass should have failed") 1536 1537 def test_classmethods(self): 1538 # Testing class methods... 1539 class C(object): 1540 def foo(*a): return a 1541 goo = classmethod(foo) 1542 c = C() 1543 self.assertEqual(C.goo(1), (C, 1)) 1544 self.assertEqual(c.goo(1), (C, 1)) 1545 self.assertEqual(c.foo(1), (c, 1)) 1546 class D(C): 1547 pass 1548 d = D() 1549 self.assertEqual(D.goo(1), (D, 1)) 1550 self.assertEqual(d.goo(1), (D, 1)) 1551 self.assertEqual(d.foo(1), (d, 1)) 1552 self.assertEqual(D.foo(d, 1), (d, 1)) 1553 # Test for a specific crash (SF bug 528132) 1554 def f(cls, arg): 1555 "f docstring" 1556 return (cls, arg) 1557 ff = classmethod(f) 1558 self.assertEqual(ff.__get__(0, int)(42), (int, 42)) 1559 self.assertEqual(ff.__get__(0)(42), (int, 42)) 1560 1561 # Test super() with classmethods (SF bug 535444) 1562 self.assertEqual(C.goo.__self__, C) 1563 self.assertEqual(D.goo.__self__, D) 1564 self.assertEqual(super(D,D).goo.__self__, D) 1565 self.assertEqual(super(D,d).goo.__self__, D) 1566 self.assertEqual(super(D,D).goo(), (D,)) 1567 self.assertEqual(super(D,d).goo(), (D,)) 1568 1569 # Verify that a non-callable will raise 1570 meth = classmethod(1).__get__(1) 1571 self.assertRaises(TypeError, meth) 1572 1573 # Verify that classmethod() doesn't allow keyword args 1574 try: 1575 classmethod(f, kw=1) 1576 except TypeError: 1577 pass 1578 else: 1579 self.fail("classmethod shouldn't accept keyword args") 1580 1581 cm = classmethod(f) 1582 cm_dict = {'__annotations__': {}, 1583 '__doc__': "f docstring", 1584 '__module__': __name__, 1585 '__name__': 'f', 1586 '__qualname__': f.__qualname__} 1587 self.assertEqual(cm.__dict__, cm_dict) 1588 1589 cm.x = 42 1590 self.assertEqual(cm.x, 42) 1591 self.assertEqual(cm.__dict__, {"x" : 42, **cm_dict}) 1592 del cm.x 1593 self.assertNotHasAttr(cm, "x") 1594 1595 @support.refcount_test 1596 def test_refleaks_in_classmethod___init__(self): 1597 gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') 1598 cm = classmethod(None) 1599 refs_before = gettotalrefcount() 1600 for i in range(100): 1601 cm.__init__(None) 1602 self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) 1603 1604 @support.impl_detail("the module 'xxsubtype' is internal") 1605 def test_classmethods_in_c(self): 1606 # Testing C-based class methods... 1607 import xxsubtype as spam 1608 a = (1, 2, 3) 1609 d = {'abc': 123} 1610 x, a1, d1 = spam.spamlist.classmeth(*a, **d) 1611 self.assertEqual(x, spam.spamlist) 1612 self.assertEqual(a, a1) 1613 self.assertEqual(d, d1) 1614 x, a1, d1 = spam.spamlist().classmeth(*a, **d) 1615 self.assertEqual(x, spam.spamlist) 1616 self.assertEqual(a, a1) 1617 self.assertEqual(d, d1) 1618 spam_cm = spam.spamlist.__dict__['classmeth'] 1619 x2, a2, d2 = spam_cm(spam.spamlist, *a, **d) 1620 self.assertEqual(x2, spam.spamlist) 1621 self.assertEqual(a2, a1) 1622 self.assertEqual(d2, d1) 1623 class SubSpam(spam.spamlist): pass 1624 x2, a2, d2 = spam_cm(SubSpam, *a, **d) 1625 self.assertEqual(x2, SubSpam) 1626 self.assertEqual(a2, a1) 1627 self.assertEqual(d2, d1) 1628 1629 with self.assertRaises(TypeError) as cm: 1630 spam_cm() 1631 self.assertEqual( 1632 str(cm.exception), 1633 "descriptor 'classmeth' of 'xxsubtype.spamlist' " 1634 "object needs an argument") 1635 1636 with self.assertRaises(TypeError) as cm: 1637 spam_cm(spam.spamlist()) 1638 self.assertEqual( 1639 str(cm.exception), 1640 "descriptor 'classmeth' for type 'xxsubtype.spamlist' " 1641 "needs a type, not a 'xxsubtype.spamlist' as arg 2") 1642 1643 with self.assertRaises(TypeError) as cm: 1644 spam_cm(list) 1645 expected_errmsg = ( 1646 "descriptor 'classmeth' requires a subtype of 'xxsubtype.spamlist' " 1647 "but received 'list'") 1648 self.assertEqual(str(cm.exception), expected_errmsg) 1649 1650 with self.assertRaises(TypeError) as cm: 1651 spam_cm.__get__(None, list) 1652 self.assertEqual(str(cm.exception), expected_errmsg) 1653 1654 def test_staticmethods(self): 1655 # Testing static methods... 1656 class C(object): 1657 def foo(*a): return a 1658 goo = staticmethod(foo) 1659 c = C() 1660 self.assertEqual(C.goo(1), (1,)) 1661 self.assertEqual(c.goo(1), (1,)) 1662 self.assertEqual(c.foo(1), (c, 1,)) 1663 class D(C): 1664 pass 1665 d = D() 1666 self.assertEqual(D.goo(1), (1,)) 1667 self.assertEqual(d.goo(1), (1,)) 1668 self.assertEqual(d.foo(1), (d, 1)) 1669 self.assertEqual(D.foo(d, 1), (d, 1)) 1670 sm = staticmethod(None) 1671 self.assertEqual(sm.__dict__, {'__doc__': None}) 1672 sm.x = 42 1673 self.assertEqual(sm.x, 42) 1674 self.assertEqual(sm.__dict__, {"x" : 42, '__doc__': None}) 1675 del sm.x 1676 self.assertNotHasAttr(sm, "x") 1677 1678 @support.refcount_test 1679 def test_refleaks_in_staticmethod___init__(self): 1680 gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') 1681 sm = staticmethod(None) 1682 refs_before = gettotalrefcount() 1683 for i in range(100): 1684 sm.__init__(None) 1685 self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) 1686 1687 @support.impl_detail("the module 'xxsubtype' is internal") 1688 def test_staticmethods_in_c(self): 1689 # Testing C-based static methods... 1690 import xxsubtype as spam 1691 a = (1, 2, 3) 1692 d = {"abc": 123} 1693 x, a1, d1 = spam.spamlist.staticmeth(*a, **d) 1694 self.assertEqual(x, None) 1695 self.assertEqual(a, a1) 1696 self.assertEqual(d, d1) 1697 x, a1, d2 = spam.spamlist().staticmeth(*a, **d) 1698 self.assertEqual(x, None) 1699 self.assertEqual(a, a1) 1700 self.assertEqual(d, d1) 1701 1702 def test_classic(self): 1703 # Testing classic classes... 1704 class C: 1705 def foo(*a): return a 1706 goo = classmethod(foo) 1707 c = C() 1708 self.assertEqual(C.goo(1), (C, 1)) 1709 self.assertEqual(c.goo(1), (C, 1)) 1710 self.assertEqual(c.foo(1), (c, 1)) 1711 class D(C): 1712 pass 1713 d = D() 1714 self.assertEqual(D.goo(1), (D, 1)) 1715 self.assertEqual(d.goo(1), (D, 1)) 1716 self.assertEqual(d.foo(1), (d, 1)) 1717 self.assertEqual(D.foo(d, 1), (d, 1)) 1718 class E: # *not* subclassing from C 1719 foo = C.foo 1720 self.assertEqual(E().foo.__func__, C.foo) # i.e., unbound 1721 self.assertTrue(repr(C.foo.__get__(C())).startswith("<bound method ")) 1722 1723 def test_compattr(self): 1724 # Testing computed attributes... 1725 class C(object): 1726 class computed_attribute(object): 1727 def __init__(self, get, set=None, delete=None): 1728 self.__get = get 1729 self.__set = set 1730 self.__delete = delete 1731 def __get__(self, obj, type=None): 1732 return self.__get(obj) 1733 def __set__(self, obj, value): 1734 return self.__set(obj, value) 1735 def __delete__(self, obj): 1736 return self.__delete(obj) 1737 def __init__(self): 1738 self.__x = 0 1739 def __get_x(self): 1740 x = self.__x 1741 self.__x = x+1 1742 return x 1743 def __set_x(self, x): 1744 self.__x = x 1745 def __delete_x(self): 1746 del self.__x 1747 x = computed_attribute(__get_x, __set_x, __delete_x) 1748 a = C() 1749 self.assertEqual(a.x, 0) 1750 self.assertEqual(a.x, 1) 1751 a.x = 10 1752 self.assertEqual(a.x, 10) 1753 self.assertEqual(a.x, 11) 1754 del a.x 1755 self.assertNotHasAttr(a, 'x') 1756 1757 def test_newslots(self): 1758 # Testing __new__ slot override... 1759 class C(list): 1760 def __new__(cls): 1761 self = list.__new__(cls) 1762 self.foo = 1 1763 return self 1764 def __init__(self): 1765 self.foo = self.foo + 2 1766 a = C() 1767 self.assertEqual(a.foo, 3) 1768 self.assertEqual(a.__class__, C) 1769 class D(C): 1770 pass 1771 b = D() 1772 self.assertEqual(b.foo, 3) 1773 self.assertEqual(b.__class__, D) 1774 1775 @unittest.expectedFailure 1776 def test_bad_new(self): 1777 self.assertRaises(TypeError, object.__new__) 1778 self.assertRaises(TypeError, object.__new__, '') 1779 self.assertRaises(TypeError, list.__new__, object) 1780 self.assertRaises(TypeError, object.__new__, list) 1781 class C(object): 1782 __new__ = list.__new__ 1783 self.assertRaises(TypeError, C) 1784 class C(list): 1785 __new__ = object.__new__ 1786 self.assertRaises(TypeError, C) 1787 1788 def test_object_new(self): 1789 class A(object): 1790 pass 1791 object.__new__(A) 1792 self.assertRaises(TypeError, object.__new__, A, 5) 1793 object.__init__(A()) 1794 self.assertRaises(TypeError, object.__init__, A(), 5) 1795 1796 class A(object): 1797 def __init__(self, foo): 1798 self.foo = foo 1799 object.__new__(A) 1800 object.__new__(A, 5) 1801 object.__init__(A(3)) 1802 self.assertRaises(TypeError, object.__init__, A(3), 5) 1803 1804 class A(object): 1805 def __new__(cls, foo): 1806 return object.__new__(cls) 1807 object.__new__(A) 1808 self.assertRaises(TypeError, object.__new__, A, 5) 1809 object.__init__(A(3)) 1810 object.__init__(A(3), 5) 1811 1812 class A(object): 1813 def __new__(cls, foo): 1814 return object.__new__(cls) 1815 def __init__(self, foo): 1816 self.foo = foo 1817 object.__new__(A) 1818 self.assertRaises(TypeError, object.__new__, A, 5) 1819 object.__init__(A(3)) 1820 self.assertRaises(TypeError, object.__init__, A(3), 5) 1821 1822 @unittest.expectedFailure 1823 def test_restored_object_new(self): 1824 class A(object): 1825 def __new__(cls, *args, **kwargs): 1826 raise AssertionError 1827 self.assertRaises(AssertionError, A) 1828 class B(A): 1829 __new__ = object.__new__ 1830 def __init__(self, foo): 1831 self.foo = foo 1832 with warnings.catch_warnings(): 1833 warnings.simplefilter('error', DeprecationWarning) 1834 b = B(3) 1835 self.assertEqual(b.foo, 3) 1836 self.assertEqual(b.__class__, B) 1837 del B.__new__ 1838 self.assertRaises(AssertionError, B) 1839 del A.__new__ 1840 with warnings.catch_warnings(): 1841 warnings.simplefilter('error', DeprecationWarning) 1842 b = B(3) 1843 self.assertEqual(b.foo, 3) 1844 self.assertEqual(b.__class__, B) 1845 1846 def test_altmro(self): 1847 # Testing mro() and overriding it... 1848 class A(object): 1849 def f(self): return "A" 1850 class B(A): 1851 pass 1852 class C(A): 1853 def f(self): return "C" 1854 class D(B, C): 1855 pass 1856 self.assertEqual(A.mro(), [A, object]) 1857 self.assertEqual(A.__mro__, (A, object)) 1858 self.assertEqual(B.mro(), [B, A, object]) 1859 self.assertEqual(B.__mro__, (B, A, object)) 1860 self.assertEqual(C.mro(), [C, A, object]) 1861 self.assertEqual(C.__mro__, (C, A, object)) 1862 self.assertEqual(D.mro(), [D, B, C, A, object]) 1863 self.assertEqual(D.__mro__, (D, B, C, A, object)) 1864 self.assertEqual(D().f(), "C") 1865 1866 class PerverseMetaType(type): 1867 def mro(cls): 1868 L = type.mro(cls) 1869 L.reverse() 1870 return L 1871 class X(D,B,C,A, metaclass=PerverseMetaType): 1872 pass 1873 self.assertEqual(X.__mro__, (object, A, C, B, D, X)) 1874 self.assertEqual(X().f(), "A") 1875 1876 try: 1877 class _metaclass(type): 1878 def mro(self): 1879 return [self, dict, object] 1880 class X(object, metaclass=_metaclass): 1881 pass 1882 # In CPython, the class creation above already raises 1883 # TypeError, as a protection against the fact that 1884 # instances of X would segfault it. In other Python 1885 # implementations it would be ok to let the class X 1886 # be created, but instead get a clean TypeError on the 1887 # __setitem__ below. 1888 x = object.__new__(X) 1889 x[5] = 6 1890 except TypeError: 1891 pass 1892 else: 1893 self.fail("devious mro() return not caught") 1894 1895 try: 1896 class _metaclass(type): 1897 def mro(self): 1898 return [1] 1899 class X(object, metaclass=_metaclass): 1900 pass 1901 except TypeError: 1902 pass 1903 else: 1904 self.fail("non-class mro() return not caught") 1905 1906 try: 1907 class _metaclass(type): 1908 def mro(self): 1909 return 1 1910 class X(object, metaclass=_metaclass): 1911 pass 1912 except TypeError: 1913 pass 1914 else: 1915 self.fail("non-sequence mro() return not caught") 1916 1917 def test_overloading(self): 1918 # Testing operator overloading... 1919 1920 class B(object): 1921 "Intermediate class because object doesn't have a __setattr__" 1922 1923 class C(B): 1924 def __getattr__(self, name): 1925 if name == "foo": 1926 return ("getattr", name) 1927 else: 1928 raise AttributeError 1929 def __setattr__(self, name, value): 1930 if name == "foo": 1931 self.setattr = (name, value) 1932 else: 1933 return B.__setattr__(self, name, value) 1934 def __delattr__(self, name): 1935 if name == "foo": 1936 self.delattr = name 1937 else: 1938 return B.__delattr__(self, name) 1939 1940 def __getitem__(self, key): 1941 return ("getitem", key) 1942 def __setitem__(self, key, value): 1943 self.setitem = (key, value) 1944 def __delitem__(self, key): 1945 self.delitem = key 1946 1947 a = C() 1948 self.assertEqual(a.foo, ("getattr", "foo")) 1949 a.foo = 12 1950 self.assertEqual(a.setattr, ("foo", 12)) 1951 del a.foo 1952 self.assertEqual(a.delattr, "foo") 1953 1954 self.assertEqual(a[12], ("getitem", 12)) 1955 a[12] = 21 1956 self.assertEqual(a.setitem, (12, 21)) 1957 del a[12] 1958 self.assertEqual(a.delitem, 12) 1959 1960 self.assertEqual(a[0:10], ("getitem", slice(0, 10))) 1961 a[0:10] = "foo" 1962 self.assertEqual(a.setitem, (slice(0, 10), "foo")) 1963 del a[0:10] 1964 self.assertEqual(a.delitem, (slice(0, 10))) 1965 1966 def test_methods(self): 1967 # Testing methods... 1968 class C(object): 1969 def __init__(self, x): 1970 self.x = x 1971 def foo(self): 1972 return self.x 1973 c1 = C(1) 1974 self.assertEqual(c1.foo(), 1) 1975 class D(C): 1976 boo = C.foo 1977 goo = c1.foo 1978 d2 = D(2) 1979 self.assertEqual(d2.foo(), 2) 1980 self.assertEqual(d2.boo(), 2) 1981 self.assertEqual(d2.goo(), 1) 1982 class E(object): 1983 foo = C.foo 1984 self.assertEqual(E().foo.__func__, C.foo) # i.e., unbound 1985 self.assertTrue(repr(C.foo.__get__(C(1))).startswith("<bound method ")) 1986 1987 @support.impl_detail("testing error message from implementation") 1988 def test_methods_in_c(self): 1989 # This test checks error messages in builtin method descriptor. 1990 # It is allowed that other Python implementations use 1991 # different error messages. 1992 set_add = set.add 1993 1994 expected_errmsg = "unbound method set.add() needs an argument" 1995 1996 with self.assertRaises(TypeError) as cm: 1997 set_add() 1998 self.assertEqual(cm.exception.args[0], expected_errmsg) 1999 2000 expected_errmsg = "descriptor 'add' for 'set' objects doesn't apply to a 'int' object" 2001 2002 with self.assertRaises(TypeError) as cm: 2003 set_add(0) 2004 self.assertEqual(cm.exception.args[0], expected_errmsg) 2005 2006 with self.assertRaises(TypeError) as cm: 2007 set_add.__get__(0) 2008 self.assertEqual(cm.exception.args[0], expected_errmsg) 2009 2010 def test_special_method_lookup(self): 2011 # The lookup of special methods bypasses __getattr__ and 2012 # __getattribute__, but they still can be descriptors. 2013 2014 def run_context(manager): 2015 with manager: 2016 pass 2017 def iden(self): 2018 return self 2019 def hello(self): 2020 return b"hello" 2021 def empty_seq(self): 2022 return [] 2023 def zero(self): 2024 return 0 2025 def complex_num(self): 2026 return 1j 2027 def stop(self): 2028 raise StopIteration 2029 def return_true(self, thing=None): 2030 return True 2031 def do_isinstance(obj): 2032 return isinstance(int, obj) 2033 def do_issubclass(obj): 2034 return issubclass(int, obj) 2035 def do_dict_missing(checker): 2036 class DictSub(checker.__class__, dict): 2037 pass 2038 self.assertEqual(DictSub()["hi"], 4) 2039 def some_number(self_, key): 2040 self.assertEqual(key, "hi") 2041 return 4 2042 def swallow(*args): pass 2043 def format_impl(self, spec): 2044 return "hello" 2045 2046 # It would be nice to have every special method tested here, but I'm 2047 # only listing the ones I can remember outside of typeobject.c, since it 2048 # does it right. 2049 specials = [ 2050 ("__bytes__", bytes, hello, set(), {}), 2051 ("__reversed__", reversed, empty_seq, set(), {}), 2052 ("__length_hint__", list, zero, set(), 2053 {"__iter__" : iden, "__next__" : stop}), 2054 ("__sizeof__", sys.getsizeof, zero, set(), {}), 2055 ("__instancecheck__", do_isinstance, return_true, set(), {}), 2056 ("__missing__", do_dict_missing, some_number, 2057 set(("__class__",)), {}), 2058 ("__subclasscheck__", do_issubclass, return_true, 2059 set(("__bases__",)), {}), 2060 ("__enter__", run_context, iden, set(), {"__exit__" : swallow}), 2061 ("__exit__", run_context, swallow, set(), {"__enter__" : iden}), 2062 ("__complex__", complex, complex_num, set(), {}), 2063 ("__format__", format, format_impl, set(), {}), 2064 ("__floor__", math.floor, zero, set(), {}), 2065 ("__trunc__", math.trunc, zero, set(), {}), 2066 ("__trunc__", int, zero, set(), {}), 2067 ("__ceil__", math.ceil, zero, set(), {}), 2068 ("__dir__", dir, empty_seq, set(), {}), 2069 ("__round__", round, zero, set(), {}), 2070 ] 2071 2072 class Checker(object): 2073 def __getattr__(self, attr, test=self): 2074 test.fail("__getattr__ called with {0}".format(attr)) 2075 def __getattribute__(self, attr, test=self): 2076 if attr not in ok: 2077 test.fail("__getattribute__ called with {0}".format(attr)) 2078 return object.__getattribute__(self, attr) 2079 class SpecialDescr(object): 2080 def __init__(self, impl): 2081 self.impl = impl 2082 def __get__(self, obj, owner): 2083 record.append(1) 2084 return self.impl.__get__(obj, owner) 2085 class MyException(Exception): 2086 pass 2087 class ErrDescr(object): 2088 def __get__(self, obj, owner): 2089 raise MyException 2090 2091 for name, runner, meth_impl, ok, env in specials: 2092 class X(Checker): 2093 pass 2094 for attr, obj in env.items(): 2095 setattr(X, attr, obj) 2096 setattr(X, name, meth_impl) 2097 runner(X()) 2098 2099 record = [] 2100 class X(Checker): 2101 pass 2102 for attr, obj in env.items(): 2103 setattr(X, attr, obj) 2104 setattr(X, name, SpecialDescr(meth_impl)) 2105 runner(X()) 2106 self.assertEqual(record, [1], name) 2107 2108 class X(Checker): 2109 pass 2110 for attr, obj in env.items(): 2111 setattr(X, attr, obj) 2112 setattr(X, name, ErrDescr()) 2113 self.assertRaises(MyException, runner, X()) 2114 2115 def test_specials(self): 2116 # Testing special operators... 2117 # Test operators like __hash__ for which a built-in default exists 2118 2119 # Test the default behavior for static classes 2120 class C(object): 2121 def __getitem__(self, i): 2122 if 0 <= i < 10: return i 2123 raise IndexError 2124 c1 = C() 2125 c2 = C() 2126 self.assertFalse(not c1) 2127 self.assertNotEqual(id(c1), id(c2)) 2128 hash(c1) 2129 hash(c2) 2130 self.assertEqual(c1, c1) 2131 self.assertTrue(c1 != c2) 2132 self.assertFalse(c1 != c1) 2133 self.assertFalse(c1 == c2) 2134 # Note that the module name appears in str/repr, and that varies 2135 # depending on whether this test is run standalone or from a framework. 2136 self.assertGreaterEqual(str(c1).find('C object at '), 0) 2137 self.assertEqual(str(c1), repr(c1)) 2138 self.assertNotIn(-1, c1) 2139 for i in range(10): 2140 self.assertIn(i, c1) 2141 self.assertNotIn(10, c1) 2142 # Test the default behavior for dynamic classes 2143 class D(object): 2144 def __getitem__(self, i): 2145 if 0 <= i < 10: return i 2146 raise IndexError 2147 d1 = D() 2148 d2 = D() 2149 self.assertFalse(not d1) 2150 self.assertNotEqual(id(d1), id(d2)) 2151 hash(d1) 2152 hash(d2) 2153 self.assertEqual(d1, d1) 2154 self.assertNotEqual(d1, d2) 2155 self.assertFalse(d1 != d1) 2156 self.assertFalse(d1 == d2) 2157 # Note that the module name appears in str/repr, and that varies 2158 # depending on whether this test is run standalone or from a framework. 2159 self.assertGreaterEqual(str(d1).find('D object at '), 0) 2160 self.assertEqual(str(d1), repr(d1)) 2161 self.assertNotIn(-1, d1) 2162 for i in range(10): 2163 self.assertIn(i, d1) 2164 self.assertNotIn(10, d1) 2165 # Test overridden behavior 2166 class Proxy(object): 2167 def __init__(self, x): 2168 self.x = x 2169 def __bool__(self): 2170 return not not self.x 2171 def __hash__(self): 2172 return hash(self.x) 2173 def __eq__(self, other): 2174 return self.x == other 2175 def __ne__(self, other): 2176 return self.x != other 2177 def __ge__(self, other): 2178 return self.x >= other 2179 def __gt__(self, other): 2180 return self.x > other 2181 def __le__(self, other): 2182 return self.x <= other 2183 def __lt__(self, other): 2184 return self.x < other 2185 def __str__(self): 2186 return "Proxy:%s" % self.x 2187 def __repr__(self): 2188 return "Proxy(%r)" % self.x 2189 def __contains__(self, value): 2190 return value in self.x 2191 p0 = Proxy(0) 2192 p1 = Proxy(1) 2193 p_1 = Proxy(-1) 2194 self.assertFalse(p0) 2195 self.assertFalse(not p1) 2196 self.assertEqual(hash(p0), hash(0)) 2197 self.assertEqual(p0, p0) 2198 self.assertNotEqual(p0, p1) 2199 self.assertFalse(p0 != p0) 2200 self.assertEqual(not p0, p1) 2201 self.assertTrue(p0 < p1) 2202 self.assertTrue(p0 <= p1) 2203 self.assertTrue(p1 > p0) 2204 self.assertTrue(p1 >= p0) 2205 self.assertEqual(str(p0), "Proxy:0") 2206 self.assertEqual(repr(p0), "Proxy(0)") 2207 p10 = Proxy(range(10)) 2208 self.assertNotIn(-1, p10) 2209 for i in range(10): 2210 self.assertIn(i, p10) 2211 self.assertNotIn(10, p10) 2212 2213 def test_weakrefs(self): 2214 # Testing weak references... 2215 import weakref 2216 class C(object): 2217 pass 2218 c = C() 2219 r = weakref.ref(c) 2220 self.assertEqual(r(), c) 2221 del c 2222 support.gc_collect() 2223 self.assertEqual(r(), None) 2224 del r 2225 class NoWeak(object): 2226 __slots__ = ['foo'] 2227 no = NoWeak() 2228 try: 2229 weakref.ref(no) 2230 except TypeError as msg: 2231 self.assertIn("weak reference", str(msg)) 2232 else: 2233 self.fail("weakref.ref(no) should be illegal") 2234 class Weak(object): 2235 __slots__ = ['foo', '__weakref__'] 2236 yes = Weak() 2237 r = weakref.ref(yes) 2238 self.assertEqual(r(), yes) 2239 del yes 2240 support.gc_collect() 2241 self.assertEqual(r(), None) 2242 del r 2243 2244 def test_properties(self): 2245 # Testing property... 2246 class C(object): 2247 def getx(self): 2248 return self.__x 2249 def setx(self, value): 2250 self.__x = value 2251 def delx(self): 2252 del self.__x 2253 x = property(getx, setx, delx, doc="I'm the x property.") 2254 a = C() 2255 self.assertNotHasAttr(a, "x") 2256 a.x = 42 2257 self.assertEqual(a._C__x, 42) 2258 self.assertEqual(a.x, 42) 2259 del a.x 2260 self.assertNotHasAttr(a, "x") 2261 self.assertNotHasAttr(a, "_C__x") 2262 C.x.__set__(a, 100) 2263 self.assertEqual(C.x.__get__(a), 100) 2264 C.x.__delete__(a) 2265 self.assertNotHasAttr(a, "x") 2266 2267 raw = C.__dict__['x'] 2268 self.assertIsInstance(raw, property) 2269 2270 attrs = dir(raw) 2271 self.assertIn("__doc__", attrs) 2272 self.assertIn("fget", attrs) 2273 self.assertIn("fset", attrs) 2274 self.assertIn("fdel", attrs) 2275 2276 self.assertEqual(raw.__doc__, "I'm the x property.") 2277 self.assertIs(raw.fget, C.__dict__['getx']) 2278 self.assertIs(raw.fset, C.__dict__['setx']) 2279 self.assertIs(raw.fdel, C.__dict__['delx']) 2280 2281 for attr in "fget", "fset", "fdel": 2282 try: 2283 setattr(raw, attr, 42) 2284 except AttributeError as msg: 2285 if str(msg).find('readonly') < 0: 2286 self.fail("when setting readonly attr %r on a property, " 2287 "got unexpected AttributeError msg %r" % (attr, str(msg))) 2288 else: 2289 self.fail("expected AttributeError from trying to set readonly %r " 2290 "attr on a property" % attr) 2291 2292 raw.__doc__ = 42 2293 self.assertEqual(raw.__doc__, 42) 2294 2295 class D(object): 2296 __getitem__ = property(lambda s: 1/0) 2297 2298 d = D() 2299 try: 2300 for i in d: 2301 str(i) 2302 except ZeroDivisionError: 2303 pass 2304 else: 2305 self.fail("expected ZeroDivisionError from bad property") 2306 2307 @unittest.skipIf(sys.flags.optimize >= 2, 2308 "Docstrings are omitted with -O2 and above") 2309 def test_properties_doc_attrib(self): 2310 class E(object): 2311 def getter(self): 2312 "getter method" 2313 return 0 2314 def setter(self_, value): 2315 "setter method" 2316 pass 2317 prop = property(getter) 2318 self.assertEqual(prop.__doc__, "getter method") 2319 prop2 = property(fset=setter) 2320 self.assertEqual(prop2.__doc__, None) 2321 2322 @support.cpython_only 2323 def test_testcapi_no_segfault(self): 2324 # this segfaulted in 2.5b2 2325 try: 2326 import _testcapi 2327 except ImportError: 2328 pass 2329 else: 2330 class X(object): 2331 p = property(_testcapi.test_with_docstring) 2332 2333 def test_properties_plus(self): 2334 class C(object): 2335 foo = property(doc="hello") 2336 @foo.getter 2337 def foo(self): 2338 return self._foo 2339 @foo.setter 2340 def foo(self, value): 2341 self._foo = abs(value) 2342 @foo.deleter 2343 def foo(self): 2344 del self._foo 2345 c = C() 2346 self.assertEqual(C.foo.__doc__, "hello") 2347 self.assertNotHasAttr(c, "foo") 2348 c.foo = -42 2349 self.assertHasAttr(c, '_foo') 2350 self.assertEqual(c._foo, 42) 2351 self.assertEqual(c.foo, 42) 2352 del c.foo 2353 self.assertNotHasAttr(c, '_foo') 2354 self.assertNotHasAttr(c, "foo") 2355 2356 class D(C): 2357 @C.foo.deleter 2358 def foo(self): 2359 try: 2360 del self._foo 2361 except AttributeError: 2362 pass 2363 d = D() 2364 d.foo = 24 2365 self.assertEqual(d.foo, 24) 2366 del d.foo 2367 del d.foo 2368 2369 class E(object): 2370 @property 2371 def foo(self): 2372 return self._foo 2373 @foo.setter 2374 def foo(self, value): 2375 raise RuntimeError 2376 @foo.setter 2377 def foo(self, value): 2378 self._foo = abs(value) 2379 @foo.deleter 2380 def foo(self, value=None): 2381 del self._foo 2382 2383 e = E() 2384 e.foo = -42 2385 self.assertEqual(e.foo, 42) 2386 del e.foo 2387 2388 class F(E): 2389 @E.foo.deleter 2390 def foo(self): 2391 del self._foo 2392 @foo.setter 2393 def foo(self, value): 2394 self._foo = max(0, value) 2395 f = F() 2396 f.foo = -10 2397 self.assertEqual(f.foo, 0) 2398 del f.foo 2399 2400 def test_dict_constructors(self): 2401 # Testing dict constructor ... 2402 d = dict() 2403 self.assertEqual(d, {}) 2404 d = dict({}) 2405 self.assertEqual(d, {}) 2406 d = dict({1: 2, 'a': 'b'}) 2407 self.assertEqual(d, {1: 2, 'a': 'b'}) 2408 self.assertEqual(d, dict(list(d.items()))) 2409 self.assertEqual(d, dict(iter(d.items()))) 2410 d = dict({'one':1, 'two':2}) 2411 self.assertEqual(d, dict(one=1, two=2)) 2412 self.assertEqual(d, dict(**d)) 2413 self.assertEqual(d, dict({"one": 1}, two=2)) 2414 self.assertEqual(d, dict([("two", 2)], one=1)) 2415 self.assertEqual(d, dict([("one", 100), ("two", 200)], **d)) 2416 self.assertEqual(d, dict(**d)) 2417 2418 for badarg in 0, 0, 0j, "0", [0], (0,): 2419 try: 2420 dict(badarg) 2421 except TypeError: 2422 pass 2423 except ValueError: 2424 if badarg == "0": 2425 # It's a sequence, and its elements are also sequences (gotta 2426 # love strings <wink>), but they aren't of length 2, so this 2427 # one seemed better as a ValueError than a TypeError. 2428 pass 2429 else: 2430 self.fail("no TypeError from dict(%r)" % badarg) 2431 else: 2432 self.fail("no TypeError from dict(%r)" % badarg) 2433 2434 try: 2435 dict({}, {}) 2436 except TypeError: 2437 pass 2438 else: 2439 self.fail("no TypeError from dict({}, {})") 2440 2441 class Mapping: 2442 # Lacks a .keys() method; will be added later. 2443 dict = {1:2, 3:4, 'a':1j} 2444 2445 try: 2446 dict(Mapping()) 2447 except TypeError: 2448 pass 2449 else: 2450 self.fail("no TypeError from dict(incomplete mapping)") 2451 2452 Mapping.keys = lambda self: list(self.dict.keys()) 2453 Mapping.__getitem__ = lambda self, i: self.dict[i] 2454 d = dict(Mapping()) 2455 self.assertEqual(d, Mapping.dict) 2456 2457 # Init from sequence of iterable objects, each producing a 2-sequence. 2458 class AddressBookEntry: 2459 def __init__(self, first, last): 2460 self.first = first 2461 self.last = last 2462 def __iter__(self): 2463 return iter([self.first, self.last]) 2464 2465 d = dict([AddressBookEntry('Tim', 'Warsaw'), 2466 AddressBookEntry('Barry', 'Peters'), 2467 AddressBookEntry('Tim', 'Peters'), 2468 AddressBookEntry('Barry', 'Warsaw')]) 2469 self.assertEqual(d, {'Barry': 'Warsaw', 'Tim': 'Peters'}) 2470 2471 d = dict(zip(range(4), range(1, 5))) 2472 self.assertEqual(d, dict([(i, i+1) for i in range(4)])) 2473 2474 # Bad sequence lengths. 2475 for bad in [('tooshort',)], [('too', 'long', 'by 1')]: 2476 try: 2477 dict(bad) 2478 except ValueError: 2479 pass 2480 else: 2481 self.fail("no ValueError from dict(%r)" % bad) 2482 2483 def test_dir(self): 2484 # Testing dir() ... 2485 junk = 12 2486 self.assertEqual(dir(), ['junk', 'self']) 2487 del junk 2488 2489 # Just make sure these don't blow up! 2490 for arg in 2, 2, 2j, 2e0, [2], "2", b"2", (2,), {2:2}, type, self.test_dir: 2491 dir(arg) 2492 2493 # Test dir on new-style classes. Since these have object as a 2494 # base class, a lot more gets sucked in. 2495 def interesting(strings): 2496 return [s for s in strings if not s.startswith('_')] 2497 2498 class C(object): 2499 Cdata = 1 2500 def Cmethod(self): pass 2501 2502 cstuff = ['Cdata', 'Cmethod'] 2503 self.assertEqual(interesting(dir(C)), cstuff) 2504 2505 c = C() 2506 self.assertEqual(interesting(dir(c)), cstuff) 2507 ## self.assertIn('__self__', dir(C.Cmethod)) 2508 2509 c.cdata = 2 2510 c.cmethod = lambda self: 0 2511 self.assertEqual(interesting(dir(c)), cstuff + ['cdata', 'cmethod']) 2512 ## self.assertIn('__self__', dir(c.Cmethod)) 2513 2514 class A(C): 2515 Adata = 1 2516 def Amethod(self): pass 2517 2518 astuff = ['Adata', 'Amethod'] + cstuff 2519 self.assertEqual(interesting(dir(A)), astuff) 2520 ## self.assertIn('__self__', dir(A.Amethod)) 2521 a = A() 2522 self.assertEqual(interesting(dir(a)), astuff) 2523 a.adata = 42 2524 a.amethod = lambda self: 3 2525 self.assertEqual(interesting(dir(a)), astuff + ['adata', 'amethod']) 2526 ## self.assertIn('__self__', dir(a.Amethod)) 2527 2528 # Try a module subclass. 2529 class M(type(sys)): 2530 pass 2531 minstance = M("m") 2532 minstance.b = 2 2533 minstance.a = 1 2534 default_attributes = ['__name__', '__doc__', '__package__', 2535 '__loader__', '__spec__'] 2536 names = [x for x in dir(minstance) if x not in default_attributes] 2537 self.assertEqual(names, ['a', 'b']) 2538 2539 class M2(M): 2540 def getdict(self): 2541 return "Not a dict!" 2542 __dict__ = property(getdict) 2543 2544 m2instance = M2("m2") 2545 m2instance.b = 2 2546 m2instance.a = 1 2547 self.assertEqual(m2instance.__dict__, "Not a dict!") 2548 with self.assertRaises(TypeError): 2549 dir(m2instance) 2550 2551 # Two essentially featureless objects, (Ellipsis just inherits stuff 2552 # from object. 2553 self.assertEqual(dir(object()), dir(Ellipsis)) 2554 2555 # Nasty test case for proxied objects 2556 class Wrapper(object): 2557 def __init__(self, obj): 2558 self.__obj = obj 2559 def __repr__(self): 2560 return "Wrapper(%s)" % repr(self.__obj) 2561 def __getitem__(self, key): 2562 return Wrapper(self.__obj[key]) 2563 def __len__(self): 2564 return len(self.__obj) 2565 def __getattr__(self, name): 2566 return Wrapper(getattr(self.__obj, name)) 2567 2568 class C(object): 2569 def __getclass(self): 2570 return Wrapper(type(self)) 2571 __class__ = property(__getclass) 2572 2573 dir(C()) # This used to segfault 2574 2575 def test_supers(self): 2576 # Testing super... 2577 2578 class A(object): 2579 def meth(self, a): 2580 return "A(%r)" % a 2581 2582 self.assertEqual(A().meth(1), "A(1)") 2583 2584 class B(A): 2585 def __init__(self): 2586 self.__super = super(B, self) 2587 def meth(self, a): 2588 return "B(%r)" % a + self.__super.meth(a) 2589 2590 self.assertEqual(B().meth(2), "B(2)A(2)") 2591 2592 class C(A): 2593 def meth(self, a): 2594 return "C(%r)" % a + self.__super.meth(a) 2595 C._C__super = super(C) 2596 2597 self.assertEqual(C().meth(3), "C(3)A(3)") 2598 2599 class D(C, B): 2600 def meth(self, a): 2601 return "D(%r)" % a + super(D, self).meth(a) 2602 2603 self.assertEqual(D().meth(4), "D(4)C(4)B(4)A(4)") 2604 2605 # Test for subclassing super 2606 2607 class mysuper(super): 2608 def __init__(self, *args): 2609 return super(mysuper, self).__init__(*args) 2610 2611 class E(D): 2612 def meth(self, a): 2613 return "E(%r)" % a + mysuper(E, self).meth(a) 2614 2615 self.assertEqual(E().meth(5), "E(5)D(5)C(5)B(5)A(5)") 2616 2617 class F(E): 2618 def meth(self, a): 2619 s = self.__super # == mysuper(F, self) 2620 return "F(%r)[%s]" % (a, s.__class__.__name__) + s.meth(a) 2621 F._F__super = mysuper(F) 2622 2623 self.assertEqual(F().meth(6), "F(6)[mysuper]E(6)D(6)C(6)B(6)A(6)") 2624 2625 # Make sure certain errors are raised 2626 2627 try: 2628 super(D, 42) 2629 except TypeError: 2630 pass 2631 else: 2632 self.fail("shouldn't allow super(D, 42)") 2633 2634 try: 2635 super(D, C()) 2636 except TypeError: 2637 pass 2638 else: 2639 self.fail("shouldn't allow super(D, C())") 2640 2641 try: 2642 super(D).__get__(12) 2643 except TypeError: 2644 pass 2645 else: 2646 self.fail("shouldn't allow super(D).__get__(12)") 2647 2648 try: 2649 super(D).__get__(C()) 2650 except TypeError: 2651 pass 2652 else: 2653 self.fail("shouldn't allow super(D).__get__(C())") 2654 2655 # Make sure data descriptors can be overridden and accessed via super 2656 # (new feature in Python 2.3) 2657 2658 class DDbase(object): 2659 def getx(self): return 42 2660 x = property(getx) 2661 2662 class DDsub(DDbase): 2663 def getx(self): return "hello" 2664 x = property(getx) 2665 2666 dd = DDsub() 2667 self.assertEqual(dd.x, "hello") 2668 self.assertEqual(super(DDsub, dd).x, 42) 2669 2670 # Ensure that super() lookup of descriptor from classmethod 2671 # works (SF ID# 743627) 2672 2673 class Base(object): 2674 aProp = property(lambda self: "foo") 2675 2676 class Sub(Base): 2677 @classmethod 2678 def test(klass): 2679 return super(Sub,klass).aProp 2680 2681 self.assertEqual(Sub.test(), Base.aProp) 2682 2683 # Verify that super() doesn't allow keyword args 2684 with self.assertRaises(TypeError): 2685 super(Base, kw=1) 2686 2687 def test_basic_inheritance(self): 2688 # Testing inheritance from basic types... 2689 2690 class hexint(int): 2691 def __repr__(self): 2692 return hex(self) 2693 def __add__(self, other): 2694 return hexint(int.__add__(self, other)) 2695 # (Note that overriding __radd__ doesn't work, 2696 # because the int type gets first dibs.) 2697 self.assertEqual(repr(hexint(7) + 9), "0x10") 2698 self.assertEqual(repr(hexint(1000) + 7), "0x3ef") 2699 a = hexint(12345) 2700 self.assertEqual(a, 12345) 2701 self.assertEqual(int(a), 12345) 2702 self.assertIs(int(a).__class__, int) 2703 self.assertEqual(hash(a), hash(12345)) 2704 self.assertIs((+a).__class__, int) 2705 self.assertIs((a >> 0).__class__, int) 2706 self.assertIs((a << 0).__class__, int) 2707 self.assertIs((hexint(0) << 12).__class__, int) 2708 self.assertIs((hexint(0) >> 12).__class__, int) 2709 2710 class octlong(int): 2711 __slots__ = [] 2712 def __str__(self): 2713 return oct(self) 2714 def __add__(self, other): 2715 return self.__class__(super(octlong, self).__add__(other)) 2716 __radd__ = __add__ 2717 self.assertEqual(str(octlong(3) + 5), "0o10") 2718 # (Note that overriding __radd__ here only seems to work 2719 # because the example uses a short int left argument.) 2720 self.assertEqual(str(5 + octlong(3000)), "0o5675") 2721 a = octlong(12345) 2722 self.assertEqual(a, 12345) 2723 self.assertEqual(int(a), 12345) 2724 self.assertEqual(hash(a), hash(12345)) 2725 self.assertIs(int(a).__class__, int) 2726 self.assertIs((+a).__class__, int) 2727 self.assertIs((-a).__class__, int) 2728 self.assertIs((-octlong(0)).__class__, int) 2729 self.assertIs((a >> 0).__class__, int) 2730 self.assertIs((a << 0).__class__, int) 2731 self.assertIs((a - 0).__class__, int) 2732 self.assertIs((a * 1).__class__, int) 2733 self.assertIs((a ** 1).__class__, int) 2734 self.assertIs((a // 1).__class__, int) 2735 self.assertIs((1 * a).__class__, int) 2736 self.assertIs((a | 0).__class__, int) 2737 self.assertIs((a ^ 0).__class__, int) 2738 self.assertIs((a & -1).__class__, int) 2739 self.assertIs((octlong(0) << 12).__class__, int) 2740 self.assertIs((octlong(0) >> 12).__class__, int) 2741 self.assertIs(abs(octlong(0)).__class__, int) 2742 2743 # Because octlong overrides __add__, we can't check the absence of +0 2744 # optimizations using octlong. 2745 class longclone(int): 2746 pass 2747 a = longclone(1) 2748 self.assertIs((a + 0).__class__, int) 2749 self.assertIs((0 + a).__class__, int) 2750 2751 # Check that negative clones don't segfault 2752 a = longclone(-1) 2753 self.assertEqual(a.__dict__, {}) 2754 self.assertEqual(int(a), -1) # self.assertTrue PyNumber_Long() copies the sign bit 2755 2756 class precfloat(float): 2757 __slots__ = ['prec'] 2758 def __init__(self, value=0.0, prec=12): 2759 self.prec = int(prec) 2760 def __repr__(self): 2761 return "%.*g" % (self.prec, self) 2762 self.assertEqual(repr(precfloat(1.1)), "1.1") 2763 a = precfloat(12345) 2764 self.assertEqual(a, 12345.0) 2765 self.assertEqual(float(a), 12345.0) 2766 self.assertIs(float(a).__class__, float) 2767 self.assertEqual(hash(a), hash(12345.0)) 2768 self.assertIs((+a).__class__, float) 2769 2770 class madcomplex(complex): 2771 def __repr__(self): 2772 return "%.17gj%+.17g" % (self.imag, self.real) 2773 a = madcomplex(-3, 4) 2774 self.assertEqual(repr(a), "4j-3") 2775 base = complex(-3, 4) 2776 self.assertEqual(base.__class__, complex) 2777 self.assertEqual(a, base) 2778 self.assertEqual(complex(a), base) 2779 self.assertEqual(complex(a).__class__, complex) 2780 a = madcomplex(a) # just trying another form of the constructor 2781 self.assertEqual(repr(a), "4j-3") 2782 self.assertEqual(a, base) 2783 self.assertEqual(complex(a), base) 2784 self.assertEqual(complex(a).__class__, complex) 2785 self.assertEqual(hash(a), hash(base)) 2786 self.assertEqual((+a).__class__, complex) 2787 self.assertEqual((a + 0).__class__, complex) 2788 self.assertEqual(a + 0, base) 2789 self.assertEqual((a - 0).__class__, complex) 2790 self.assertEqual(a - 0, base) 2791 self.assertEqual((a * 1).__class__, complex) 2792 self.assertEqual(a * 1, base) 2793 self.assertEqual((a / 1).__class__, complex) 2794 self.assertEqual(a / 1, base) 2795 2796 class madtuple(tuple): 2797 _rev = None 2798 def rev(self): 2799 if self._rev is not None: 2800 return self._rev 2801 L = list(self) 2802 L.reverse() 2803 self._rev = self.__class__(L) 2804 return self._rev 2805 a = madtuple((1,2,3,4,5,6,7,8,9,0)) 2806 self.assertEqual(a, (1,2,3,4,5,6,7,8,9,0)) 2807 self.assertEqual(a.rev(), madtuple((0,9,8,7,6,5,4,3,2,1))) 2808 self.assertEqual(a.rev().rev(), madtuple((1,2,3,4,5,6,7,8,9,0))) 2809 for i in range(512): 2810 t = madtuple(range(i)) 2811 u = t.rev() 2812 v = u.rev() 2813 self.assertEqual(v, t) 2814 a = madtuple((1,2,3,4,5)) 2815 self.assertEqual(tuple(a), (1,2,3,4,5)) 2816 self.assertIs(tuple(a).__class__, tuple) 2817 self.assertEqual(hash(a), hash((1,2,3,4,5))) 2818 self.assertIs(a[:].__class__, tuple) 2819 self.assertIs((a * 1).__class__, tuple) 2820 self.assertIs((a * 0).__class__, tuple) 2821 self.assertIs((a + ()).__class__, tuple) 2822 a = madtuple(()) 2823 self.assertEqual(tuple(a), ()) 2824 self.assertIs(tuple(a).__class__, tuple) 2825 self.assertIs((a + a).__class__, tuple) 2826 self.assertIs((a * 0).__class__, tuple) 2827 self.assertIs((a * 1).__class__, tuple) 2828 self.assertIs((a * 2).__class__, tuple) 2829 self.assertIs(a[:].__class__, tuple) 2830 2831 class madstring(str): 2832 _rev = None 2833 def rev(self): 2834 if self._rev is not None: 2835 return self._rev 2836 L = list(self) 2837 L.reverse() 2838 self._rev = self.__class__("".join(L)) 2839 return self._rev 2840 s = madstring("abcdefghijklmnopqrstuvwxyz") 2841 self.assertEqual(s, "abcdefghijklmnopqrstuvwxyz") 2842 self.assertEqual(s.rev(), madstring("zyxwvutsrqponmlkjihgfedcba")) 2843 self.assertEqual(s.rev().rev(), madstring("abcdefghijklmnopqrstuvwxyz")) 2844 for i in range(256): 2845 s = madstring("".join(map(chr, range(i)))) 2846 t = s.rev() 2847 u = t.rev() 2848 self.assertEqual(u, s) 2849 s = madstring("12345") 2850 self.assertEqual(str(s), "12345") 2851 self.assertIs(str(s).__class__, str) 2852 2853 base = "\x00" * 5 2854 s = madstring(base) 2855 self.assertEqual(s, base) 2856 self.assertEqual(str(s), base) 2857 self.assertIs(str(s).__class__, str) 2858 self.assertEqual(hash(s), hash(base)) 2859 self.assertEqual({s: 1}[base], 1) 2860 self.assertEqual({base: 1}[s], 1) 2861 self.assertIs((s + "").__class__, str) 2862 self.assertEqual(s + "", base) 2863 self.assertIs(("" + s).__class__, str) 2864 self.assertEqual("" + s, base) 2865 self.assertIs((s * 0).__class__, str) 2866 self.assertEqual(s * 0, "") 2867 self.assertIs((s * 1).__class__, str) 2868 self.assertEqual(s * 1, base) 2869 self.assertIs((s * 2).__class__, str) 2870 self.assertEqual(s * 2, base + base) 2871 self.assertIs(s[:].__class__, str) 2872 self.assertEqual(s[:], base) 2873 self.assertIs(s[0:0].__class__, str) 2874 self.assertEqual(s[0:0], "") 2875 self.assertIs(s.strip().__class__, str) 2876 self.assertEqual(s.strip(), base) 2877 self.assertIs(s.lstrip().__class__, str) 2878 self.assertEqual(s.lstrip(), base) 2879 self.assertIs(s.rstrip().__class__, str) 2880 self.assertEqual(s.rstrip(), base) 2881 identitytab = {} 2882 self.assertIs(s.translate(identitytab).__class__, str) 2883 self.assertEqual(s.translate(identitytab), base) 2884 self.assertIs(s.replace("x", "x").__class__, str) 2885 self.assertEqual(s.replace("x", "x"), base) 2886 self.assertIs(s.ljust(len(s)).__class__, str) 2887 self.assertEqual(s.ljust(len(s)), base) 2888 self.assertIs(s.rjust(len(s)).__class__, str) 2889 self.assertEqual(s.rjust(len(s)), base) 2890 self.assertIs(s.center(len(s)).__class__, str) 2891 self.assertEqual(s.center(len(s)), base) 2892 self.assertIs(s.lower().__class__, str) 2893 self.assertEqual(s.lower(), base) 2894 2895 class madunicode(str): 2896 _rev = None 2897 def rev(self): 2898 if self._rev is not None: 2899 return self._rev 2900 L = list(self) 2901 L.reverse() 2902 self._rev = self.__class__("".join(L)) 2903 return self._rev 2904 u = madunicode("ABCDEF") 2905 self.assertEqual(u, "ABCDEF") 2906 self.assertEqual(u.rev(), madunicode("FEDCBA")) 2907 self.assertEqual(u.rev().rev(), madunicode("ABCDEF")) 2908 base = "12345" 2909 u = madunicode(base) 2910 self.assertEqual(str(u), base) 2911 self.assertIs(str(u).__class__, str) 2912 self.assertEqual(hash(u), hash(base)) 2913 self.assertEqual({u: 1}[base], 1) 2914 self.assertEqual({base: 1}[u], 1) 2915 self.assertIs(u.strip().__class__, str) 2916 self.assertEqual(u.strip(), base) 2917 self.assertIs(u.lstrip().__class__, str) 2918 self.assertEqual(u.lstrip(), base) 2919 self.assertIs(u.rstrip().__class__, str) 2920 self.assertEqual(u.rstrip(), base) 2921 self.assertIs(u.replace("x", "x").__class__, str) 2922 self.assertEqual(u.replace("x", "x"), base) 2923 self.assertIs(u.replace("xy", "xy").__class__, str) 2924 self.assertEqual(u.replace("xy", "xy"), base) 2925 self.assertIs(u.center(len(u)).__class__, str) 2926 self.assertEqual(u.center(len(u)), base) 2927 self.assertIs(u.ljust(len(u)).__class__, str) 2928 self.assertEqual(u.ljust(len(u)), base) 2929 self.assertIs(u.rjust(len(u)).__class__, str) 2930 self.assertEqual(u.rjust(len(u)), base) 2931 self.assertIs(u.lower().__class__, str) 2932 self.assertEqual(u.lower(), base) 2933 self.assertIs(u.upper().__class__, str) 2934 self.assertEqual(u.upper(), base) 2935 self.assertIs(u.capitalize().__class__, str) 2936 self.assertEqual(u.capitalize(), base) 2937 self.assertIs(u.title().__class__, str) 2938 self.assertEqual(u.title(), base) 2939 self.assertIs((u + "").__class__, str) 2940 self.assertEqual(u + "", base) 2941 self.assertIs(("" + u).__class__, str) 2942 self.assertEqual("" + u, base) 2943 self.assertIs((u * 0).__class__, str) 2944 self.assertEqual(u * 0, "") 2945 self.assertIs((u * 1).__class__, str) 2946 self.assertEqual(u * 1, base) 2947 self.assertIs((u * 2).__class__, str) 2948 self.assertEqual(u * 2, base + base) 2949 self.assertIs(u[:].__class__, str) 2950 self.assertEqual(u[:], base) 2951 self.assertIs(u[0:0].__class__, str) 2952 self.assertEqual(u[0:0], "") 2953 2954 class sublist(list): 2955 pass 2956 a = sublist(range(5)) 2957 self.assertEqual(a, list(range(5))) 2958 a.append("hello") 2959 self.assertEqual(a, list(range(5)) + ["hello"]) 2960 a[5] = 5 2961 self.assertEqual(a, list(range(6))) 2962 a.extend(range(6, 20)) 2963 self.assertEqual(a, list(range(20))) 2964 a[-5:] = [] 2965 self.assertEqual(a, list(range(15))) 2966 del a[10:15] 2967 self.assertEqual(len(a), 10) 2968 self.assertEqual(a, list(range(10))) 2969 self.assertEqual(list(a), list(range(10))) 2970 self.assertEqual(a[0], 0) 2971 self.assertEqual(a[9], 9) 2972 self.assertEqual(a[-10], 0) 2973 self.assertEqual(a[-1], 9) 2974 self.assertEqual(a[:5], list(range(5))) 2975 2976 ## class CountedInput(file): 2977 ## """Counts lines read by self.readline(). 2978 ## 2979 ## self.lineno is the 0-based ordinal of the last line read, up to 2980 ## a maximum of one greater than the number of lines in the file. 2981 ## 2982 ## self.ateof is true if and only if the final "" line has been read, 2983 ## at which point self.lineno stops incrementing, and further calls 2984 ## to readline() continue to return "". 2985 ## """ 2986 ## 2987 ## lineno = 0 2988 ## ateof = 0 2989 ## def readline(self): 2990 ## if self.ateof: 2991 ## return "" 2992 ## s = file.readline(self) 2993 ## # Next line works too. 2994 ## # s = super(CountedInput, self).readline() 2995 ## self.lineno += 1 2996 ## if s == "": 2997 ## self.ateof = 1 2998 ## return s 2999 ## 3000 ## f = file(name=os_helper.TESTFN, mode='w') 3001 ## lines = ['a\n', 'b\n', 'c\n'] 3002 ## try: 3003 ## f.writelines(lines) 3004 ## f.close() 3005 ## f = CountedInput(os_helper.TESTFN) 3006 ## for (i, expected) in zip(range(1, 5) + [4], lines + 2 * [""]): 3007 ## got = f.readline() 3008 ## self.assertEqual(expected, got) 3009 ## self.assertEqual(f.lineno, i) 3010 ## self.assertEqual(f.ateof, (i > len(lines))) 3011 ## f.close() 3012 ## finally: 3013 ## try: 3014 ## f.close() 3015 ## except: 3016 ## pass 3017 ## os_helper.unlink(os_helper.TESTFN) 3018 3019 def test_keywords(self): 3020 # Testing keyword args to basic type constructors ... 3021 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3022 int(x=1) 3023 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3024 float(x=2) 3025 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3026 bool(x=2) 3027 self.assertEqual(complex(imag=42, real=666), complex(666, 42)) 3028 self.assertEqual(str(object=500), '500') 3029 self.assertEqual(str(object=b'abc', errors='strict'), 'abc') 3030 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3031 tuple(sequence=range(3)) 3032 with self.assertRaisesRegex(TypeError, 'keyword argument'): 3033 list(sequence=(0, 1, 2)) 3034 # note: as of Python 2.3, dict() no longer has an "items" keyword arg 3035 3036 for constructor in (int, float, int, complex, str, str, 3037 tuple, list): 3038 try: 3039 constructor(bogus_keyword_arg=1) 3040 except TypeError: 3041 pass 3042 else: 3043 self.fail("expected TypeError from bogus keyword argument to %r" 3044 % constructor) 3045 3046 def test_str_subclass_as_dict_key(self): 3047 # Testing a str subclass used as dict key .. 3048 3049 class cistr(str): 3050 """Subclass of str that computes __eq__ case-insensitively. 3051 3052 Also computes a hash code of the string in canonical form. 3053 """ 3054 3055 def __init__(self, value): 3056 self.canonical = value.lower() 3057 self.hashcode = hash(self.canonical) 3058 3059 def __eq__(self, other): 3060 if not isinstance(other, cistr): 3061 other = cistr(other) 3062 return self.canonical == other.canonical 3063 3064 def __hash__(self): 3065 return self.hashcode 3066 3067 self.assertEqual(cistr('ABC'), 'abc') 3068 self.assertEqual('aBc', cistr('ABC')) 3069 self.assertEqual(str(cistr('ABC')), 'ABC') 3070 3071 d = {cistr('one'): 1, cistr('two'): 2, cistr('tHree'): 3} 3072 self.assertEqual(d[cistr('one')], 1) 3073 self.assertEqual(d[cistr('tWo')], 2) 3074 self.assertEqual(d[cistr('THrEE')], 3) 3075 self.assertIn(cistr('ONe'), d) 3076 self.assertEqual(d.get(cistr('thrEE')), 3) 3077 3078 def test_classic_comparisons(self): 3079 # Testing classic comparisons... 3080 class classic: 3081 pass 3082 3083 for base in (classic, int, object): 3084 class C(base): 3085 def __init__(self, value): 3086 self.value = int(value) 3087 def __eq__(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 __ne__(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 __lt__(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 __le__(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 def __gt__(self, other): 3112 if isinstance(other, C): 3113 return self.value > other.value 3114 if isinstance(other, int) or isinstance(other, int): 3115 return self.value > other 3116 return NotImplemented 3117 def __ge__(self, other): 3118 if isinstance(other, C): 3119 return self.value >= other.value 3120 if isinstance(other, int) or isinstance(other, int): 3121 return self.value >= other 3122 return NotImplemented 3123 3124 c1 = C(1) 3125 c2 = C(2) 3126 c3 = C(3) 3127 self.assertEqual(c1, 1) 3128 c = {1: c1, 2: c2, 3: c3} 3129 for x in 1, 2, 3: 3130 for y in 1, 2, 3: 3131 for op in "<", "<=", "==", "!=", ">", ">=": 3132 self.assertEqual(eval("c[x] %s c[y]" % op), 3133 eval("x %s y" % op), 3134 "x=%d, y=%d" % (x, y)) 3135 self.assertEqual(eval("c[x] %s y" % op), 3136 eval("x %s y" % op), 3137 "x=%d, y=%d" % (x, y)) 3138 self.assertEqual(eval("x %s c[y]" % op), 3139 eval("x %s y" % op), 3140 "x=%d, y=%d" % (x, y)) 3141 3142 def test_rich_comparisons(self): 3143 # Testing rich comparisons... 3144 class Z(complex): 3145 pass 3146 z = Z(1) 3147 self.assertEqual(z, 1+0j) 3148 self.assertEqual(1+0j, z) 3149 class ZZ(complex): 3150 def __eq__(self, other): 3151 try: 3152 return abs(self - other) <= 1e-6 3153 except: 3154 return NotImplemented 3155 zz = ZZ(1.0000003) 3156 self.assertEqual(zz, 1+0j) 3157 self.assertEqual(1+0j, zz) 3158 3159 class classic: 3160 pass 3161 for base in (classic, int, object, list): 3162 class C(base): 3163 def __init__(self, value): 3164 self.value = int(value) 3165 def __cmp__(self_, other): 3166 self.fail("shouldn't call __cmp__") 3167 def __eq__(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 __ne__(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 __lt__(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 __le__(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 def __gt__(self, other): 3192 if isinstance(other, C): 3193 return self.value > other.value 3194 if isinstance(other, int) or isinstance(other, int): 3195 return self.value > other 3196 return NotImplemented 3197 def __ge__(self, other): 3198 if isinstance(other, C): 3199 return self.value >= other.value 3200 if isinstance(other, int) or isinstance(other, int): 3201 return self.value >= other 3202 return NotImplemented 3203 c1 = C(1) 3204 c2 = C(2) 3205 c3 = C(3) 3206 self.assertEqual(c1, 1) 3207 c = {1: c1, 2: c2, 3: c3} 3208 for x in 1, 2, 3: 3209 for y in 1, 2, 3: 3210 for op in "<", "<=", "==", "!=", ">", ">=": 3211 self.assertEqual(eval("c[x] %s c[y]" % op), 3212 eval("x %s y" % op), 3213 "x=%d, y=%d" % (x, y)) 3214 self.assertEqual(eval("c[x] %s y" % op), 3215 eval("x %s y" % op), 3216 "x=%d, y=%d" % (x, y)) 3217 self.assertEqual(eval("x %s c[y]" % op), 3218 eval("x %s y" % op), 3219 "x=%d, y=%d" % (x, y)) 3220 3221 def test_descrdoc(self): 3222 # Testing descriptor doc strings... 3223 from _io import FileIO 3224 def check(descr, what): 3225 self.assertEqual(descr.__doc__, what) 3226 check(FileIO.closed, "True if the file is closed") # getset descriptor 3227 check(complex.real, "the real part of a complex number") # member descriptor 3228 3229 def test_doc_descriptor(self): 3230 # Testing __doc__ descriptor... 3231 # SF bug 542984 3232 class DocDescr(object): 3233 def __get__(self, object, otype): 3234 if object: 3235 object = object.__class__.__name__ + ' instance' 3236 if otype: 3237 otype = otype.__name__ 3238 return 'object=%s; type=%s' % (object, otype) 3239 class OldClass: 3240 __doc__ = DocDescr() 3241 class NewClass(object): 3242 __doc__ = DocDescr() 3243 self.assertEqual(OldClass.__doc__, 'object=None; type=OldClass') 3244 self.assertEqual(OldClass().__doc__, 'object=OldClass instance; type=OldClass') 3245 self.assertEqual(NewClass.__doc__, 'object=None; type=NewClass') 3246 self.assertEqual(NewClass().__doc__, 'object=NewClass instance; type=NewClass') 3247 3248 def test_set_class(self): 3249 # Testing __class__ assignment... 3250 class C(object): pass 3251 class D(object): pass 3252 class E(object): pass 3253 class F(D, E): pass 3254 for cls in C, D, E, F: 3255 for cls2 in C, D, E, F: 3256 x = cls() 3257 x.__class__ = cls2 3258 self.assertIs(x.__class__, cls2) 3259 x.__class__ = cls 3260 self.assertIs(x.__class__, cls) 3261 def cant(x, C): 3262 try: 3263 x.__class__ = C 3264 except TypeError: 3265 pass 3266 else: 3267 self.fail("shouldn't allow %r.__class__ = %r" % (x, C)) 3268 try: 3269 delattr(x, "__class__") 3270 except (TypeError, AttributeError): 3271 pass 3272 else: 3273 self.fail("shouldn't allow del %r.__class__" % x) 3274 cant(C(), list) 3275 cant(list(), C) 3276 cant(C(), 1) 3277 cant(C(), object) 3278 cant(object(), list) 3279 cant(list(), object) 3280 class Int(int): __slots__ = [] 3281 cant(True, int) 3282 cant(2, bool) 3283 o = object() 3284 cant(o, type(1)) 3285 cant(o, type(None)) 3286 del o 3287 class G(object): 3288 __slots__ = ["a", "b"] 3289 class H(object): 3290 __slots__ = ["b", "a"] 3291 class I(object): 3292 __slots__ = ["a", "b"] 3293 class J(object): 3294 __slots__ = ["c", "b"] 3295 class K(object): 3296 __slots__ = ["a", "b", "d"] 3297 class L(H): 3298 __slots__ = ["e"] 3299 class M(I): 3300 __slots__ = ["e"] 3301 class N(J): 3302 __slots__ = ["__weakref__"] 3303 class P(J): 3304 __slots__ = ["__dict__"] 3305 class Q(J): 3306 pass 3307 class R(J): 3308 __slots__ = ["__dict__", "__weakref__"] 3309 3310 for cls, cls2 in ((G, H), (G, I), (I, H), (Q, R), (R, Q)): 3311 x = cls() 3312 x.a = 1 3313 x.__class__ = cls2 3314 self.assertIs(x.__class__, cls2, 3315 "assigning %r as __class__ for %r silently failed" % (cls2, x)) 3316 self.assertEqual(x.a, 1) 3317 x.__class__ = cls 3318 self.assertIs(x.__class__, cls, 3319 "assigning %r as __class__ for %r silently failed" % (cls, x)) 3320 self.assertEqual(x.a, 1) 3321 for cls in G, J, K, L, M, N, P, R, list, Int: 3322 for cls2 in G, J, K, L, M, N, P, R, list, Int: 3323 if cls is cls2: 3324 continue 3325 cant(cls(), cls2) 3326 3327 # Issue5283: when __class__ changes in __del__, the wrong 3328 # type gets DECREF'd. 3329 class O(object): 3330 pass 3331 class A(object): 3332 def __del__(self): 3333 self.__class__ = O 3334 l = [A() for x in range(100)] 3335 del l 3336 3337 def test_set_dict(self): 3338 # Testing __dict__ assignment... 3339 class C(object): pass 3340 a = C() 3341 a.__dict__ = {'b': 1} 3342 self.assertEqual(a.b, 1) 3343 def cant(x, dict): 3344 try: 3345 x.__dict__ = dict 3346 except (AttributeError, TypeError): 3347 pass 3348 else: 3349 self.fail("shouldn't allow %r.__dict__ = %r" % (x, dict)) 3350 cant(a, None) 3351 cant(a, []) 3352 cant(a, 1) 3353 del a.__dict__ # Deleting __dict__ is allowed 3354 3355 class Base(object): 3356 pass 3357 def verify_dict_readonly(x): 3358 """ 3359 x has to be an instance of a class inheriting from Base. 3360 """ 3361 cant(x, {}) 3362 try: 3363 del x.__dict__ 3364 except (AttributeError, TypeError): 3365 pass 3366 else: 3367 self.fail("shouldn't allow del %r.__dict__" % x) 3368 dict_descr = Base.__dict__["__dict__"] 3369 try: 3370 dict_descr.__set__(x, {}) 3371 except (AttributeError, TypeError): 3372 pass 3373 else: 3374 self.fail("dict_descr allowed access to %r's dict" % x) 3375 3376 # Classes don't allow __dict__ assignment and have readonly dicts 3377 class Meta1(type, Base): 3378 pass 3379 class Meta2(Base, type): 3380 pass 3381 class D(object, metaclass=Meta1): 3382 pass 3383 class E(object, metaclass=Meta2): 3384 pass 3385 for cls in C, D, E: 3386 verify_dict_readonly(cls) 3387 class_dict = cls.__dict__ 3388 try: 3389 class_dict["spam"] = "eggs" 3390 except TypeError: 3391 pass 3392 else: 3393 self.fail("%r's __dict__ can be modified" % cls) 3394 3395 # Modules also disallow __dict__ assignment 3396 class Module1(types.ModuleType, Base): 3397 pass 3398 class Module2(Base, types.ModuleType): 3399 pass 3400 for ModuleType in Module1, Module2: 3401 mod = ModuleType("spam") 3402 verify_dict_readonly(mod) 3403 mod.__dict__["spam"] = "eggs" 3404 3405 # Exception's __dict__ can be replaced, but not deleted 3406 # (at least not any more than regular exception's __dict__ can 3407 # be deleted; on CPython it is not the case, whereas on PyPy they 3408 # can, just like any other new-style instance's __dict__.) 3409 def can_delete_dict(e): 3410 try: 3411 del e.__dict__ 3412 except (TypeError, AttributeError): 3413 return False 3414 else: 3415 return True 3416 class Exception1(Exception, Base): 3417 pass 3418 class Exception2(Base, Exception): 3419 pass 3420 for ExceptionType in Exception, Exception1, Exception2: 3421 e = ExceptionType() 3422 e.__dict__ = {"a": 1} 3423 self.assertEqual(e.a, 1) 3424 self.assertEqual(can_delete_dict(e), can_delete_dict(ValueError())) 3425 3426 def test_binary_operator_override(self): 3427 # Testing overrides of binary operations... 3428 class I(int): 3429 def __repr__(self): 3430 return "I(%r)" % int(self) 3431 def __add__(self, other): 3432 return I(int(self) + int(other)) 3433 __radd__ = __add__ 3434 def __pow__(self, other, mod=None): 3435 if mod is None: 3436 return I(pow(int(self), int(other))) 3437 else: 3438 return I(pow(int(self), int(other), int(mod))) 3439 def __rpow__(self, other, mod=None): 3440 if mod is None: 3441 return I(pow(int(other), int(self), mod)) 3442 else: 3443 return I(pow(int(other), int(self), int(mod))) 3444 3445 self.assertEqual(repr(I(1) + I(2)), "I(3)") 3446 self.assertEqual(repr(I(1) + 2), "I(3)") 3447 self.assertEqual(repr(1 + I(2)), "I(3)") 3448 self.assertEqual(repr(I(2) ** I(3)), "I(8)") 3449 self.assertEqual(repr(2 ** I(3)), "I(8)") 3450 self.assertEqual(repr(I(2) ** 3), "I(8)") 3451 self.assertEqual(repr(pow(I(2), I(3), I(5))), "I(3)") 3452 class S(str): 3453 def __eq__(self, other): 3454 return self.lower() == other.lower() 3455 3456 def test_subclass_propagation(self): 3457 # Testing propagation of slot functions to subclasses... 3458 class A(object): 3459 pass 3460 class B(A): 3461 pass 3462 class C(A): 3463 pass 3464 class D(B, C): 3465 pass 3466 d = D() 3467 orig_hash = hash(d) # related to id(d) in platform-dependent ways 3468 A.__hash__ = lambda self: 42 3469 self.assertEqual(hash(d), 42) 3470 C.__hash__ = lambda self: 314 3471 self.assertEqual(hash(d), 314) 3472 B.__hash__ = lambda self: 144 3473 self.assertEqual(hash(d), 144) 3474 D.__hash__ = lambda self: 100 3475 self.assertEqual(hash(d), 100) 3476 D.__hash__ = None 3477 self.assertRaises(TypeError, hash, d) 3478 del D.__hash__ 3479 self.assertEqual(hash(d), 144) 3480 B.__hash__ = None 3481 self.assertRaises(TypeError, hash, d) 3482 del B.__hash__ 3483 self.assertEqual(hash(d), 314) 3484 C.__hash__ = None 3485 self.assertRaises(TypeError, hash, d) 3486 del C.__hash__ 3487 self.assertEqual(hash(d), 42) 3488 A.__hash__ = None 3489 self.assertRaises(TypeError, hash, d) 3490 del A.__hash__ 3491 self.assertEqual(hash(d), orig_hash) 3492 d.foo = 42 3493 d.bar = 42 3494 self.assertEqual(d.foo, 42) 3495 self.assertEqual(d.bar, 42) 3496 def __getattribute__(self, name): 3497 if name == "foo": 3498 return 24 3499 return object.__getattribute__(self, name) 3500 A.__getattribute__ = __getattribute__ 3501 self.assertEqual(d.foo, 24) 3502 self.assertEqual(d.bar, 42) 3503 def __getattr__(self, name): 3504 if name in ("spam", "foo", "bar"): 3505 return "hello" 3506 raise AttributeError(name) 3507 B.__getattr__ = __getattr__ 3508 self.assertEqual(d.spam, "hello") 3509 self.assertEqual(d.foo, 24) 3510 self.assertEqual(d.bar, 42) 3511 del A.__getattribute__ 3512 self.assertEqual(d.foo, 42) 3513 del d.foo 3514 self.assertEqual(d.foo, "hello") 3515 self.assertEqual(d.bar, 42) 3516 del B.__getattr__ 3517 try: 3518 d.foo 3519 except AttributeError: 3520 pass 3521 else: 3522 self.fail("d.foo should be undefined now") 3523 3524 # Test a nasty bug in recurse_down_subclasses() 3525 class A(object): 3526 pass 3527 class B(A): 3528 pass 3529 del B 3530 support.gc_collect() 3531 A.__setitem__ = lambda *a: None # crash 3532 3533 def test_buffer_inheritance(self): 3534 # Testing that buffer interface is inherited ... 3535 3536 import binascii 3537 # SF bug [#470040] ParseTuple t# vs subclasses. 3538 3539 class MyBytes(bytes): 3540 pass 3541 base = b'abc' 3542 m = MyBytes(base) 3543 # b2a_hex uses the buffer interface to get its argument's value, via 3544 # PyArg_ParseTuple 't#' code. 3545 self.assertEqual(binascii.b2a_hex(m), binascii.b2a_hex(base)) 3546 3547 class MyInt(int): 3548 pass 3549 m = MyInt(42) 3550 try: 3551 binascii.b2a_hex(m) 3552 self.fail('subclass of int should not have a buffer interface') 3553 except TypeError: 3554 pass 3555 3556 def test_str_of_str_subclass(self): 3557 # Testing __str__ defined in subclass of str ... 3558 import binascii 3559 import io 3560 3561 class octetstring(str): 3562 def __str__(self): 3563 return binascii.b2a_hex(self.encode('ascii')).decode("ascii") 3564 def __repr__(self): 3565 return self + " repr" 3566 3567 o = octetstring('A') 3568 self.assertEqual(type(o), octetstring) 3569 self.assertEqual(type(str(o)), str) 3570 self.assertEqual(type(repr(o)), str) 3571 self.assertEqual(ord(o), 0x41) 3572 self.assertEqual(str(o), '41') 3573 self.assertEqual(repr(o), 'A repr') 3574 self.assertEqual(o.__str__(), '41') 3575 self.assertEqual(o.__repr__(), 'A repr') 3576 3577 def test_keyword_arguments(self): 3578 # Testing keyword arguments to __init__, __call__... 3579 def f(a): return a 3580 self.assertEqual(f.__call__(a=42), 42) 3581 ba = bytearray() 3582 bytearray.__init__(ba, 'abc\xbd\u20ac', 3583 encoding='latin1', errors='replace') 3584 self.assertEqual(ba, b'abc\xbd?') 3585 3586 def test_recursive_call(self): 3587 # Testing recursive __call__() by setting to instance of class... 3588 class A(object): 3589 pass 3590 3591 A.__call__ = A() 3592 try: 3593 A()() 3594 except RecursionError: 3595 pass 3596 else: 3597 self.fail("Recursion limit should have been reached for __call__()") 3598 3599 def test_delete_hook(self): 3600 # Testing __del__ hook... 3601 log = [] 3602 class C(object): 3603 def __del__(self): 3604 log.append(1) 3605 c = C() 3606 self.assertEqual(log, []) 3607 del c 3608 support.gc_collect() 3609 self.assertEqual(log, [1]) 3610 3611 class D(object): pass 3612 d = D() 3613 try: del d[0] 3614 except TypeError: pass 3615 else: self.fail("invalid del() didn't raise TypeError") 3616 3617 def test_hash_inheritance(self): 3618 # Testing hash of mutable subclasses... 3619 3620 class mydict(dict): 3621 pass 3622 d = mydict() 3623 try: 3624 hash(d) 3625 except TypeError: 3626 pass 3627 else: 3628 self.fail("hash() of dict subclass should fail") 3629 3630 class mylist(list): 3631 pass 3632 d = mylist() 3633 try: 3634 hash(d) 3635 except TypeError: 3636 pass 3637 else: 3638 self.fail("hash() of list subclass should fail") 3639 3640 def test_str_operations(self): 3641 try: 'a' + 5 3642 except TypeError: pass 3643 else: self.fail("'' + 5 doesn't raise TypeError") 3644 3645 try: ''.split('') 3646 except ValueError: pass 3647 else: self.fail("''.split('') doesn't raise ValueError") 3648 3649 try: ''.join([0]) 3650 except TypeError: pass 3651 else: self.fail("''.join([0]) doesn't raise TypeError") 3652 3653 try: ''.rindex('5') 3654 except ValueError: pass 3655 else: self.fail("''.rindex('5') doesn't raise ValueError") 3656 3657 try: '%(n)s' % None 3658 except TypeError: pass 3659 else: self.fail("'%(n)s' % None doesn't raise TypeError") 3660 3661 try: '%(n' % {} 3662 except ValueError: pass 3663 else: self.fail("'%(n' % {} '' doesn't raise ValueError") 3664 3665 try: '%*s' % ('abc') 3666 except TypeError: pass 3667 else: self.fail("'%*s' % ('abc') doesn't raise TypeError") 3668 3669 try: '%*.*s' % ('abc', 5) 3670 except TypeError: pass 3671 else: self.fail("'%*.*s' % ('abc', 5) doesn't raise TypeError") 3672 3673 try: '%s' % (1, 2) 3674 except TypeError: pass 3675 else: self.fail("'%s' % (1, 2) doesn't raise TypeError") 3676 3677 try: '%' % None 3678 except ValueError: pass 3679 else: self.fail("'%' % None doesn't raise ValueError") 3680 3681 self.assertEqual('534253'.isdigit(), 1) 3682 self.assertEqual('534253x'.isdigit(), 0) 3683 self.assertEqual('%c' % 5, '\x05') 3684 self.assertEqual('%c' % '5', '5') 3685 3686 def test_deepcopy_recursive(self): 3687 # Testing deepcopy of recursive objects... 3688 class Node: 3689 pass 3690 a = Node() 3691 b = Node() 3692 a.b = b 3693 b.a = a 3694 z = deepcopy(a) # This blew up before 3695 3696 def test_uninitialized_modules(self): 3697 # Testing uninitialized module objects... 3698 from types import ModuleType as M 3699 m = M.__new__(M) 3700 str(m) 3701 self.assertNotHasAttr(m, "__name__") 3702 self.assertNotHasAttr(m, "__file__") 3703 self.assertNotHasAttr(m, "foo") 3704 self.assertFalse(m.__dict__) # None or {} are both reasonable answers 3705 m.foo = 1 3706 self.assertEqual(m.__dict__, {"foo": 1}) 3707 3708 def test_funny_new(self): 3709 # Testing __new__ returning something unexpected... 3710 class C(object): 3711 def __new__(cls, arg): 3712 if isinstance(arg, str): return [1, 2, 3] 3713 elif isinstance(arg, int): return object.__new__(D) 3714 else: return object.__new__(cls) 3715 class D(C): 3716 def __init__(self, arg): 3717 self.foo = arg 3718 self.assertEqual(C("1"), [1, 2, 3]) 3719 self.assertEqual(D("1"), [1, 2, 3]) 3720 d = D(None) 3721 self.assertEqual(d.foo, None) 3722 d = C(1) 3723 self.assertIsInstance(d, D) 3724 self.assertEqual(d.foo, 1) 3725 d = D(1) 3726 self.assertIsInstance(d, D) 3727 self.assertEqual(d.foo, 1) 3728 3729 class C(object): 3730 @staticmethod 3731 def __new__(*args): 3732 return args 3733 self.assertEqual(C(1, 2), (C, 1, 2)) 3734 class D(C): 3735 pass 3736 self.assertEqual(D(1, 2), (D, 1, 2)) 3737 3738 class C(object): 3739 @classmethod 3740 def __new__(*args): 3741 return args 3742 self.assertEqual(C(1, 2), (C, C, 1, 2)) 3743 class D(C): 3744 pass 3745 self.assertEqual(D(1, 2), (D, D, 1, 2)) 3746 3747 def test_imul_bug(self): 3748 # Testing for __imul__ problems... 3749 # SF bug 544647 3750 class C(object): 3751 def __imul__(self, other): 3752 return (self, other) 3753 x = C() 3754 y = x 3755 y *= 1.0 3756 self.assertEqual(y, (x, 1.0)) 3757 y = x 3758 y *= 2 3759 self.assertEqual(y, (x, 2)) 3760 y = x 3761 y *= 3 3762 self.assertEqual(y, (x, 3)) 3763 y = x 3764 y *= 1<<100 3765 self.assertEqual(y, (x, 1<<100)) 3766 y = x 3767 y *= None 3768 self.assertEqual(y, (x, None)) 3769 y = x 3770 y *= "foo" 3771 self.assertEqual(y, (x, "foo")) 3772 3773 def test_copy_setstate(self): 3774 # Testing that copy.*copy() correctly uses __setstate__... 3775 import copy 3776 class C(object): 3777 def __init__(self, foo=None): 3778 self.foo = foo 3779 self.__foo = foo 3780 def setfoo(self, foo=None): 3781 self.foo = foo 3782 def getfoo(self): 3783 return self.__foo 3784 def __getstate__(self): 3785 return [self.foo] 3786 def __setstate__(self_, lst): 3787 self.assertEqual(len(lst), 1) 3788 self_.__foo = self_.foo = lst[0] 3789 a = C(42) 3790 a.setfoo(24) 3791 self.assertEqual(a.foo, 24) 3792 self.assertEqual(a.getfoo(), 42) 3793 b = copy.copy(a) 3794 self.assertEqual(b.foo, 24) 3795 self.assertEqual(b.getfoo(), 24) 3796 b = copy.deepcopy(a) 3797 self.assertEqual(b.foo, 24) 3798 self.assertEqual(b.getfoo(), 24) 3799 3800 def test_slices(self): 3801 # Testing cases with slices and overridden __getitem__ ... 3802 3803 # Strings 3804 self.assertEqual("hello"[:4], "hell") 3805 self.assertEqual("hello"[slice(4)], "hell") 3806 self.assertEqual(str.__getitem__("hello", slice(4)), "hell") 3807 class S(str): 3808 def __getitem__(self, x): 3809 return str.__getitem__(self, x) 3810 self.assertEqual(S("hello")[:4], "hell") 3811 self.assertEqual(S("hello")[slice(4)], "hell") 3812 self.assertEqual(S("hello").__getitem__(slice(4)), "hell") 3813 # Tuples 3814 self.assertEqual((1,2,3)[:2], (1,2)) 3815 self.assertEqual((1,2,3)[slice(2)], (1,2)) 3816 self.assertEqual(tuple.__getitem__((1,2,3), slice(2)), (1,2)) 3817 class T(tuple): 3818 def __getitem__(self, x): 3819 return tuple.__getitem__(self, x) 3820 self.assertEqual(T((1,2,3))[:2], (1,2)) 3821 self.assertEqual(T((1,2,3))[slice(2)], (1,2)) 3822 self.assertEqual(T((1,2,3)).__getitem__(slice(2)), (1,2)) 3823 # Lists 3824 self.assertEqual([1,2,3][:2], [1,2]) 3825 self.assertEqual([1,2,3][slice(2)], [1,2]) 3826 self.assertEqual(list.__getitem__([1,2,3], slice(2)), [1,2]) 3827 class L(list): 3828 def __getitem__(self, x): 3829 return list.__getitem__(self, x) 3830 self.assertEqual(L([1,2,3])[:2], [1,2]) 3831 self.assertEqual(L([1,2,3])[slice(2)], [1,2]) 3832 self.assertEqual(L([1,2,3]).__getitem__(slice(2)), [1,2]) 3833 # Now do lists and __setitem__ 3834 a = L([1,2,3]) 3835 a[slice(1, 3)] = [3,2] 3836 self.assertEqual(a, [1,3,2]) 3837 a[slice(0, 2, 1)] = [3,1] 3838 self.assertEqual(a, [3,1,2]) 3839 a.__setitem__(slice(1, 3), [2,1]) 3840 self.assertEqual(a, [3,2,1]) 3841 a.__setitem__(slice(0, 2, 1), [2,3]) 3842 self.assertEqual(a, [2,3,1]) 3843 3844 def test_subtype_resurrection(self): 3845 # Testing resurrection of new-style instance... 3846 3847 class C(object): 3848 container = [] 3849 3850 def __del__(self): 3851 # resurrect the instance 3852 C.container.append(self) 3853 3854 c = C() 3855 c.attr = 42 3856 3857 # The most interesting thing here is whether this blows up, due to 3858 # flawed GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 3859 # bug). 3860 del c 3861 3862 support.gc_collect() 3863 self.assertEqual(len(C.container), 1) 3864 3865 # Make c mortal again, so that the test framework with -l doesn't report 3866 # it as a leak. 3867 del C.__del__ 3868 3869 def test_slots_trash(self): 3870 # Testing slot trash... 3871 # Deallocating deeply nested slotted trash caused stack overflows 3872 class trash(object): 3873 __slots__ = ['x'] 3874 def __init__(self, x): 3875 self.x = x 3876 o = None 3877 for i in range(50000): 3878 o = trash(o) 3879 del o 3880 3881 def test_slots_multiple_inheritance(self): 3882 # SF bug 575229, multiple inheritance w/ slots dumps core 3883 class A(object): 3884 __slots__=() 3885 class B(object): 3886 pass 3887 class C(A,B) : 3888 __slots__=() 3889 if support.check_impl_detail(): 3890 self.assertEqual(C.__basicsize__, B.__basicsize__) 3891 self.assertHasAttr(C, '__dict__') 3892 self.assertHasAttr(C, '__weakref__') 3893 C().x = 2 3894 3895 def test_rmul(self): 3896 # Testing correct invocation of __rmul__... 3897 # SF patch 592646 3898 class C(object): 3899 def __mul__(self, other): 3900 return "mul" 3901 def __rmul__(self, other): 3902 return "rmul" 3903 a = C() 3904 self.assertEqual(a*2, "mul") 3905 self.assertEqual(a*2.2, "mul") 3906 self.assertEqual(2*a, "rmul") 3907 self.assertEqual(2.2*a, "rmul") 3908 3909 def test_ipow(self): 3910 # Testing correct invocation of __ipow__... 3911 # [SF bug 620179] 3912 class C(object): 3913 def __ipow__(self, other): 3914 pass 3915 a = C() 3916 a **= 2 3917 3918 def test_ipow_returns_not_implemented(self): 3919 class A: 3920 def __ipow__(self, other): 3921 return NotImplemented 3922 3923 class B(A): 3924 def __rpow__(self, other): 3925 return 1 3926 3927 class C(A): 3928 def __pow__(self, other): 3929 return 2 3930 a = A() 3931 b = B() 3932 c = C() 3933 3934 a **= b 3935 self.assertEqual(a, 1) 3936 3937 c **= b 3938 self.assertEqual(c, 2) 3939 3940 def test_no_ipow(self): 3941 class B: 3942 def __rpow__(self, other): 3943 return 1 3944 3945 a = object() 3946 b = B() 3947 a **= b 3948 self.assertEqual(a, 1) 3949 3950 def test_ipow_exception_text(self): 3951 x = None 3952 with self.assertRaises(TypeError) as cm: 3953 x **= 2 3954 self.assertIn('unsupported operand type(s) for **=', str(cm.exception)) 3955 3956 with self.assertRaises(TypeError) as cm: 3957 y = x ** 2 3958 self.assertIn('unsupported operand type(s) for **', str(cm.exception)) 3959 3960 def test_mutable_bases(self): 3961 # Testing mutable bases... 3962 3963 # stuff that should work: 3964 class C(object): 3965 pass 3966 class C2(object): 3967 def __getattribute__(self, attr): 3968 if attr == 'a': 3969 return 2 3970 else: 3971 return super(C2, self).__getattribute__(attr) 3972 def meth(self): 3973 return 1 3974 class D(C): 3975 pass 3976 class E(D): 3977 pass 3978 d = D() 3979 e = E() 3980 D.__bases__ = (C,) 3981 D.__bases__ = (C2,) 3982 self.assertEqual(d.meth(), 1) 3983 self.assertEqual(e.meth(), 1) 3984 self.assertEqual(d.a, 2) 3985 self.assertEqual(e.a, 2) 3986 self.assertEqual(C2.__subclasses__(), [D]) 3987 3988 try: 3989 del D.__bases__ 3990 except (TypeError, AttributeError): 3991 pass 3992 else: 3993 self.fail("shouldn't be able to delete .__bases__") 3994 3995 try: 3996 D.__bases__ = () 3997 except TypeError as msg: 3998 if str(msg) == "a new-style class can't have only classic bases": 3999 self.fail("wrong error message for .__bases__ = ()") 4000 else: 4001 self.fail("shouldn't be able to set .__bases__ to ()") 4002 4003 try: 4004 D.__bases__ = (D,) 4005 except TypeError: 4006 pass 4007 else: 4008 # actually, we'll have crashed by here... 4009 self.fail("shouldn't be able to create inheritance cycles") 4010 4011 try: 4012 D.__bases__ = (C, C) 4013 except TypeError: 4014 pass 4015 else: 4016 self.fail("didn't detect repeated base classes") 4017 4018 try: 4019 D.__bases__ = (E,) 4020 except TypeError: 4021 pass 4022 else: 4023 self.fail("shouldn't be able to create inheritance cycles") 4024 4025 def test_builtin_bases(self): 4026 # Make sure all the builtin types can have their base queried without 4027 # segfaulting. See issue #5787. 4028 builtin_types = [tp for tp in builtins.__dict__.values() 4029 if isinstance(tp, type)] 4030 for tp in builtin_types: 4031 object.__getattribute__(tp, "__bases__") 4032 if tp is not object: 4033 self.assertEqual(len(tp.__bases__), 1, tp) 4034 4035 class L(list): 4036 pass 4037 4038 class C(object): 4039 pass 4040 4041 class D(C): 4042 pass 4043 4044 try: 4045 L.__bases__ = (dict,) 4046 except TypeError: 4047 pass 4048 else: 4049 self.fail("shouldn't turn list subclass into dict subclass") 4050 4051 try: 4052 list.__bases__ = (dict,) 4053 except TypeError: 4054 pass 4055 else: 4056 self.fail("shouldn't be able to assign to list.__bases__") 4057 4058 try: 4059 D.__bases__ = (C, list) 4060 except TypeError: 4061 pass 4062 else: 4063 self.fail("best_base calculation found wanting") 4064 4065 def test_unsubclassable_types(self): 4066 with self.assertRaises(TypeError): 4067 class X(type(None)): 4068 pass 4069 with self.assertRaises(TypeError): 4070 class X(object, type(None)): 4071 pass 4072 with self.assertRaises(TypeError): 4073 class X(type(None), object): 4074 pass 4075 class O(object): 4076 pass 4077 with self.assertRaises(TypeError): 4078 class X(O, type(None)): 4079 pass 4080 with self.assertRaises(TypeError): 4081 class X(type(None), O): 4082 pass 4083 4084 class X(object): 4085 pass 4086 with self.assertRaises(TypeError): 4087 X.__bases__ = type(None), 4088 with self.assertRaises(TypeError): 4089 X.__bases__ = object, type(None) 4090 with self.assertRaises(TypeError): 4091 X.__bases__ = type(None), object 4092 with self.assertRaises(TypeError): 4093 X.__bases__ = O, type(None) 4094 with self.assertRaises(TypeError): 4095 X.__bases__ = type(None), O 4096 4097 def test_mutable_bases_with_failing_mro(self): 4098 # Testing mutable bases with failing mro... 4099 class WorkOnce(type): 4100 def __new__(self, name, bases, ns): 4101 self.flag = 0 4102 return super(WorkOnce, self).__new__(WorkOnce, name, bases, ns) 4103 def mro(self): 4104 if self.flag > 0: 4105 raise RuntimeError("bozo") 4106 else: 4107 self.flag += 1 4108 return type.mro(self) 4109 4110 class WorkAlways(type): 4111 def mro(self): 4112 # this is here to make sure that .mro()s aren't called 4113 # with an exception set (which was possible at one point). 4114 # An error message will be printed in a debug build. 4115 # What's a good way to test for this? 4116 return type.mro(self) 4117 4118 class C(object): 4119 pass 4120 4121 class C2(object): 4122 pass 4123 4124 class D(C): 4125 pass 4126 4127 class E(D): 4128 pass 4129 4130 class F(D, metaclass=WorkOnce): 4131 pass 4132 4133 class G(D, metaclass=WorkAlways): 4134 pass 4135 4136 # Immediate subclasses have their mro's adjusted in alphabetical 4137 # order, so E's will get adjusted before adjusting F's fails. We 4138 # check here that E's gets restored. 4139 4140 E_mro_before = E.__mro__ 4141 D_mro_before = D.__mro__ 4142 4143 try: 4144 D.__bases__ = (C2,) 4145 except RuntimeError: 4146 self.assertEqual(E.__mro__, E_mro_before) 4147 self.assertEqual(D.__mro__, D_mro_before) 4148 else: 4149 self.fail("exception not propagated") 4150 4151 def test_mutable_bases_catch_mro_conflict(self): 4152 # Testing mutable bases catch mro conflict... 4153 class A(object): 4154 pass 4155 4156 class B(object): 4157 pass 4158 4159 class C(A, B): 4160 pass 4161 4162 class D(A, B): 4163 pass 4164 4165 class E(C, D): 4166 pass 4167 4168 try: 4169 C.__bases__ = (B, A) 4170 except TypeError: 4171 pass 4172 else: 4173 self.fail("didn't catch MRO conflict") 4174 4175 def test_mutable_names(self): 4176 # Testing mutable names... 4177 class C(object): 4178 pass 4179 4180 # C.__module__ could be 'test_descr' or '__main__' 4181 mod = C.__module__ 4182 4183 C.__name__ = 'D' 4184 self.assertEqual((C.__module__, C.__name__), (mod, 'D')) 4185 4186 C.__name__ = 'D.E' 4187 self.assertEqual((C.__module__, C.__name__), (mod, 'D.E')) 4188 4189 def test_evil_type_name(self): 4190 # A badly placed Py_DECREF in type_set_name led to arbitrary code 4191 # execution while the type structure was not in a sane state, and a 4192 # possible segmentation fault as a result. See bug #16447. 4193 class Nasty(str): 4194 def __del__(self): 4195 C.__name__ = "other" 4196 4197 class C: 4198 pass 4199 4200 C.__name__ = Nasty("abc") 4201 C.__name__ = "normal" 4202 4203 def test_subclass_right_op(self): 4204 # Testing correct dispatch of subclass overloading __r<op>__... 4205 4206 # This code tests various cases where right-dispatch of a subclass 4207 # should be preferred over left-dispatch of a base class. 4208 4209 # Case 1: subclass of int; this tests code in abstract.c::binary_op1() 4210 4211 class B(int): 4212 def __floordiv__(self, other): 4213 return "B.__floordiv__" 4214 def __rfloordiv__(self, other): 4215 return "B.__rfloordiv__" 4216 4217 self.assertEqual(B(1) // 1, "B.__floordiv__") 4218 self.assertEqual(1 // B(1), "B.__rfloordiv__") 4219 4220 # Case 2: subclass of object; this is just the baseline for case 3 4221 4222 class C(object): 4223 def __floordiv__(self, other): 4224 return "C.__floordiv__" 4225 def __rfloordiv__(self, other): 4226 return "C.__rfloordiv__" 4227 4228 self.assertEqual(C() // 1, "C.__floordiv__") 4229 self.assertEqual(1 // C(), "C.__rfloordiv__") 4230 4231 # Case 3: subclass of new-style class; here it gets interesting 4232 4233 class D(C): 4234 def __floordiv__(self, other): 4235 return "D.__floordiv__" 4236 def __rfloordiv__(self, other): 4237 return "D.__rfloordiv__" 4238 4239 self.assertEqual(D() // C(), "D.__floordiv__") 4240 self.assertEqual(C() // D(), "D.__rfloordiv__") 4241 4242 # Case 4: this didn't work right in 2.2.2 and 2.3a1 4243 4244 class E(C): 4245 pass 4246 4247 self.assertEqual(E.__rfloordiv__, C.__rfloordiv__) 4248 4249 self.assertEqual(E() // 1, "C.__floordiv__") 4250 self.assertEqual(1 // E(), "C.__rfloordiv__") 4251 self.assertEqual(E() // C(), "C.__floordiv__") 4252 self.assertEqual(C() // E(), "C.__floordiv__") # This one would fail 4253 4254 @support.impl_detail("testing an internal kind of method object") 4255 def test_meth_class_get(self): 4256 # Testing __get__ method of METH_CLASS C methods... 4257 # Full coverage of descrobject.c::classmethod_get() 4258 4259 # Baseline 4260 arg = [1, 2, 3] 4261 res = {1: None, 2: None, 3: None} 4262 self.assertEqual(dict.fromkeys(arg), res) 4263 self.assertEqual({}.fromkeys(arg), res) 4264 4265 # Now get the descriptor 4266 descr = dict.__dict__["fromkeys"] 4267 4268 # More baseline using the descriptor directly 4269 self.assertEqual(descr.__get__(None, dict)(arg), res) 4270 self.assertEqual(descr.__get__({})(arg), res) 4271 4272 # Now check various error cases 4273 try: 4274 descr.__get__(None, None) 4275 except TypeError: 4276 pass 4277 else: 4278 self.fail("shouldn't have allowed descr.__get__(None, None)") 4279 try: 4280 descr.__get__(42) 4281 except TypeError: 4282 pass 4283 else: 4284 self.fail("shouldn't have allowed descr.__get__(42)") 4285 try: 4286 descr.__get__(None, 42) 4287 except TypeError: 4288 pass 4289 else: 4290 self.fail("shouldn't have allowed descr.__get__(None, 42)") 4291 try: 4292 descr.__get__(None, int) 4293 except TypeError: 4294 pass 4295 else: 4296 self.fail("shouldn't have allowed descr.__get__(None, int)") 4297 4298 def test_isinst_isclass(self): 4299 # Testing proxy isinstance() and isclass()... 4300 class Proxy(object): 4301 def __init__(self, obj): 4302 self.__obj = obj 4303 def __getattribute__(self, name): 4304 if name.startswith("_Proxy__"): 4305 return object.__getattribute__(self, name) 4306 else: 4307 return getattr(self.__obj, name) 4308 # Test with a classic class 4309 class C: 4310 pass 4311 a = C() 4312 pa = Proxy(a) 4313 self.assertIsInstance(a, C) # Baseline 4314 self.assertIsInstance(pa, C) # Test 4315 # Test with a classic subclass 4316 class D(C): 4317 pass 4318 a = D() 4319 pa = Proxy(a) 4320 self.assertIsInstance(a, C) # Baseline 4321 self.assertIsInstance(pa, C) # Test 4322 # Test with a new-style class 4323 class C(object): 4324 pass 4325 a = C() 4326 pa = Proxy(a) 4327 self.assertIsInstance(a, C) # Baseline 4328 self.assertIsInstance(pa, C) # Test 4329 # Test with a new-style subclass 4330 class D(C): 4331 pass 4332 a = D() 4333 pa = Proxy(a) 4334 self.assertIsInstance(a, C) # Baseline 4335 self.assertIsInstance(pa, C) # Test 4336 4337 def test_proxy_super(self): 4338 # Testing super() for a proxy object... 4339 class Proxy(object): 4340 def __init__(self, obj): 4341 self.__obj = obj 4342 def __getattribute__(self, name): 4343 if name.startswith("_Proxy__"): 4344 return object.__getattribute__(self, name) 4345 else: 4346 return getattr(self.__obj, name) 4347 4348 class B(object): 4349 def f(self): 4350 return "B.f" 4351 4352 class C(B): 4353 def f(self): 4354 return super(C, self).f() + "->C.f" 4355 4356 obj = C() 4357 p = Proxy(obj) 4358 self.assertEqual(C.__dict__["f"](p), "B.f->C.f") 4359 4360 def test_carloverre(self): 4361 # Testing prohibition of Carlo Verre's hack... 4362 try: 4363 object.__setattr__(str, "foo", 42) 4364 except TypeError: 4365 pass 4366 else: 4367 self.fail("Carlo Verre __setattr__ succeeded!") 4368 try: 4369 object.__delattr__(str, "lower") 4370 except TypeError: 4371 pass 4372 else: 4373 self.fail("Carlo Verre __delattr__ succeeded!") 4374 4375 def test_carloverre_multi_inherit_valid(self): 4376 class A(type): 4377 def __setattr__(cls, key, value): 4378 type.__setattr__(cls, key, value) 4379 4380 class B: 4381 pass 4382 4383 class C(B, A): 4384 pass 4385 4386 obj = C('D', (object,), {}) 4387 try: 4388 obj.test = True 4389 except TypeError: 4390 self.fail("setattr through direct base types should be legal") 4391 4392 def test_carloverre_multi_inherit_invalid(self): 4393 class A(type): 4394 def __setattr__(cls, key, value): 4395 object.__setattr__(cls, key, value) # this should fail! 4396 4397 class B: 4398 pass 4399 4400 class C(B, A): 4401 pass 4402 4403 obj = C('D', (object,), {}) 4404 try: 4405 obj.test = True 4406 except TypeError: 4407 pass 4408 else: 4409 self.fail("setattr through indirect base types should be rejected") 4410 4411 def test_weakref_segfault(self): 4412 # Testing weakref segfault... 4413 # SF 742911 4414 import weakref 4415 4416 class Provoker: 4417 def __init__(self, referrent): 4418 self.ref = weakref.ref(referrent) 4419 4420 def __del__(self): 4421 x = self.ref() 4422 4423 class Oops(object): 4424 pass 4425 4426 o = Oops() 4427 o.whatever = Provoker(o) 4428 del o 4429 4430 def test_wrapper_segfault(self): 4431 # SF 927248: deeply nested wrappers could cause stack overflow 4432 f = lambda:None 4433 for i in range(1000000): 4434 f = f.__call__ 4435 f = None 4436 4437 def test_file_fault(self): 4438 # Testing sys.stdout is changed in getattr... 4439 test_stdout = sys.stdout 4440 class StdoutGuard: 4441 def __getattr__(self, attr): 4442 sys.stdout = sys.__stdout__ 4443 raise RuntimeError("Premature access to sys.stdout.%s" % attr) 4444 sys.stdout = StdoutGuard() 4445 try: 4446 print("Oops!") 4447 except RuntimeError: 4448 pass 4449 else: 4450 self.fail("Didn't raise RuntimeError") 4451 finally: 4452 sys.stdout = test_stdout 4453 4454 def test_vicious_descriptor_nonsense(self): 4455 # Testing vicious_descriptor_nonsense... 4456 4457 # A potential segfault spotted by Thomas Wouters in mail to 4458 # python-dev 2003-04-17, turned into an example & fixed by Michael 4459 # Hudson just less than four months later... 4460 4461 class Evil(object): 4462 def __hash__(self): 4463 return hash('attr') 4464 def __eq__(self, other): 4465 try: 4466 del C.attr 4467 except AttributeError: 4468 # possible race condition 4469 pass 4470 return 0 4471 4472 class Descr(object): 4473 def __get__(self, ob, type=None): 4474 return 1 4475 4476 class C(object): 4477 attr = Descr() 4478 4479 c = C() 4480 c.__dict__[Evil()] = 0 4481 4482 self.assertEqual(c.attr, 1) 4483 # this makes a crash more likely: 4484 support.gc_collect() 4485 self.assertNotHasAttr(c, 'attr') 4486 4487 def test_init(self): 4488 # SF 1155938 4489 class Foo(object): 4490 def __init__(self): 4491 return 10 4492 try: 4493 Foo() 4494 except TypeError: 4495 pass 4496 else: 4497 self.fail("did not test __init__() for None return") 4498 4499 def assertNotOrderable(self, a, b): 4500 with self.assertRaises(TypeError): 4501 a < b 4502 with self.assertRaises(TypeError): 4503 a > b 4504 with self.assertRaises(TypeError): 4505 a <= b 4506 with self.assertRaises(TypeError): 4507 a >= b 4508 4509 def test_method_wrapper(self): 4510 # Testing method-wrapper objects... 4511 # <type 'method-wrapper'> did not support any reflection before 2.5 4512 l = [] 4513 self.assertTrue(l.__add__ == l.__add__) 4514 self.assertFalse(l.__add__ != l.__add__) 4515 self.assertFalse(l.__add__ == [].__add__) 4516 self.assertTrue(l.__add__ != [].__add__) 4517 self.assertFalse(l.__add__ == l.__mul__) 4518 self.assertTrue(l.__add__ != l.__mul__) 4519 self.assertNotOrderable(l.__add__, l.__add__) 4520 self.assertEqual(l.__add__.__name__, '__add__') 4521 self.assertIs(l.__add__.__self__, l) 4522 self.assertIs(l.__add__.__objclass__, list) 4523 self.assertEqual(l.__add__.__doc__, list.__add__.__doc__) 4524 # hash([].__add__) should not be based on hash([]) 4525 hash(l.__add__) 4526 4527 def test_builtin_function_or_method(self): 4528 # Not really belonging to test_descr, but introspection and 4529 # comparison on <type 'builtin_function_or_method'> seems not 4530 # to be tested elsewhere 4531 l = [] 4532 self.assertTrue(l.append == l.append) 4533 self.assertFalse(l.append != l.append) 4534 self.assertFalse(l.append == [].append) 4535 self.assertTrue(l.append != [].append) 4536 self.assertFalse(l.append == l.pop) 4537 self.assertTrue(l.append != l.pop) 4538 self.assertNotOrderable(l.append, l.append) 4539 self.assertEqual(l.append.__name__, 'append') 4540 self.assertIs(l.append.__self__, l) 4541 # self.assertIs(l.append.__objclass__, list) --- could be added? 4542 self.assertEqual(l.append.__doc__, list.append.__doc__) 4543 # hash([].append) should not be based on hash([]) 4544 hash(l.append) 4545 4546 def test_special_unbound_method_types(self): 4547 # Testing objects of <type 'wrapper_descriptor'>... 4548 self.assertTrue(list.__add__ == list.__add__) 4549 self.assertFalse(list.__add__ != list.__add__) 4550 self.assertFalse(list.__add__ == list.__mul__) 4551 self.assertTrue(list.__add__ != list.__mul__) 4552 self.assertNotOrderable(list.__add__, list.__add__) 4553 self.assertEqual(list.__add__.__name__, '__add__') 4554 self.assertIs(list.__add__.__objclass__, list) 4555 4556 # Testing objects of <type 'method_descriptor'>... 4557 self.assertTrue(list.append == list.append) 4558 self.assertFalse(list.append != list.append) 4559 self.assertFalse(list.append == list.pop) 4560 self.assertTrue(list.append != list.pop) 4561 self.assertNotOrderable(list.append, list.append) 4562 self.assertEqual(list.append.__name__, 'append') 4563 self.assertIs(list.append.__objclass__, list) 4564 4565 def test_not_implemented(self): 4566 # Testing NotImplemented... 4567 # all binary methods should be able to return a NotImplemented 4568 import operator 4569 4570 def specialmethod(self, other): 4571 return NotImplemented 4572 4573 def check(expr, x, y): 4574 try: 4575 exec(expr, {'x': x, 'y': y, 'operator': operator}) 4576 except TypeError: 4577 pass 4578 else: 4579 self.fail("no TypeError from %r" % (expr,)) 4580 4581 N1 = sys.maxsize + 1 # might trigger OverflowErrors instead of 4582 # TypeErrors 4583 N2 = sys.maxsize # if sizeof(int) < sizeof(long), might trigger 4584 # ValueErrors instead of TypeErrors 4585 for name, expr, iexpr in [ 4586 ('__add__', 'x + y', 'x += y'), 4587 ('__sub__', 'x - y', 'x -= y'), 4588 ('__mul__', 'x * y', 'x *= y'), 4589 ('__matmul__', 'x @ y', 'x @= y'), 4590 ('__truediv__', 'x / y', 'x /= y'), 4591 ('__floordiv__', 'x // y', 'x //= y'), 4592 ('__mod__', 'x % y', 'x %= y'), 4593 ('__divmod__', 'divmod(x, y)', None), 4594 ('__pow__', 'x ** y', 'x **= y'), 4595 ('__lshift__', 'x << y', 'x <<= y'), 4596 ('__rshift__', 'x >> y', 'x >>= y'), 4597 ('__and__', 'x & y', 'x &= y'), 4598 ('__or__', 'x | y', 'x |= y'), 4599 ('__xor__', 'x ^ y', 'x ^= y')]: 4600 rname = '__r' + name[2:] 4601 A = type('A', (), {name: specialmethod}) 4602 a = A() 4603 check(expr, a, a) 4604 check(expr, a, N1) 4605 check(expr, a, N2) 4606 if iexpr: 4607 check(iexpr, a, a) 4608 check(iexpr, a, N1) 4609 check(iexpr, a, N2) 4610 iname = '__i' + name[2:] 4611 C = type('C', (), {iname: specialmethod}) 4612 c = C() 4613 check(iexpr, c, a) 4614 check(iexpr, c, N1) 4615 check(iexpr, c, N2) 4616 4617 def test_assign_slice(self): 4618 # ceval.c's assign_slice used to check for 4619 # tp->tp_as_sequence->sq_slice instead of 4620 # tp->tp_as_sequence->sq_ass_slice 4621 4622 class C(object): 4623 def __setitem__(self, idx, value): 4624 self.value = value 4625 4626 c = C() 4627 c[1:2] = 3 4628 self.assertEqual(c.value, 3) 4629 4630 def test_set_and_no_get(self): 4631 # See 4632 # http://mail.python.org/pipermail/python-dev/2010-January/095637.html 4633 class Descr(object): 4634 4635 def __init__(self, name): 4636 self.name = name 4637 4638 def __set__(self, obj, value): 4639 obj.__dict__[self.name] = value 4640 descr = Descr("a") 4641 4642 class X(object): 4643 a = descr 4644 4645 x = X() 4646 self.assertIs(x.a, descr) 4647 x.a = 42 4648 self.assertEqual(x.a, 42) 4649 4650 # Also check type_getattro for correctness. 4651 class Meta(type): 4652 pass 4653 class X(metaclass=Meta): 4654 pass 4655 X.a = 42 4656 Meta.a = Descr("a") 4657 self.assertEqual(X.a, 42) 4658 4659 def test_getattr_hooks(self): 4660 # issue 4230 4661 4662 class Descriptor(object): 4663 counter = 0 4664 def __get__(self, obj, objtype=None): 4665 def getter(name): 4666 self.counter += 1 4667 raise AttributeError(name) 4668 return getter 4669 4670 descr = Descriptor() 4671 class A(object): 4672 __getattribute__ = descr 4673 class B(object): 4674 __getattr__ = descr 4675 class C(object): 4676 __getattribute__ = descr 4677 __getattr__ = descr 4678 4679 self.assertRaises(AttributeError, getattr, A(), "attr") 4680 self.assertEqual(descr.counter, 1) 4681 self.assertRaises(AttributeError, getattr, B(), "attr") 4682 self.assertEqual(descr.counter, 2) 4683 self.assertRaises(AttributeError, getattr, C(), "attr") 4684 self.assertEqual(descr.counter, 4) 4685 4686 class EvilGetattribute(object): 4687 # This used to segfault 4688 def __getattr__(self, name): 4689 raise AttributeError(name) 4690 def __getattribute__(self, name): 4691 del EvilGetattribute.__getattr__ 4692 for i in range(5): 4693 gc.collect() 4694 raise AttributeError(name) 4695 4696 self.assertRaises(AttributeError, getattr, EvilGetattribute(), "attr") 4697 4698 def test_type___getattribute__(self): 4699 self.assertRaises(TypeError, type.__getattribute__, list, type) 4700 4701 def test_abstractmethods(self): 4702 # type pretends not to have __abstractmethods__. 4703 self.assertRaises(AttributeError, getattr, type, "__abstractmethods__") 4704 class meta(type): 4705 pass 4706 self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__") 4707 class X(object): 4708 pass 4709 with self.assertRaises(AttributeError): 4710 del X.__abstractmethods__ 4711 4712 def test_proxy_call(self): 4713 class FakeStr: 4714 __class__ = str 4715 4716 fake_str = FakeStr() 4717 # isinstance() reads __class__ 4718 self.assertIsInstance(fake_str, str) 4719 4720 # call a method descriptor 4721 with self.assertRaises(TypeError): 4722 str.split(fake_str) 4723 4724 # call a slot wrapper descriptor 4725 with self.assertRaises(TypeError): 4726 str.__add__(fake_str, "abc") 4727 4728 def test_repr_as_str(self): 4729 # Issue #11603: crash or infinite loop when rebinding __str__ as 4730 # __repr__. 4731 class Foo: 4732 pass 4733 Foo.__repr__ = Foo.__str__ 4734 foo = Foo() 4735 self.assertRaises(RecursionError, str, foo) 4736 self.assertRaises(RecursionError, repr, foo) 4737 4738 def test_mixing_slot_wrappers(self): 4739 class X(dict): 4740 __setattr__ = dict.__setitem__ 4741 __neg__ = dict.copy 4742 x = X() 4743 x.y = 42 4744 self.assertEqual(x["y"], 42) 4745 self.assertEqual(x, -x) 4746 4747 def test_wrong_class_slot_wrapper(self): 4748 # Check bpo-37619: a wrapper descriptor taken from the wrong class 4749 # should raise an exception instead of silently being ignored 4750 class A(int): 4751 __eq__ = str.__eq__ 4752 __add__ = str.__add__ 4753 a = A() 4754 with self.assertRaises(TypeError): 4755 a == a 4756 with self.assertRaises(TypeError): 4757 a + a 4758 4759 def test_slot_shadows_class_variable(self): 4760 with self.assertRaises(ValueError) as cm: 4761 class X: 4762 __slots__ = ["foo"] 4763 foo = None 4764 m = str(cm.exception) 4765 self.assertEqual("'foo' in __slots__ conflicts with class variable", m) 4766 4767 def test_set_doc(self): 4768 class X: 4769 "elephant" 4770 X.__doc__ = "banana" 4771 self.assertEqual(X.__doc__, "banana") 4772 4773 with self.assertRaises(TypeError) as cm: 4774 type(list).__dict__["__doc__"].__set__(list, "blah") 4775 self.assertIn("cannot set '__doc__' attribute of immutable type 'list'", str(cm.exception)) 4776 4777 with self.assertRaises(TypeError) as cm: 4778 type(X).__dict__["__doc__"].__delete__(X) 4779 self.assertIn("cannot delete '__doc__' attribute of immutable type 'X'", str(cm.exception)) 4780 self.assertEqual(X.__doc__, "banana") 4781 4782 def test_qualname(self): 4783 descriptors = [str.lower, complex.real, float.real, int.__add__] 4784 types = ['method', 'member', 'getset', 'wrapper'] 4785 4786 # make sure we have an example of each type of descriptor 4787 for d, n in zip(descriptors, types): 4788 self.assertEqual(type(d).__name__, n + '_descriptor') 4789 4790 for d in descriptors: 4791 qualname = d.__objclass__.__qualname__ + '.' + d.__name__ 4792 self.assertEqual(d.__qualname__, qualname) 4793 4794 self.assertEqual(str.lower.__qualname__, 'str.lower') 4795 self.assertEqual(complex.real.__qualname__, 'complex.real') 4796 self.assertEqual(float.real.__qualname__, 'float.real') 4797 self.assertEqual(int.__add__.__qualname__, 'int.__add__') 4798 4799 class X: 4800 pass 4801 with self.assertRaises(TypeError): 4802 del X.__qualname__ 4803 4804 self.assertRaises(TypeError, type.__dict__['__qualname__'].__set__, 4805 str, 'Oink') 4806 4807 global Y 4808 class Y: 4809 class Inside: 4810 pass 4811 self.assertEqual(Y.__qualname__, 'Y') 4812 self.assertEqual(Y.Inside.__qualname__, 'Y.Inside') 4813 4814 def test_qualname_dict(self): 4815 ns = {'__qualname__': 'some.name'} 4816 tp = type('Foo', (), ns) 4817 self.assertEqual(tp.__qualname__, 'some.name') 4818 self.assertNotIn('__qualname__', tp.__dict__) 4819 self.assertEqual(ns, {'__qualname__': 'some.name'}) 4820 4821 ns = {'__qualname__': 1} 4822 self.assertRaises(TypeError, type, 'Foo', (), ns) 4823 4824 def test_cycle_through_dict(self): 4825 # See bug #1469629 4826 class X(dict): 4827 def __init__(self): 4828 dict.__init__(self) 4829 self.__dict__ = self 4830 x = X() 4831 x.attr = 42 4832 wr = weakref.ref(x) 4833 del x 4834 support.gc_collect() 4835 self.assertIsNone(wr()) 4836 for o in gc.get_objects(): 4837 self.assertIsNot(type(o), X) 4838 4839 def test_object_new_and_init_with_parameters(self): 4840 # See issue #1683368 4841 class OverrideNeither: 4842 pass 4843 self.assertRaises(TypeError, OverrideNeither, 1) 4844 self.assertRaises(TypeError, OverrideNeither, kw=1) 4845 class OverrideNew: 4846 def __new__(cls, foo, kw=0, *args, **kwds): 4847 return object.__new__(cls, *args, **kwds) 4848 class OverrideInit: 4849 def __init__(self, foo, kw=0, *args, **kwargs): 4850 return object.__init__(self, *args, **kwargs) 4851 class OverrideBoth(OverrideNew, OverrideInit): 4852 pass 4853 for case in OverrideNew, OverrideInit, OverrideBoth: 4854 case(1) 4855 case(1, kw=2) 4856 self.assertRaises(TypeError, case, 1, 2, 3) 4857 self.assertRaises(TypeError, case, 1, 2, foo=3) 4858 4859 def test_subclassing_does_not_duplicate_dict_descriptors(self): 4860 class Base: 4861 pass 4862 class Sub(Base): 4863 pass 4864 self.assertIn("__dict__", Base.__dict__) 4865 self.assertNotIn("__dict__", Sub.__dict__) 4866 4867 def test_bound_method_repr(self): 4868 class Foo: 4869 def method(self): 4870 pass 4871 self.assertRegex(repr(Foo().method), 4872 r"<bound method .*Foo\.method of <.*Foo object at .*>>") 4873 4874 4875 class Base: 4876 def method(self): 4877 pass 4878 class Derived1(Base): 4879 pass 4880 class Derived2(Base): 4881 def method(self): 4882 pass 4883 base = Base() 4884 derived1 = Derived1() 4885 derived2 = Derived2() 4886 super_d2 = super(Derived2, derived2) 4887 self.assertRegex(repr(base.method), 4888 r"<bound method .*Base\.method of <.*Base object at .*>>") 4889 self.assertRegex(repr(derived1.method), 4890 r"<bound method .*Base\.method of <.*Derived1 object at .*>>") 4891 self.assertRegex(repr(derived2.method), 4892 r"<bound method .*Derived2\.method of <.*Derived2 object at .*>>") 4893 self.assertRegex(repr(super_d2.method), 4894 r"<bound method .*Base\.method of <.*Derived2 object at .*>>") 4895 4896 class Foo: 4897 @classmethod 4898 def method(cls): 4899 pass 4900 foo = Foo() 4901 self.assertRegex(repr(foo.method), # access via instance 4902 r"<bound method .*Foo\.method of <class '.*Foo'>>") 4903 self.assertRegex(repr(Foo.method), # access via the class 4904 r"<bound method .*Foo\.method of <class '.*Foo'>>") 4905 4906 4907 class MyCallable: 4908 def __call__(self, arg): 4909 pass 4910 func = MyCallable() # func has no __name__ or __qualname__ attributes 4911 instance = object() 4912 method = types.MethodType(func, instance) 4913 self.assertRegex(repr(method), 4914 r"<bound method \? of <object object at .*>>") 4915 func.__name__ = "name" 4916 self.assertRegex(repr(method), 4917 r"<bound method name of <object object at .*>>") 4918 func.__qualname__ = "qualname" 4919 self.assertRegex(repr(method), 4920 r"<bound method qualname of <object object at .*>>") 4921 4922 @unittest.skipIf(_testcapi is None, 'need the _testcapi module') 4923 def test_bpo25750(self): 4924 # bpo-25750: calling a descriptor (implemented as built-in 4925 # function with METH_FASTCALL) should not crash CPython if the 4926 # descriptor deletes itself from the class. 4927 class Descr: 4928 __get__ = _testcapi.bad_get 4929 4930 class X: 4931 descr = Descr() 4932 def __new__(cls): 4933 cls.descr = None 4934 # Create this large list to corrupt some unused memory 4935 cls.lst = [2**i for i in range(10000)] 4936 X.descr 4937 4938 4939class DictProxyTests(unittest.TestCase): 4940 def setUp(self): 4941 class C(object): 4942 def meth(self): 4943 pass 4944 self.C = C 4945 4946 @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 4947 'trace function introduces __local__') 4948 def test_iter_keys(self): 4949 # Testing dict-proxy keys... 4950 it = self.C.__dict__.keys() 4951 self.assertNotIsInstance(it, list) 4952 keys = list(it) 4953 keys.sort() 4954 self.assertEqual(keys, ['__dict__', '__doc__', '__module__', 4955 '__weakref__', 'meth']) 4956 4957 @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 4958 'trace function introduces __local__') 4959 def test_iter_values(self): 4960 # Testing dict-proxy values... 4961 it = self.C.__dict__.values() 4962 self.assertNotIsInstance(it, list) 4963 values = list(it) 4964 self.assertEqual(len(values), 5) 4965 4966 @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 4967 'trace function introduces __local__') 4968 def test_iter_items(self): 4969 # Testing dict-proxy iteritems... 4970 it = self.C.__dict__.items() 4971 self.assertNotIsInstance(it, list) 4972 keys = [item[0] for item in it] 4973 keys.sort() 4974 self.assertEqual(keys, ['__dict__', '__doc__', '__module__', 4975 '__weakref__', 'meth']) 4976 4977 def test_dict_type_with_metaclass(self): 4978 # Testing type of __dict__ when metaclass set... 4979 class B(object): 4980 pass 4981 class M(type): 4982 pass 4983 class C(metaclass=M): 4984 # In 2.3a1, C.__dict__ was a real dict rather than a dict proxy 4985 pass 4986 self.assertEqual(type(C.__dict__), type(B.__dict__)) 4987 4988 def test_repr(self): 4989 # Testing mappingproxy.__repr__. 4990 # We can't blindly compare with the repr of another dict as ordering 4991 # of keys and values is arbitrary and may differ. 4992 r = repr(self.C.__dict__) 4993 self.assertTrue(r.startswith('mappingproxy('), r) 4994 self.assertTrue(r.endswith(')'), r) 4995 for k, v in self.C.__dict__.items(): 4996 self.assertIn('{!r}: {!r}'.format(k, v), r) 4997 4998 4999class AAAPTypesLongInitTest(unittest.TestCase): 5000 # This is in its own TestCase so that it can be run before any other tests. 5001 # (Hence the 'AAA' in the test class name: to make it the first 5002 # item in a list sorted by name, like 5003 # unittest.TestLoader.getTestCaseNames() does.) 5004 def test_pytype_long_ready(self): 5005 # Testing SF bug 551412 ... 5006 5007 # This dumps core when SF bug 551412 isn't fixed -- 5008 # but only when test_descr.py is run separately. 5009 # (That can't be helped -- as soon as PyType_Ready() 5010 # is called for PyLong_Type, the bug is gone.) 5011 class UserLong(object): 5012 def __pow__(self, *args): 5013 pass 5014 try: 5015 pow(0, UserLong(), 0) 5016 except: 5017 pass 5018 5019 # Another segfault only when run early 5020 # (before PyType_Ready(tuple) is called) 5021 type.mro(tuple) 5022 5023 5024class MiscTests(unittest.TestCase): 5025 def test_type_lookup_mro_reference(self): 5026 # Issue #14199: _PyType_Lookup() has to keep a strong reference to 5027 # the type MRO because it may be modified during the lookup, if 5028 # __bases__ is set during the lookup for example. 5029 class MyKey(object): 5030 def __hash__(self): 5031 return hash('mykey') 5032 5033 def __eq__(self, other): 5034 X.__bases__ = (Base2,) 5035 5036 class Base(object): 5037 mykey = 'from Base' 5038 mykey2 = 'from Base' 5039 5040 class Base2(object): 5041 mykey = 'from Base2' 5042 mykey2 = 'from Base2' 5043 5044 X = type('X', (Base,), {MyKey(): 5}) 5045 # mykey is read from Base 5046 self.assertEqual(X.mykey, 'from Base') 5047 # mykey2 is read from Base2 because MyKey.__eq__ has set __bases__ 5048 self.assertEqual(X.mykey2, 'from Base2') 5049 5050 5051class PicklingTests(unittest.TestCase): 5052 5053 def _check_reduce(self, proto, obj, args=(), kwargs={}, state=None, 5054 listitems=None, dictitems=None): 5055 if proto >= 2: 5056 reduce_value = obj.__reduce_ex__(proto) 5057 if kwargs: 5058 self.assertEqual(reduce_value[0], copyreg.__newobj_ex__) 5059 self.assertEqual(reduce_value[1], (type(obj), args, kwargs)) 5060 else: 5061 self.assertEqual(reduce_value[0], copyreg.__newobj__) 5062 self.assertEqual(reduce_value[1], (type(obj),) + args) 5063 self.assertEqual(reduce_value[2], state) 5064 if listitems is not None: 5065 self.assertListEqual(list(reduce_value[3]), listitems) 5066 else: 5067 self.assertIsNone(reduce_value[3]) 5068 if dictitems is not None: 5069 self.assertDictEqual(dict(reduce_value[4]), dictitems) 5070 else: 5071 self.assertIsNone(reduce_value[4]) 5072 else: 5073 base_type = type(obj).__base__ 5074 reduce_value = (copyreg._reconstructor, 5075 (type(obj), 5076 base_type, 5077 None if base_type is object else base_type(obj))) 5078 if state is not None: 5079 reduce_value += (state,) 5080 self.assertEqual(obj.__reduce_ex__(proto), reduce_value) 5081 self.assertEqual(obj.__reduce__(), reduce_value) 5082 5083 def test_reduce(self): 5084 protocols = range(pickle.HIGHEST_PROTOCOL + 1) 5085 args = (-101, "spam") 5086 kwargs = {'bacon': -201, 'fish': -301} 5087 state = {'cheese': -401} 5088 5089 class C1: 5090 def __getnewargs__(self): 5091 return args 5092 obj = C1() 5093 for proto in protocols: 5094 self._check_reduce(proto, obj, args) 5095 5096 for name, value in state.items(): 5097 setattr(obj, name, value) 5098 for proto in protocols: 5099 self._check_reduce(proto, obj, args, state=state) 5100 5101 class C2: 5102 def __getnewargs__(self): 5103 return "bad args" 5104 obj = C2() 5105 for proto in protocols: 5106 if proto >= 2: 5107 with self.assertRaises(TypeError): 5108 obj.__reduce_ex__(proto) 5109 5110 class C3: 5111 def __getnewargs_ex__(self): 5112 return (args, kwargs) 5113 obj = C3() 5114 for proto in protocols: 5115 if proto >= 2: 5116 self._check_reduce(proto, obj, args, kwargs) 5117 5118 class C4: 5119 def __getnewargs_ex__(self): 5120 return (args, "bad dict") 5121 class C5: 5122 def __getnewargs_ex__(self): 5123 return ("bad tuple", kwargs) 5124 class C6: 5125 def __getnewargs_ex__(self): 5126 return () 5127 class C7: 5128 def __getnewargs_ex__(self): 5129 return "bad args" 5130 for proto in protocols: 5131 for cls in C4, C5, C6, C7: 5132 obj = cls() 5133 if proto >= 2: 5134 with self.assertRaises((TypeError, ValueError)): 5135 obj.__reduce_ex__(proto) 5136 5137 class C9: 5138 def __getnewargs_ex__(self): 5139 return (args, {}) 5140 obj = C9() 5141 for proto in protocols: 5142 self._check_reduce(proto, obj, args) 5143 5144 class C10: 5145 def __getnewargs_ex__(self): 5146 raise IndexError 5147 obj = C10() 5148 for proto in protocols: 5149 if proto >= 2: 5150 with self.assertRaises(IndexError): 5151 obj.__reduce_ex__(proto) 5152 5153 class C11: 5154 def __getstate__(self): 5155 return state 5156 obj = C11() 5157 for proto in protocols: 5158 self._check_reduce(proto, obj, state=state) 5159 5160 class C12: 5161 def __getstate__(self): 5162 return "not dict" 5163 obj = C12() 5164 for proto in protocols: 5165 self._check_reduce(proto, obj, state="not dict") 5166 5167 class C13: 5168 def __getstate__(self): 5169 raise IndexError 5170 obj = C13() 5171 for proto in protocols: 5172 with self.assertRaises(IndexError): 5173 obj.__reduce_ex__(proto) 5174 if proto < 2: 5175 with self.assertRaises(IndexError): 5176 obj.__reduce__() 5177 5178 class C14: 5179 __slots__ = tuple(state) 5180 def __init__(self): 5181 for name, value in state.items(): 5182 setattr(self, name, value) 5183 5184 obj = C14() 5185 for proto in protocols: 5186 if proto >= 2: 5187 self._check_reduce(proto, obj, state=(None, state)) 5188 else: 5189 with self.assertRaises(TypeError): 5190 obj.__reduce_ex__(proto) 5191 with self.assertRaises(TypeError): 5192 obj.__reduce__() 5193 5194 class C15(dict): 5195 pass 5196 obj = C15({"quebec": -601}) 5197 for proto in protocols: 5198 self._check_reduce(proto, obj, dictitems=dict(obj)) 5199 5200 class C16(list): 5201 pass 5202 obj = C16(["yukon"]) 5203 for proto in protocols: 5204 self._check_reduce(proto, obj, listitems=list(obj)) 5205 5206 def test_special_method_lookup(self): 5207 protocols = range(pickle.HIGHEST_PROTOCOL + 1) 5208 class Picky: 5209 def __getstate__(self): 5210 return {} 5211 5212 def __getattr__(self, attr): 5213 if attr in ("__getnewargs__", "__getnewargs_ex__"): 5214 raise AssertionError(attr) 5215 return None 5216 for protocol in protocols: 5217 state = {} if protocol >= 2 else None 5218 self._check_reduce(protocol, Picky(), state=state) 5219 5220 def _assert_is_copy(self, obj, objcopy, msg=None): 5221 """Utility method to verify if two objects are copies of each others. 5222 """ 5223 if msg is None: 5224 msg = "{!r} is not a copy of {!r}".format(obj, objcopy) 5225 if type(obj).__repr__ is object.__repr__: 5226 # We have this limitation for now because we use the object's repr 5227 # to help us verify that the two objects are copies. This allows 5228 # us to delegate the non-generic verification logic to the objects 5229 # themselves. 5230 raise ValueError("object passed to _assert_is_copy must " + 5231 "override the __repr__ method.") 5232 self.assertIsNot(obj, objcopy, msg=msg) 5233 self.assertIs(type(obj), type(objcopy), msg=msg) 5234 if hasattr(obj, '__dict__'): 5235 self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg) 5236 self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg) 5237 if hasattr(obj, '__slots__'): 5238 self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg) 5239 for slot in obj.__slots__: 5240 self.assertEqual( 5241 hasattr(obj, slot), hasattr(objcopy, slot), msg=msg) 5242 self.assertEqual(getattr(obj, slot, None), 5243 getattr(objcopy, slot, None), msg=msg) 5244 self.assertEqual(repr(obj), repr(objcopy), msg=msg) 5245 5246 @staticmethod 5247 def _generate_pickle_copiers(): 5248 """Utility method to generate the many possible pickle configurations. 5249 """ 5250 class PickleCopier: 5251 "This class copies object using pickle." 5252 def __init__(self, proto, dumps, loads): 5253 self.proto = proto 5254 self.dumps = dumps 5255 self.loads = loads 5256 def copy(self, obj): 5257 return self.loads(self.dumps(obj, self.proto)) 5258 def __repr__(self): 5259 # We try to be as descriptive as possible here since this is 5260 # the string which we will allow us to tell the pickle 5261 # configuration we are using during debugging. 5262 return ("PickleCopier(proto={}, dumps={}.{}, loads={}.{})" 5263 .format(self.proto, 5264 self.dumps.__module__, self.dumps.__qualname__, 5265 self.loads.__module__, self.loads.__qualname__)) 5266 return (PickleCopier(*args) for args in 5267 itertools.product(range(pickle.HIGHEST_PROTOCOL + 1), 5268 {pickle.dumps, pickle._dumps}, 5269 {pickle.loads, pickle._loads})) 5270 5271 def test_pickle_slots(self): 5272 # Tests pickling of classes with __slots__. 5273 5274 # Pickling of classes with __slots__ but without __getstate__ should 5275 # fail (if using protocol 0 or 1) 5276 global C 5277 class C: 5278 __slots__ = ['a'] 5279 with self.assertRaises(TypeError): 5280 pickle.dumps(C(), 0) 5281 5282 global D 5283 class D(C): 5284 pass 5285 with self.assertRaises(TypeError): 5286 pickle.dumps(D(), 0) 5287 5288 class C: 5289 "A class with __getstate__ and __setstate__ implemented." 5290 __slots__ = ['a'] 5291 def __getstate__(self): 5292 state = getattr(self, '__dict__', {}).copy() 5293 for cls in type(self).__mro__: 5294 for slot in cls.__dict__.get('__slots__', ()): 5295 try: 5296 state[slot] = getattr(self, slot) 5297 except AttributeError: 5298 pass 5299 return state 5300 def __setstate__(self, state): 5301 for k, v in state.items(): 5302 setattr(self, k, v) 5303 def __repr__(self): 5304 return "%s()<%r>" % (type(self).__name__, self.__getstate__()) 5305 5306 class D(C): 5307 "A subclass of a class with slots." 5308 pass 5309 5310 global E 5311 class E(C): 5312 "A subclass with an extra slot." 5313 __slots__ = ['b'] 5314 5315 # Now it should work 5316 for pickle_copier in self._generate_pickle_copiers(): 5317 with self.subTest(pickle_copier=pickle_copier): 5318 x = C() 5319 y = pickle_copier.copy(x) 5320 self._assert_is_copy(x, y) 5321 5322 x.a = 42 5323 y = pickle_copier.copy(x) 5324 self._assert_is_copy(x, y) 5325 5326 x = D() 5327 x.a = 42 5328 x.b = 100 5329 y = pickle_copier.copy(x) 5330 self._assert_is_copy(x, y) 5331 5332 x = E() 5333 x.a = 42 5334 x.b = "foo" 5335 y = pickle_copier.copy(x) 5336 self._assert_is_copy(x, y) 5337 5338 def test_reduce_copying(self): 5339 # Tests pickling and copying new-style classes and objects. 5340 global C1 5341 class C1: 5342 "The state of this class is copyable via its instance dict." 5343 ARGS = (1, 2) 5344 NEED_DICT_COPYING = True 5345 def __init__(self, a, b): 5346 super().__init__() 5347 self.a = a 5348 self.b = b 5349 def __repr__(self): 5350 return "C1(%r, %r)" % (self.a, self.b) 5351 5352 global C2 5353 class C2(list): 5354 "A list subclass copyable via __getnewargs__." 5355 ARGS = (1, 2) 5356 NEED_DICT_COPYING = False 5357 def __new__(cls, a, b): 5358 self = super().__new__(cls) 5359 self.a = a 5360 self.b = b 5361 return self 5362 def __init__(self, *args): 5363 super().__init__() 5364 # This helps testing that __init__ is not called during the 5365 # unpickling process, which would cause extra appends. 5366 self.append("cheese") 5367 @classmethod 5368 def __getnewargs__(cls): 5369 return cls.ARGS 5370 def __repr__(self): 5371 return "C2(%r, %r)<%r>" % (self.a, self.b, list(self)) 5372 5373 global C3 5374 class C3(list): 5375 "A list subclass copyable via __getstate__." 5376 ARGS = (1, 2) 5377 NEED_DICT_COPYING = False 5378 def __init__(self, a, b): 5379 self.a = a 5380 self.b = b 5381 # This helps testing that __init__ is not called during the 5382 # unpickling process, which would cause extra appends. 5383 self.append("cheese") 5384 @classmethod 5385 def __getstate__(cls): 5386 return cls.ARGS 5387 def __setstate__(self, state): 5388 a, b = state 5389 self.a = a 5390 self.b = b 5391 def __repr__(self): 5392 return "C3(%r, %r)<%r>" % (self.a, self.b, list(self)) 5393 5394 global C4 5395 class C4(int): 5396 "An int subclass copyable via __getnewargs__." 5397 ARGS = ("hello", "world", 1) 5398 NEED_DICT_COPYING = False 5399 def __new__(cls, a, b, value): 5400 self = super().__new__(cls, value) 5401 self.a = a 5402 self.b = b 5403 return self 5404 @classmethod 5405 def __getnewargs__(cls): 5406 return cls.ARGS 5407 def __repr__(self): 5408 return "C4(%r, %r)<%r>" % (self.a, self.b, int(self)) 5409 5410 global C5 5411 class C5(int): 5412 "An int subclass copyable via __getnewargs_ex__." 5413 ARGS = (1, 2) 5414 KWARGS = {'value': 3} 5415 NEED_DICT_COPYING = False 5416 def __new__(cls, a, b, *, value=0): 5417 self = super().__new__(cls, value) 5418 self.a = a 5419 self.b = b 5420 return self 5421 @classmethod 5422 def __getnewargs_ex__(cls): 5423 return (cls.ARGS, cls.KWARGS) 5424 def __repr__(self): 5425 return "C5(%r, %r)<%r>" % (self.a, self.b, int(self)) 5426 5427 test_classes = (C1, C2, C3, C4, C5) 5428 # Testing copying through pickle 5429 pickle_copiers = self._generate_pickle_copiers() 5430 for cls, pickle_copier in itertools.product(test_classes, pickle_copiers): 5431 with self.subTest(cls=cls, pickle_copier=pickle_copier): 5432 kwargs = getattr(cls, 'KWARGS', {}) 5433 obj = cls(*cls.ARGS, **kwargs) 5434 proto = pickle_copier.proto 5435 objcopy = pickle_copier.copy(obj) 5436 self._assert_is_copy(obj, objcopy) 5437 # For test classes that supports this, make sure we didn't go 5438 # around the reduce protocol by simply copying the attribute 5439 # dictionary. We clear attributes using the previous copy to 5440 # not mutate the original argument. 5441 if proto >= 2 and not cls.NEED_DICT_COPYING: 5442 objcopy.__dict__.clear() 5443 objcopy2 = pickle_copier.copy(objcopy) 5444 self._assert_is_copy(obj, objcopy2) 5445 5446 # Testing copying through copy.deepcopy() 5447 for cls in test_classes: 5448 with self.subTest(cls=cls): 5449 kwargs = getattr(cls, 'KWARGS', {}) 5450 obj = cls(*cls.ARGS, **kwargs) 5451 objcopy = deepcopy(obj) 5452 self._assert_is_copy(obj, objcopy) 5453 # For test classes that supports this, make sure we didn't go 5454 # around the reduce protocol by simply copying the attribute 5455 # dictionary. We clear attributes using the previous copy to 5456 # not mutate the original argument. 5457 if not cls.NEED_DICT_COPYING: 5458 objcopy.__dict__.clear() 5459 objcopy2 = deepcopy(objcopy) 5460 self._assert_is_copy(obj, objcopy2) 5461 5462 def test_issue24097(self): 5463 # Slot name is freed inside __getattr__ and is later used. 5464 class S(str): # Not interned 5465 pass 5466 class A: 5467 __slotnames__ = [S('spam')] 5468 def __getattr__(self, attr): 5469 if attr == 'spam': 5470 A.__slotnames__[:] = [S('spam')] 5471 return 42 5472 else: 5473 raise AttributeError 5474 5475 import copyreg 5476 expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None) 5477 self.assertEqual(A().__reduce_ex__(2), expected) # Shouldn't crash 5478 5479 def test_object_reduce(self): 5480 # Issue #29914 5481 # __reduce__() takes no arguments 5482 object().__reduce__() 5483 with self.assertRaises(TypeError): 5484 object().__reduce__(0) 5485 # __reduce_ex__() takes one integer argument 5486 object().__reduce_ex__(0) 5487 with self.assertRaises(TypeError): 5488 object().__reduce_ex__() 5489 with self.assertRaises(TypeError): 5490 object().__reduce_ex__(None) 5491 5492 5493class SharedKeyTests(unittest.TestCase): 5494 5495 @support.cpython_only 5496 def test_subclasses(self): 5497 # Verify that subclasses can share keys (per PEP 412) 5498 class A: 5499 pass 5500 class B(A): 5501 pass 5502 5503 a, b = A(), B() 5504 self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) 5505 self.assertLess(sys.getsizeof(vars(a)), sys.getsizeof({"a":1})) 5506 # Initial hash table can contain at most 5 elements. 5507 # Set 6 attributes to cause internal resizing. 5508 a.x, a.y, a.z, a.w, a.v, a.u = range(6) 5509 self.assertNotEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) 5510 a2 = A() 5511 self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(a2))) 5512 self.assertLess(sys.getsizeof(vars(a)), sys.getsizeof({"a":1})) 5513 b.u, b.v, b.w, b.t, b.s, b.r = range(6) 5514 self.assertLess(sys.getsizeof(vars(b)), sys.getsizeof({"a":1})) 5515 5516 5517class DebugHelperMeta(type): 5518 """ 5519 Sets default __doc__ and simplifies repr() output. 5520 """ 5521 def __new__(mcls, name, bases, attrs): 5522 if attrs.get('__doc__') is None: 5523 attrs['__doc__'] = name # helps when debugging with gdb 5524 return type.__new__(mcls, name, bases, attrs) 5525 def __repr__(cls): 5526 return repr(cls.__name__) 5527 5528 5529class MroTest(unittest.TestCase): 5530 """ 5531 Regressions for some bugs revealed through 5532 mcsl.mro() customization (typeobject.c: mro_internal()) and 5533 cls.__bases__ assignment (typeobject.c: type_set_bases()). 5534 """ 5535 5536 def setUp(self): 5537 self.step = 0 5538 self.ready = False 5539 5540 def step_until(self, limit): 5541 ret = (self.step < limit) 5542 if ret: 5543 self.step += 1 5544 return ret 5545 5546 def test_incomplete_set_bases_on_self(self): 5547 """ 5548 type_set_bases must be aware that type->tp_mro can be NULL. 5549 """ 5550 class M(DebugHelperMeta): 5551 def mro(cls): 5552 if self.step_until(1): 5553 assert cls.__mro__ is None 5554 cls.__bases__ += () 5555 5556 return type.mro(cls) 5557 5558 class A(metaclass=M): 5559 pass 5560 5561 def test_reent_set_bases_on_base(self): 5562 """ 5563 Deep reentrancy must not over-decref old_mro. 5564 """ 5565 class M(DebugHelperMeta): 5566 def mro(cls): 5567 if cls.__mro__ is not None and cls.__name__ == 'B': 5568 # 4-5 steps are usually enough to make it crash somewhere 5569 if self.step_until(10): 5570 A.__bases__ += () 5571 5572 return type.mro(cls) 5573 5574 class A(metaclass=M): 5575 pass 5576 class B(A): 5577 pass 5578 B.__bases__ += () 5579 5580 def test_reent_set_bases_on_direct_base(self): 5581 """ 5582 Similar to test_reent_set_bases_on_base, but may crash differently. 5583 """ 5584 class M(DebugHelperMeta): 5585 def mro(cls): 5586 base = cls.__bases__[0] 5587 if base is not object: 5588 if self.step_until(5): 5589 base.__bases__ += () 5590 5591 return type.mro(cls) 5592 5593 class A(metaclass=M): 5594 pass 5595 class B(A): 5596 pass 5597 class C(B): 5598 pass 5599 5600 def test_reent_set_bases_tp_base_cycle(self): 5601 """ 5602 type_set_bases must check for an inheritance cycle not only through 5603 MRO of the type, which may be not yet updated in case of reentrance, 5604 but also through tp_base chain, which is assigned before diving into 5605 inner calls to mro(). 5606 5607 Otherwise, the following snippet can loop forever: 5608 do { 5609 // ... 5610 type = type->tp_base; 5611 } while (type != NULL); 5612 5613 Functions that rely on tp_base (like solid_base and PyType_IsSubtype) 5614 would not be happy in that case, causing a stack overflow. 5615 """ 5616 class M(DebugHelperMeta): 5617 def mro(cls): 5618 if self.ready: 5619 if cls.__name__ == 'B1': 5620 B2.__bases__ = (B1,) 5621 if cls.__name__ == 'B2': 5622 B1.__bases__ = (B2,) 5623 return type.mro(cls) 5624 5625 class A(metaclass=M): 5626 pass 5627 class B1(A): 5628 pass 5629 class B2(A): 5630 pass 5631 5632 self.ready = True 5633 with self.assertRaises(TypeError): 5634 B1.__bases__ += () 5635 5636 def test_tp_subclasses_cycle_in_update_slots(self): 5637 """ 5638 type_set_bases must check for reentrancy upon finishing its job 5639 by updating tp_subclasses of old/new bases of the type. 5640 Otherwise, an implicit inheritance cycle through tp_subclasses 5641 can break functions that recurse on elements of that field 5642 (like recurse_down_subclasses and mro_hierarchy) eventually 5643 leading to a stack overflow. 5644 """ 5645 class M(DebugHelperMeta): 5646 def mro(cls): 5647 if self.ready and cls.__name__ == 'C': 5648 self.ready = False 5649 C.__bases__ = (B2,) 5650 return type.mro(cls) 5651 5652 class A(metaclass=M): 5653 pass 5654 class B1(A): 5655 pass 5656 class B2(A): 5657 pass 5658 class C(A): 5659 pass 5660 5661 self.ready = True 5662 C.__bases__ = (B1,) 5663 B1.__bases__ = (C,) 5664 5665 self.assertEqual(C.__bases__, (B2,)) 5666 self.assertEqual(B2.__subclasses__(), [C]) 5667 self.assertEqual(B1.__subclasses__(), []) 5668 5669 self.assertEqual(B1.__bases__, (C,)) 5670 self.assertEqual(C.__subclasses__(), [B1]) 5671 5672 def test_tp_subclasses_cycle_error_return_path(self): 5673 """ 5674 The same as test_tp_subclasses_cycle_in_update_slots, but tests 5675 a code path executed on error (goto bail). 5676 """ 5677 class E(Exception): 5678 pass 5679 class M(DebugHelperMeta): 5680 def mro(cls): 5681 if self.ready and cls.__name__ == 'C': 5682 if C.__bases__ == (B2,): 5683 self.ready = False 5684 else: 5685 C.__bases__ = (B2,) 5686 raise E 5687 return type.mro(cls) 5688 5689 class A(metaclass=M): 5690 pass 5691 class B1(A): 5692 pass 5693 class B2(A): 5694 pass 5695 class C(A): 5696 pass 5697 5698 self.ready = True 5699 with self.assertRaises(E): 5700 C.__bases__ = (B1,) 5701 B1.__bases__ = (C,) 5702 5703 self.assertEqual(C.__bases__, (B2,)) 5704 self.assertEqual(C.__mro__, tuple(type.mro(C))) 5705 5706 def test_incomplete_extend(self): 5707 """ 5708 Extending an unitialized type with type->tp_mro == NULL must 5709 throw a reasonable TypeError exception, instead of failing 5710 with PyErr_BadInternalCall. 5711 """ 5712 class M(DebugHelperMeta): 5713 def mro(cls): 5714 if cls.__mro__ is None and cls.__name__ != 'X': 5715 with self.assertRaises(TypeError): 5716 class X(cls): 5717 pass 5718 5719 return type.mro(cls) 5720 5721 class A(metaclass=M): 5722 pass 5723 5724 def test_incomplete_super(self): 5725 """ 5726 Attribute lookup on a super object must be aware that 5727 its target type can be uninitialized (type->tp_mro == NULL). 5728 """ 5729 class M(DebugHelperMeta): 5730 def mro(cls): 5731 if cls.__mro__ is None: 5732 with self.assertRaises(AttributeError): 5733 super(cls, cls).xxx 5734 5735 return type.mro(cls) 5736 5737 class A(metaclass=M): 5738 pass 5739 5740 5741if __name__ == "__main__": 5742 unittest.main() 5743