17db96d56Sopenharmony_ciimport builtins 27db96d56Sopenharmony_ciimport copyreg 37db96d56Sopenharmony_ciimport gc 47db96d56Sopenharmony_ciimport itertools 57db96d56Sopenharmony_ciimport math 67db96d56Sopenharmony_ciimport pickle 77db96d56Sopenharmony_ciimport random 87db96d56Sopenharmony_ciimport string 97db96d56Sopenharmony_ciimport sys 107db96d56Sopenharmony_ciimport types 117db96d56Sopenharmony_ciimport unittest 127db96d56Sopenharmony_ciimport warnings 137db96d56Sopenharmony_ciimport weakref 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_cifrom copy import deepcopy 167db96d56Sopenharmony_cifrom contextlib import redirect_stdout 177db96d56Sopenharmony_cifrom test import support 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_citry: 207db96d56Sopenharmony_ci import _testcapi 217db96d56Sopenharmony_ciexcept ImportError: 227db96d56Sopenharmony_ci _testcapi = None 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ciclass OperatorsTest(unittest.TestCase): 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci def __init__(self, *args, **kwargs): 287db96d56Sopenharmony_ci unittest.TestCase.__init__(self, *args, **kwargs) 297db96d56Sopenharmony_ci self.binops = { 307db96d56Sopenharmony_ci 'add': '+', 317db96d56Sopenharmony_ci 'sub': '-', 327db96d56Sopenharmony_ci 'mul': '*', 337db96d56Sopenharmony_ci 'matmul': '@', 347db96d56Sopenharmony_ci 'truediv': '/', 357db96d56Sopenharmony_ci 'floordiv': '//', 367db96d56Sopenharmony_ci 'divmod': 'divmod', 377db96d56Sopenharmony_ci 'pow': '**', 387db96d56Sopenharmony_ci 'lshift': '<<', 397db96d56Sopenharmony_ci 'rshift': '>>', 407db96d56Sopenharmony_ci 'and': '&', 417db96d56Sopenharmony_ci 'xor': '^', 427db96d56Sopenharmony_ci 'or': '|', 437db96d56Sopenharmony_ci 'cmp': 'cmp', 447db96d56Sopenharmony_ci 'lt': '<', 457db96d56Sopenharmony_ci 'le': '<=', 467db96d56Sopenharmony_ci 'eq': '==', 477db96d56Sopenharmony_ci 'ne': '!=', 487db96d56Sopenharmony_ci 'gt': '>', 497db96d56Sopenharmony_ci 'ge': '>=', 507db96d56Sopenharmony_ci } 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci for name, expr in list(self.binops.items()): 537db96d56Sopenharmony_ci if expr.islower(): 547db96d56Sopenharmony_ci expr = expr + "(a, b)" 557db96d56Sopenharmony_ci else: 567db96d56Sopenharmony_ci expr = 'a %s b' % expr 577db96d56Sopenharmony_ci self.binops[name] = expr 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci self.unops = { 607db96d56Sopenharmony_ci 'pos': '+', 617db96d56Sopenharmony_ci 'neg': '-', 627db96d56Sopenharmony_ci 'abs': 'abs', 637db96d56Sopenharmony_ci 'invert': '~', 647db96d56Sopenharmony_ci 'int': 'int', 657db96d56Sopenharmony_ci 'float': 'float', 667db96d56Sopenharmony_ci } 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ci for name, expr in list(self.unops.items()): 697db96d56Sopenharmony_ci if expr.islower(): 707db96d56Sopenharmony_ci expr = expr + "(a)" 717db96d56Sopenharmony_ci else: 727db96d56Sopenharmony_ci expr = '%s a' % expr 737db96d56Sopenharmony_ci self.unops[name] = expr 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci def unop_test(self, a, res, expr="len(a)", meth="__len__"): 767db96d56Sopenharmony_ci d = {'a': a} 777db96d56Sopenharmony_ci self.assertEqual(eval(expr, d), res) 787db96d56Sopenharmony_ci t = type(a) 797db96d56Sopenharmony_ci m = getattr(t, meth) 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci # Find method in parent class 827db96d56Sopenharmony_ci while meth not in t.__dict__: 837db96d56Sopenharmony_ci t = t.__bases__[0] 847db96d56Sopenharmony_ci # in some implementations (e.g. PyPy), 'm' can be a regular unbound 857db96d56Sopenharmony_ci # method object; the getattr() below obtains its underlying function. 867db96d56Sopenharmony_ci self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 877db96d56Sopenharmony_ci self.assertEqual(m(a), res) 887db96d56Sopenharmony_ci bm = getattr(a, meth) 897db96d56Sopenharmony_ci self.assertEqual(bm(), res) 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci def binop_test(self, a, b, res, expr="a+b", meth="__add__"): 927db96d56Sopenharmony_ci d = {'a': a, 'b': b} 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci self.assertEqual(eval(expr, d), res) 957db96d56Sopenharmony_ci t = type(a) 967db96d56Sopenharmony_ci m = getattr(t, meth) 977db96d56Sopenharmony_ci while meth not in t.__dict__: 987db96d56Sopenharmony_ci t = t.__bases__[0] 997db96d56Sopenharmony_ci # in some implementations (e.g. PyPy), 'm' can be a regular unbound 1007db96d56Sopenharmony_ci # method object; the getattr() below obtains its underlying function. 1017db96d56Sopenharmony_ci self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 1027db96d56Sopenharmony_ci self.assertEqual(m(a, b), res) 1037db96d56Sopenharmony_ci bm = getattr(a, meth) 1047db96d56Sopenharmony_ci self.assertEqual(bm(b), res) 1057db96d56Sopenharmony_ci 1067db96d56Sopenharmony_ci def sliceop_test(self, a, b, c, res, expr="a[b:c]", meth="__getitem__"): 1077db96d56Sopenharmony_ci d = {'a': a, 'b': b, 'c': c} 1087db96d56Sopenharmony_ci self.assertEqual(eval(expr, d), res) 1097db96d56Sopenharmony_ci t = type(a) 1107db96d56Sopenharmony_ci m = getattr(t, meth) 1117db96d56Sopenharmony_ci while meth not in t.__dict__: 1127db96d56Sopenharmony_ci t = t.__bases__[0] 1137db96d56Sopenharmony_ci # in some implementations (e.g. PyPy), 'm' can be a regular unbound 1147db96d56Sopenharmony_ci # method object; the getattr() below obtains its underlying function. 1157db96d56Sopenharmony_ci self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 1167db96d56Sopenharmony_ci self.assertEqual(m(a, slice(b, c)), res) 1177db96d56Sopenharmony_ci bm = getattr(a, meth) 1187db96d56Sopenharmony_ci self.assertEqual(bm(slice(b, c)), res) 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci def setop_test(self, a, b, res, stmt="a+=b", meth="__iadd__"): 1217db96d56Sopenharmony_ci d = {'a': deepcopy(a), 'b': b} 1227db96d56Sopenharmony_ci exec(stmt, d) 1237db96d56Sopenharmony_ci self.assertEqual(d['a'], res) 1247db96d56Sopenharmony_ci t = type(a) 1257db96d56Sopenharmony_ci m = getattr(t, meth) 1267db96d56Sopenharmony_ci while meth not in t.__dict__: 1277db96d56Sopenharmony_ci t = t.__bases__[0] 1287db96d56Sopenharmony_ci # in some implementations (e.g. PyPy), 'm' can be a regular unbound 1297db96d56Sopenharmony_ci # method object; the getattr() below obtains its underlying function. 1307db96d56Sopenharmony_ci self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 1317db96d56Sopenharmony_ci d['a'] = deepcopy(a) 1327db96d56Sopenharmony_ci m(d['a'], b) 1337db96d56Sopenharmony_ci self.assertEqual(d['a'], res) 1347db96d56Sopenharmony_ci d['a'] = deepcopy(a) 1357db96d56Sopenharmony_ci bm = getattr(d['a'], meth) 1367db96d56Sopenharmony_ci bm(b) 1377db96d56Sopenharmony_ci self.assertEqual(d['a'], res) 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci def set2op_test(self, a, b, c, res, stmt="a[b]=c", meth="__setitem__"): 1407db96d56Sopenharmony_ci d = {'a': deepcopy(a), 'b': b, 'c': c} 1417db96d56Sopenharmony_ci exec(stmt, d) 1427db96d56Sopenharmony_ci self.assertEqual(d['a'], res) 1437db96d56Sopenharmony_ci t = type(a) 1447db96d56Sopenharmony_ci m = getattr(t, meth) 1457db96d56Sopenharmony_ci while meth not in t.__dict__: 1467db96d56Sopenharmony_ci t = t.__bases__[0] 1477db96d56Sopenharmony_ci # in some implementations (e.g. PyPy), 'm' can be a regular unbound 1487db96d56Sopenharmony_ci # method object; the getattr() below obtains its underlying function. 1497db96d56Sopenharmony_ci self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 1507db96d56Sopenharmony_ci d['a'] = deepcopy(a) 1517db96d56Sopenharmony_ci m(d['a'], b, c) 1527db96d56Sopenharmony_ci self.assertEqual(d['a'], res) 1537db96d56Sopenharmony_ci d['a'] = deepcopy(a) 1547db96d56Sopenharmony_ci bm = getattr(d['a'], meth) 1557db96d56Sopenharmony_ci bm(b, c) 1567db96d56Sopenharmony_ci self.assertEqual(d['a'], res) 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_ci def setsliceop_test(self, a, b, c, d, res, stmt="a[b:c]=d", meth="__setitem__"): 1597db96d56Sopenharmony_ci dictionary = {'a': deepcopy(a), 'b': b, 'c': c, 'd': d} 1607db96d56Sopenharmony_ci exec(stmt, dictionary) 1617db96d56Sopenharmony_ci self.assertEqual(dictionary['a'], res) 1627db96d56Sopenharmony_ci t = type(a) 1637db96d56Sopenharmony_ci while meth not in t.__dict__: 1647db96d56Sopenharmony_ci t = t.__bases__[0] 1657db96d56Sopenharmony_ci m = getattr(t, meth) 1667db96d56Sopenharmony_ci # in some implementations (e.g. PyPy), 'm' can be a regular unbound 1677db96d56Sopenharmony_ci # method object; the getattr() below obtains its underlying function. 1687db96d56Sopenharmony_ci self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) 1697db96d56Sopenharmony_ci dictionary['a'] = deepcopy(a) 1707db96d56Sopenharmony_ci m(dictionary['a'], slice(b, c), d) 1717db96d56Sopenharmony_ci self.assertEqual(dictionary['a'], res) 1727db96d56Sopenharmony_ci dictionary['a'] = deepcopy(a) 1737db96d56Sopenharmony_ci bm = getattr(dictionary['a'], meth) 1747db96d56Sopenharmony_ci bm(slice(b, c), d) 1757db96d56Sopenharmony_ci self.assertEqual(dictionary['a'], res) 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci def test_lists(self): 1787db96d56Sopenharmony_ci # Testing list operations... 1797db96d56Sopenharmony_ci # Asserts are within individual test methods 1807db96d56Sopenharmony_ci self.binop_test([1], [2], [1,2], "a+b", "__add__") 1817db96d56Sopenharmony_ci self.binop_test([1,2,3], 2, 1, "b in a", "__contains__") 1827db96d56Sopenharmony_ci self.binop_test([1,2,3], 4, 0, "b in a", "__contains__") 1837db96d56Sopenharmony_ci self.binop_test([1,2,3], 1, 2, "a[b]", "__getitem__") 1847db96d56Sopenharmony_ci self.sliceop_test([1,2,3], 0, 2, [1,2], "a[b:c]", "__getitem__") 1857db96d56Sopenharmony_ci self.setop_test([1], [2], [1,2], "a+=b", "__iadd__") 1867db96d56Sopenharmony_ci self.setop_test([1,2], 3, [1,2,1,2,1,2], "a*=b", "__imul__") 1877db96d56Sopenharmony_ci self.unop_test([1,2,3], 3, "len(a)", "__len__") 1887db96d56Sopenharmony_ci self.binop_test([1,2], 3, [1,2,1,2,1,2], "a*b", "__mul__") 1897db96d56Sopenharmony_ci self.binop_test([1,2], 3, [1,2,1,2,1,2], "b*a", "__rmul__") 1907db96d56Sopenharmony_ci self.set2op_test([1,2], 1, 3, [1,3], "a[b]=c", "__setitem__") 1917db96d56Sopenharmony_ci self.setsliceop_test([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d", 1927db96d56Sopenharmony_ci "__setitem__") 1937db96d56Sopenharmony_ci 1947db96d56Sopenharmony_ci def test_dicts(self): 1957db96d56Sopenharmony_ci # Testing dict operations... 1967db96d56Sopenharmony_ci self.binop_test({1:2,3:4}, 1, 1, "b in a", "__contains__") 1977db96d56Sopenharmony_ci self.binop_test({1:2,3:4}, 2, 0, "b in a", "__contains__") 1987db96d56Sopenharmony_ci self.binop_test({1:2,3:4}, 1, 2, "a[b]", "__getitem__") 1997db96d56Sopenharmony_ci 2007db96d56Sopenharmony_ci d = {1:2, 3:4} 2017db96d56Sopenharmony_ci l1 = [] 2027db96d56Sopenharmony_ci for i in list(d.keys()): 2037db96d56Sopenharmony_ci l1.append(i) 2047db96d56Sopenharmony_ci l = [] 2057db96d56Sopenharmony_ci for i in iter(d): 2067db96d56Sopenharmony_ci l.append(i) 2077db96d56Sopenharmony_ci self.assertEqual(l, l1) 2087db96d56Sopenharmony_ci l = [] 2097db96d56Sopenharmony_ci for i in d.__iter__(): 2107db96d56Sopenharmony_ci l.append(i) 2117db96d56Sopenharmony_ci self.assertEqual(l, l1) 2127db96d56Sopenharmony_ci l = [] 2137db96d56Sopenharmony_ci for i in dict.__iter__(d): 2147db96d56Sopenharmony_ci l.append(i) 2157db96d56Sopenharmony_ci self.assertEqual(l, l1) 2167db96d56Sopenharmony_ci d = {1:2, 3:4} 2177db96d56Sopenharmony_ci self.unop_test(d, 2, "len(a)", "__len__") 2187db96d56Sopenharmony_ci self.assertEqual(eval(repr(d), {}), d) 2197db96d56Sopenharmony_ci self.assertEqual(eval(d.__repr__(), {}), d) 2207db96d56Sopenharmony_ci self.set2op_test({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", 2217db96d56Sopenharmony_ci "__setitem__") 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ci # Tests for unary and binary operators 2247db96d56Sopenharmony_ci def number_operators(self, a, b, skip=[]): 2257db96d56Sopenharmony_ci dict = {'a': a, 'b': b} 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ci for name, expr in self.binops.items(): 2287db96d56Sopenharmony_ci if name not in skip: 2297db96d56Sopenharmony_ci name = "__%s__" % name 2307db96d56Sopenharmony_ci if hasattr(a, name): 2317db96d56Sopenharmony_ci res = eval(expr, dict) 2327db96d56Sopenharmony_ci self.binop_test(a, b, res, expr, name) 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ci for name, expr in list(self.unops.items()): 2357db96d56Sopenharmony_ci if name not in skip: 2367db96d56Sopenharmony_ci name = "__%s__" % name 2377db96d56Sopenharmony_ci if hasattr(a, name): 2387db96d56Sopenharmony_ci res = eval(expr, dict) 2397db96d56Sopenharmony_ci self.unop_test(a, res, expr, name) 2407db96d56Sopenharmony_ci 2417db96d56Sopenharmony_ci def test_ints(self): 2427db96d56Sopenharmony_ci # Testing int operations... 2437db96d56Sopenharmony_ci self.number_operators(100, 3) 2447db96d56Sopenharmony_ci # The following crashes in Python 2.2 2457db96d56Sopenharmony_ci self.assertEqual((1).__bool__(), 1) 2467db96d56Sopenharmony_ci self.assertEqual((0).__bool__(), 0) 2477db96d56Sopenharmony_ci # This returns 'NotImplemented' in Python 2.2 2487db96d56Sopenharmony_ci class C(int): 2497db96d56Sopenharmony_ci def __add__(self, other): 2507db96d56Sopenharmony_ci return NotImplemented 2517db96d56Sopenharmony_ci self.assertEqual(C(5), 5) 2527db96d56Sopenharmony_ci try: 2537db96d56Sopenharmony_ci C() + "" 2547db96d56Sopenharmony_ci except TypeError: 2557db96d56Sopenharmony_ci pass 2567db96d56Sopenharmony_ci else: 2577db96d56Sopenharmony_ci self.fail("NotImplemented should have caused TypeError") 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci def test_floats(self): 2607db96d56Sopenharmony_ci # Testing float operations... 2617db96d56Sopenharmony_ci self.number_operators(100.0, 3.0) 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ci def test_complexes(self): 2647db96d56Sopenharmony_ci # Testing complex operations... 2657db96d56Sopenharmony_ci self.number_operators(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge', 2667db96d56Sopenharmony_ci 'int', 'float', 2677db96d56Sopenharmony_ci 'floordiv', 'divmod', 'mod']) 2687db96d56Sopenharmony_ci 2697db96d56Sopenharmony_ci class Number(complex): 2707db96d56Sopenharmony_ci __slots__ = ['prec'] 2717db96d56Sopenharmony_ci def __new__(cls, *args, **kwds): 2727db96d56Sopenharmony_ci result = complex.__new__(cls, *args) 2737db96d56Sopenharmony_ci result.prec = kwds.get('prec', 12) 2747db96d56Sopenharmony_ci return result 2757db96d56Sopenharmony_ci def __repr__(self): 2767db96d56Sopenharmony_ci prec = self.prec 2777db96d56Sopenharmony_ci if self.imag == 0.0: 2787db96d56Sopenharmony_ci return "%.*g" % (prec, self.real) 2797db96d56Sopenharmony_ci if self.real == 0.0: 2807db96d56Sopenharmony_ci return "%.*gj" % (prec, self.imag) 2817db96d56Sopenharmony_ci return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag) 2827db96d56Sopenharmony_ci __str__ = __repr__ 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ci a = Number(3.14, prec=6) 2857db96d56Sopenharmony_ci self.assertEqual(repr(a), "3.14") 2867db96d56Sopenharmony_ci self.assertEqual(a.prec, 6) 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci a = Number(a, prec=2) 2897db96d56Sopenharmony_ci self.assertEqual(repr(a), "3.1") 2907db96d56Sopenharmony_ci self.assertEqual(a.prec, 2) 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci a = Number(234.5) 2937db96d56Sopenharmony_ci self.assertEqual(repr(a), "234.5") 2947db96d56Sopenharmony_ci self.assertEqual(a.prec, 12) 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci def test_explicit_reverse_methods(self): 2977db96d56Sopenharmony_ci # see issue 9930 2987db96d56Sopenharmony_ci self.assertEqual(complex.__radd__(3j, 4.0), complex(4.0, 3.0)) 2997db96d56Sopenharmony_ci self.assertEqual(float.__rsub__(3.0, 1), -2.0) 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_ci @support.impl_detail("the module 'xxsubtype' is internal") 3027db96d56Sopenharmony_ci def test_spam_lists(self): 3037db96d56Sopenharmony_ci # Testing spamlist operations... 3047db96d56Sopenharmony_ci import copy, xxsubtype as spam 3057db96d56Sopenharmony_ci 3067db96d56Sopenharmony_ci def spamlist(l, memo=None): 3077db96d56Sopenharmony_ci import xxsubtype as spam 3087db96d56Sopenharmony_ci return spam.spamlist(l) 3097db96d56Sopenharmony_ci 3107db96d56Sopenharmony_ci # This is an ugly hack: 3117db96d56Sopenharmony_ci copy._deepcopy_dispatch[spam.spamlist] = spamlist 3127db96d56Sopenharmony_ci 3137db96d56Sopenharmony_ci self.binop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b", 3147db96d56Sopenharmony_ci "__add__") 3157db96d56Sopenharmony_ci self.binop_test(spamlist([1,2,3]), 2, 1, "b in a", "__contains__") 3167db96d56Sopenharmony_ci self.binop_test(spamlist([1,2,3]), 4, 0, "b in a", "__contains__") 3177db96d56Sopenharmony_ci self.binop_test(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__") 3187db96d56Sopenharmony_ci self.sliceop_test(spamlist([1,2,3]), 0, 2, spamlist([1,2]), "a[b:c]", 3197db96d56Sopenharmony_ci "__getitem__") 3207db96d56Sopenharmony_ci self.setop_test(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+=b", 3217db96d56Sopenharmony_ci "__iadd__") 3227db96d56Sopenharmony_ci self.setop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b", 3237db96d56Sopenharmony_ci "__imul__") 3247db96d56Sopenharmony_ci self.unop_test(spamlist([1,2,3]), 3, "len(a)", "__len__") 3257db96d56Sopenharmony_ci self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b", 3267db96d56Sopenharmony_ci "__mul__") 3277db96d56Sopenharmony_ci self.binop_test(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a", 3287db96d56Sopenharmony_ci "__rmul__") 3297db96d56Sopenharmony_ci self.set2op_test(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c", 3307db96d56Sopenharmony_ci "__setitem__") 3317db96d56Sopenharmony_ci self.setsliceop_test(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]), 3327db96d56Sopenharmony_ci spamlist([1,5,6,4]), "a[b:c]=d", "__setitem__") 3337db96d56Sopenharmony_ci # Test subclassing 3347db96d56Sopenharmony_ci class C(spam.spamlist): 3357db96d56Sopenharmony_ci def foo(self): return 1 3367db96d56Sopenharmony_ci a = C() 3377db96d56Sopenharmony_ci self.assertEqual(a, []) 3387db96d56Sopenharmony_ci self.assertEqual(a.foo(), 1) 3397db96d56Sopenharmony_ci a.append(100) 3407db96d56Sopenharmony_ci self.assertEqual(a, [100]) 3417db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 0) 3427db96d56Sopenharmony_ci a.setstate(42) 3437db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 42) 3447db96d56Sopenharmony_ci 3457db96d56Sopenharmony_ci @support.impl_detail("the module 'xxsubtype' is internal") 3467db96d56Sopenharmony_ci def test_spam_dicts(self): 3477db96d56Sopenharmony_ci # Testing spamdict operations... 3487db96d56Sopenharmony_ci import copy, xxsubtype as spam 3497db96d56Sopenharmony_ci def spamdict(d, memo=None): 3507db96d56Sopenharmony_ci import xxsubtype as spam 3517db96d56Sopenharmony_ci sd = spam.spamdict() 3527db96d56Sopenharmony_ci for k, v in list(d.items()): 3537db96d56Sopenharmony_ci sd[k] = v 3547db96d56Sopenharmony_ci return sd 3557db96d56Sopenharmony_ci # This is an ugly hack: 3567db96d56Sopenharmony_ci copy._deepcopy_dispatch[spam.spamdict] = spamdict 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_ci self.binop_test(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__") 3597db96d56Sopenharmony_ci self.binop_test(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__") 3607db96d56Sopenharmony_ci self.binop_test(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__") 3617db96d56Sopenharmony_ci d = spamdict({1:2,3:4}) 3627db96d56Sopenharmony_ci l1 = [] 3637db96d56Sopenharmony_ci for i in list(d.keys()): 3647db96d56Sopenharmony_ci l1.append(i) 3657db96d56Sopenharmony_ci l = [] 3667db96d56Sopenharmony_ci for i in iter(d): 3677db96d56Sopenharmony_ci l.append(i) 3687db96d56Sopenharmony_ci self.assertEqual(l, l1) 3697db96d56Sopenharmony_ci l = [] 3707db96d56Sopenharmony_ci for i in d.__iter__(): 3717db96d56Sopenharmony_ci l.append(i) 3727db96d56Sopenharmony_ci self.assertEqual(l, l1) 3737db96d56Sopenharmony_ci l = [] 3747db96d56Sopenharmony_ci for i in type(spamdict({})).__iter__(d): 3757db96d56Sopenharmony_ci l.append(i) 3767db96d56Sopenharmony_ci self.assertEqual(l, l1) 3777db96d56Sopenharmony_ci straightd = {1:2, 3:4} 3787db96d56Sopenharmony_ci spamd = spamdict(straightd) 3797db96d56Sopenharmony_ci self.unop_test(spamd, 2, "len(a)", "__len__") 3807db96d56Sopenharmony_ci self.unop_test(spamd, repr(straightd), "repr(a)", "__repr__") 3817db96d56Sopenharmony_ci self.set2op_test(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}), 3827db96d56Sopenharmony_ci "a[b]=c", "__setitem__") 3837db96d56Sopenharmony_ci # Test subclassing 3847db96d56Sopenharmony_ci class C(spam.spamdict): 3857db96d56Sopenharmony_ci def foo(self): return 1 3867db96d56Sopenharmony_ci a = C() 3877db96d56Sopenharmony_ci self.assertEqual(list(a.items()), []) 3887db96d56Sopenharmony_ci self.assertEqual(a.foo(), 1) 3897db96d56Sopenharmony_ci a['foo'] = 'bar' 3907db96d56Sopenharmony_ci self.assertEqual(list(a.items()), [('foo', 'bar')]) 3917db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 0) 3927db96d56Sopenharmony_ci a.setstate(100) 3937db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 100) 3947db96d56Sopenharmony_ci 3957db96d56Sopenharmony_ci def test_wrap_lenfunc_bad_cast(self): 3967db96d56Sopenharmony_ci self.assertEqual(range(sys.maxsize).__len__(), sys.maxsize) 3977db96d56Sopenharmony_ci 3987db96d56Sopenharmony_ci 3997db96d56Sopenharmony_ciclass ClassPropertiesAndMethods(unittest.TestCase): 4007db96d56Sopenharmony_ci 4017db96d56Sopenharmony_ci def assertHasAttr(self, obj, name): 4027db96d56Sopenharmony_ci self.assertTrue(hasattr(obj, name), 4037db96d56Sopenharmony_ci '%r has no attribute %r' % (obj, name)) 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci def assertNotHasAttr(self, obj, name): 4067db96d56Sopenharmony_ci self.assertFalse(hasattr(obj, name), 4077db96d56Sopenharmony_ci '%r has unexpected attribute %r' % (obj, name)) 4087db96d56Sopenharmony_ci 4097db96d56Sopenharmony_ci def test_python_dicts(self): 4107db96d56Sopenharmony_ci # Testing Python subclass of dict... 4117db96d56Sopenharmony_ci self.assertTrue(issubclass(dict, dict)) 4127db96d56Sopenharmony_ci self.assertIsInstance({}, dict) 4137db96d56Sopenharmony_ci d = dict() 4147db96d56Sopenharmony_ci self.assertEqual(d, {}) 4157db96d56Sopenharmony_ci self.assertIs(d.__class__, dict) 4167db96d56Sopenharmony_ci self.assertIsInstance(d, dict) 4177db96d56Sopenharmony_ci class C(dict): 4187db96d56Sopenharmony_ci state = -1 4197db96d56Sopenharmony_ci def __init__(self_local, *a, **kw): 4207db96d56Sopenharmony_ci if a: 4217db96d56Sopenharmony_ci self.assertEqual(len(a), 1) 4227db96d56Sopenharmony_ci self_local.state = a[0] 4237db96d56Sopenharmony_ci if kw: 4247db96d56Sopenharmony_ci for k, v in list(kw.items()): 4257db96d56Sopenharmony_ci self_local[v] = k 4267db96d56Sopenharmony_ci def __getitem__(self, key): 4277db96d56Sopenharmony_ci return self.get(key, 0) 4287db96d56Sopenharmony_ci def __setitem__(self_local, key, value): 4297db96d56Sopenharmony_ci self.assertIsInstance(key, type(0)) 4307db96d56Sopenharmony_ci dict.__setitem__(self_local, key, value) 4317db96d56Sopenharmony_ci def setstate(self, state): 4327db96d56Sopenharmony_ci self.state = state 4337db96d56Sopenharmony_ci def getstate(self): 4347db96d56Sopenharmony_ci return self.state 4357db96d56Sopenharmony_ci self.assertTrue(issubclass(C, dict)) 4367db96d56Sopenharmony_ci a1 = C(12) 4377db96d56Sopenharmony_ci self.assertEqual(a1.state, 12) 4387db96d56Sopenharmony_ci a2 = C(foo=1, bar=2) 4397db96d56Sopenharmony_ci self.assertEqual(a2[1] == 'foo' and a2[2], 'bar') 4407db96d56Sopenharmony_ci a = C() 4417db96d56Sopenharmony_ci self.assertEqual(a.state, -1) 4427db96d56Sopenharmony_ci self.assertEqual(a.getstate(), -1) 4437db96d56Sopenharmony_ci a.setstate(0) 4447db96d56Sopenharmony_ci self.assertEqual(a.state, 0) 4457db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 0) 4467db96d56Sopenharmony_ci a.setstate(10) 4477db96d56Sopenharmony_ci self.assertEqual(a.state, 10) 4487db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 10) 4497db96d56Sopenharmony_ci self.assertEqual(a[42], 0) 4507db96d56Sopenharmony_ci a[42] = 24 4517db96d56Sopenharmony_ci self.assertEqual(a[42], 24) 4527db96d56Sopenharmony_ci N = 50 4537db96d56Sopenharmony_ci for i in range(N): 4547db96d56Sopenharmony_ci a[i] = C() 4557db96d56Sopenharmony_ci for j in range(N): 4567db96d56Sopenharmony_ci a[i][j] = i*j 4577db96d56Sopenharmony_ci for i in range(N): 4587db96d56Sopenharmony_ci for j in range(N): 4597db96d56Sopenharmony_ci self.assertEqual(a[i][j], i*j) 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_ci def test_python_lists(self): 4627db96d56Sopenharmony_ci # Testing Python subclass of list... 4637db96d56Sopenharmony_ci class C(list): 4647db96d56Sopenharmony_ci def __getitem__(self, i): 4657db96d56Sopenharmony_ci if isinstance(i, slice): 4667db96d56Sopenharmony_ci return i.start, i.stop 4677db96d56Sopenharmony_ci return list.__getitem__(self, i) + 100 4687db96d56Sopenharmony_ci a = C() 4697db96d56Sopenharmony_ci a.extend([0,1,2]) 4707db96d56Sopenharmony_ci self.assertEqual(a[0], 100) 4717db96d56Sopenharmony_ci self.assertEqual(a[1], 101) 4727db96d56Sopenharmony_ci self.assertEqual(a[2], 102) 4737db96d56Sopenharmony_ci self.assertEqual(a[100:200], (100,200)) 4747db96d56Sopenharmony_ci 4757db96d56Sopenharmony_ci def test_metaclass(self): 4767db96d56Sopenharmony_ci # Testing metaclasses... 4777db96d56Sopenharmony_ci class C(metaclass=type): 4787db96d56Sopenharmony_ci def __init__(self): 4797db96d56Sopenharmony_ci self.__state = 0 4807db96d56Sopenharmony_ci def getstate(self): 4817db96d56Sopenharmony_ci return self.__state 4827db96d56Sopenharmony_ci def setstate(self, state): 4837db96d56Sopenharmony_ci self.__state = state 4847db96d56Sopenharmony_ci a = C() 4857db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 0) 4867db96d56Sopenharmony_ci a.setstate(10) 4877db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 10) 4887db96d56Sopenharmony_ci class _metaclass(type): 4897db96d56Sopenharmony_ci def myself(cls): return cls 4907db96d56Sopenharmony_ci class D(metaclass=_metaclass): 4917db96d56Sopenharmony_ci pass 4927db96d56Sopenharmony_ci self.assertEqual(D.myself(), D) 4937db96d56Sopenharmony_ci d = D() 4947db96d56Sopenharmony_ci self.assertEqual(d.__class__, D) 4957db96d56Sopenharmony_ci class M1(type): 4967db96d56Sopenharmony_ci def __new__(cls, name, bases, dict): 4977db96d56Sopenharmony_ci dict['__spam__'] = 1 4987db96d56Sopenharmony_ci return type.__new__(cls, name, bases, dict) 4997db96d56Sopenharmony_ci class C(metaclass=M1): 5007db96d56Sopenharmony_ci pass 5017db96d56Sopenharmony_ci self.assertEqual(C.__spam__, 1) 5027db96d56Sopenharmony_ci c = C() 5037db96d56Sopenharmony_ci self.assertEqual(c.__spam__, 1) 5047db96d56Sopenharmony_ci 5057db96d56Sopenharmony_ci class _instance(object): 5067db96d56Sopenharmony_ci pass 5077db96d56Sopenharmony_ci class M2(object): 5087db96d56Sopenharmony_ci @staticmethod 5097db96d56Sopenharmony_ci def __new__(cls, name, bases, dict): 5107db96d56Sopenharmony_ci self = object.__new__(cls) 5117db96d56Sopenharmony_ci self.name = name 5127db96d56Sopenharmony_ci self.bases = bases 5137db96d56Sopenharmony_ci self.dict = dict 5147db96d56Sopenharmony_ci return self 5157db96d56Sopenharmony_ci def __call__(self): 5167db96d56Sopenharmony_ci it = _instance() 5177db96d56Sopenharmony_ci # Early binding of methods 5187db96d56Sopenharmony_ci for key in self.dict: 5197db96d56Sopenharmony_ci if key.startswith("__"): 5207db96d56Sopenharmony_ci continue 5217db96d56Sopenharmony_ci setattr(it, key, self.dict[key].__get__(it, self)) 5227db96d56Sopenharmony_ci return it 5237db96d56Sopenharmony_ci class C(metaclass=M2): 5247db96d56Sopenharmony_ci def spam(self): 5257db96d56Sopenharmony_ci return 42 5267db96d56Sopenharmony_ci self.assertEqual(C.name, 'C') 5277db96d56Sopenharmony_ci self.assertEqual(C.bases, ()) 5287db96d56Sopenharmony_ci self.assertIn('spam', C.dict) 5297db96d56Sopenharmony_ci c = C() 5307db96d56Sopenharmony_ci self.assertEqual(c.spam(), 42) 5317db96d56Sopenharmony_ci 5327db96d56Sopenharmony_ci # More metaclass examples 5337db96d56Sopenharmony_ci 5347db96d56Sopenharmony_ci class autosuper(type): 5357db96d56Sopenharmony_ci # Automatically add __super to the class 5367db96d56Sopenharmony_ci # This trick only works for dynamic classes 5377db96d56Sopenharmony_ci def __new__(metaclass, name, bases, dict): 5387db96d56Sopenharmony_ci cls = super(autosuper, metaclass).__new__(metaclass, 5397db96d56Sopenharmony_ci name, bases, dict) 5407db96d56Sopenharmony_ci # Name mangling for __super removes leading underscores 5417db96d56Sopenharmony_ci while name[:1] == "_": 5427db96d56Sopenharmony_ci name = name[1:] 5437db96d56Sopenharmony_ci if name: 5447db96d56Sopenharmony_ci name = "_%s__super" % name 5457db96d56Sopenharmony_ci else: 5467db96d56Sopenharmony_ci name = "__super" 5477db96d56Sopenharmony_ci setattr(cls, name, super(cls)) 5487db96d56Sopenharmony_ci return cls 5497db96d56Sopenharmony_ci class A(metaclass=autosuper): 5507db96d56Sopenharmony_ci def meth(self): 5517db96d56Sopenharmony_ci return "A" 5527db96d56Sopenharmony_ci class B(A): 5537db96d56Sopenharmony_ci def meth(self): 5547db96d56Sopenharmony_ci return "B" + self.__super.meth() 5557db96d56Sopenharmony_ci class C(A): 5567db96d56Sopenharmony_ci def meth(self): 5577db96d56Sopenharmony_ci return "C" + self.__super.meth() 5587db96d56Sopenharmony_ci class D(C, B): 5597db96d56Sopenharmony_ci def meth(self): 5607db96d56Sopenharmony_ci return "D" + self.__super.meth() 5617db96d56Sopenharmony_ci self.assertEqual(D().meth(), "DCBA") 5627db96d56Sopenharmony_ci class E(B, C): 5637db96d56Sopenharmony_ci def meth(self): 5647db96d56Sopenharmony_ci return "E" + self.__super.meth() 5657db96d56Sopenharmony_ci self.assertEqual(E().meth(), "EBCA") 5667db96d56Sopenharmony_ci 5677db96d56Sopenharmony_ci class autoproperty(type): 5687db96d56Sopenharmony_ci # Automatically create property attributes when methods 5697db96d56Sopenharmony_ci # named _get_x and/or _set_x are found 5707db96d56Sopenharmony_ci def __new__(metaclass, name, bases, dict): 5717db96d56Sopenharmony_ci hits = {} 5727db96d56Sopenharmony_ci for key, val in dict.items(): 5737db96d56Sopenharmony_ci if key.startswith("_get_"): 5747db96d56Sopenharmony_ci key = key[5:] 5757db96d56Sopenharmony_ci get, set = hits.get(key, (None, None)) 5767db96d56Sopenharmony_ci get = val 5777db96d56Sopenharmony_ci hits[key] = get, set 5787db96d56Sopenharmony_ci elif key.startswith("_set_"): 5797db96d56Sopenharmony_ci key = key[5:] 5807db96d56Sopenharmony_ci get, set = hits.get(key, (None, None)) 5817db96d56Sopenharmony_ci set = val 5827db96d56Sopenharmony_ci hits[key] = get, set 5837db96d56Sopenharmony_ci for key, (get, set) in hits.items(): 5847db96d56Sopenharmony_ci dict[key] = property(get, set) 5857db96d56Sopenharmony_ci return super(autoproperty, metaclass).__new__(metaclass, 5867db96d56Sopenharmony_ci name, bases, dict) 5877db96d56Sopenharmony_ci class A(metaclass=autoproperty): 5887db96d56Sopenharmony_ci def _get_x(self): 5897db96d56Sopenharmony_ci return -self.__x 5907db96d56Sopenharmony_ci def _set_x(self, x): 5917db96d56Sopenharmony_ci self.__x = -x 5927db96d56Sopenharmony_ci a = A() 5937db96d56Sopenharmony_ci self.assertNotHasAttr(a, "x") 5947db96d56Sopenharmony_ci a.x = 12 5957db96d56Sopenharmony_ci self.assertEqual(a.x, 12) 5967db96d56Sopenharmony_ci self.assertEqual(a._A__x, -12) 5977db96d56Sopenharmony_ci 5987db96d56Sopenharmony_ci class multimetaclass(autoproperty, autosuper): 5997db96d56Sopenharmony_ci # Merge of multiple cooperating metaclasses 6007db96d56Sopenharmony_ci pass 6017db96d56Sopenharmony_ci class A(metaclass=multimetaclass): 6027db96d56Sopenharmony_ci def _get_x(self): 6037db96d56Sopenharmony_ci return "A" 6047db96d56Sopenharmony_ci class B(A): 6057db96d56Sopenharmony_ci def _get_x(self): 6067db96d56Sopenharmony_ci return "B" + self.__super._get_x() 6077db96d56Sopenharmony_ci class C(A): 6087db96d56Sopenharmony_ci def _get_x(self): 6097db96d56Sopenharmony_ci return "C" + self.__super._get_x() 6107db96d56Sopenharmony_ci class D(C, B): 6117db96d56Sopenharmony_ci def _get_x(self): 6127db96d56Sopenharmony_ci return "D" + self.__super._get_x() 6137db96d56Sopenharmony_ci self.assertEqual(D().x, "DCBA") 6147db96d56Sopenharmony_ci 6157db96d56Sopenharmony_ci # Make sure type(x) doesn't call x.__class__.__init__ 6167db96d56Sopenharmony_ci class T(type): 6177db96d56Sopenharmony_ci counter = 0 6187db96d56Sopenharmony_ci def __init__(self, *args): 6197db96d56Sopenharmony_ci T.counter += 1 6207db96d56Sopenharmony_ci class C(metaclass=T): 6217db96d56Sopenharmony_ci pass 6227db96d56Sopenharmony_ci self.assertEqual(T.counter, 1) 6237db96d56Sopenharmony_ci a = C() 6247db96d56Sopenharmony_ci self.assertEqual(type(a), C) 6257db96d56Sopenharmony_ci self.assertEqual(T.counter, 1) 6267db96d56Sopenharmony_ci 6277db96d56Sopenharmony_ci class C(object): pass 6287db96d56Sopenharmony_ci c = C() 6297db96d56Sopenharmony_ci try: c() 6307db96d56Sopenharmony_ci except TypeError: pass 6317db96d56Sopenharmony_ci else: self.fail("calling object w/o call method should raise " 6327db96d56Sopenharmony_ci "TypeError") 6337db96d56Sopenharmony_ci 6347db96d56Sopenharmony_ci # Testing code to find most derived baseclass 6357db96d56Sopenharmony_ci class A(type): 6367db96d56Sopenharmony_ci def __new__(*args, **kwargs): 6377db96d56Sopenharmony_ci return type.__new__(*args, **kwargs) 6387db96d56Sopenharmony_ci 6397db96d56Sopenharmony_ci class B(object): 6407db96d56Sopenharmony_ci pass 6417db96d56Sopenharmony_ci 6427db96d56Sopenharmony_ci class C(object, metaclass=A): 6437db96d56Sopenharmony_ci pass 6447db96d56Sopenharmony_ci 6457db96d56Sopenharmony_ci # The most derived metaclass of D is A rather than type. 6467db96d56Sopenharmony_ci class D(B, C): 6477db96d56Sopenharmony_ci pass 6487db96d56Sopenharmony_ci self.assertIs(A, type(D)) 6497db96d56Sopenharmony_ci 6507db96d56Sopenharmony_ci # issue1294232: correct metaclass calculation 6517db96d56Sopenharmony_ci new_calls = [] # to check the order of __new__ calls 6527db96d56Sopenharmony_ci class AMeta(type): 6537db96d56Sopenharmony_ci @staticmethod 6547db96d56Sopenharmony_ci def __new__(mcls, name, bases, ns): 6557db96d56Sopenharmony_ci new_calls.append('AMeta') 6567db96d56Sopenharmony_ci return super().__new__(mcls, name, bases, ns) 6577db96d56Sopenharmony_ci @classmethod 6587db96d56Sopenharmony_ci def __prepare__(mcls, name, bases): 6597db96d56Sopenharmony_ci return {} 6607db96d56Sopenharmony_ci 6617db96d56Sopenharmony_ci class BMeta(AMeta): 6627db96d56Sopenharmony_ci @staticmethod 6637db96d56Sopenharmony_ci def __new__(mcls, name, bases, ns): 6647db96d56Sopenharmony_ci new_calls.append('BMeta') 6657db96d56Sopenharmony_ci return super().__new__(mcls, name, bases, ns) 6667db96d56Sopenharmony_ci @classmethod 6677db96d56Sopenharmony_ci def __prepare__(mcls, name, bases): 6687db96d56Sopenharmony_ci ns = super().__prepare__(name, bases) 6697db96d56Sopenharmony_ci ns['BMeta_was_here'] = True 6707db96d56Sopenharmony_ci return ns 6717db96d56Sopenharmony_ci 6727db96d56Sopenharmony_ci class A(metaclass=AMeta): 6737db96d56Sopenharmony_ci pass 6747db96d56Sopenharmony_ci self.assertEqual(['AMeta'], new_calls) 6757db96d56Sopenharmony_ci new_calls.clear() 6767db96d56Sopenharmony_ci 6777db96d56Sopenharmony_ci class B(metaclass=BMeta): 6787db96d56Sopenharmony_ci pass 6797db96d56Sopenharmony_ci # BMeta.__new__ calls AMeta.__new__ with super: 6807db96d56Sopenharmony_ci self.assertEqual(['BMeta', 'AMeta'], new_calls) 6817db96d56Sopenharmony_ci new_calls.clear() 6827db96d56Sopenharmony_ci 6837db96d56Sopenharmony_ci class C(A, B): 6847db96d56Sopenharmony_ci pass 6857db96d56Sopenharmony_ci # The most derived metaclass is BMeta: 6867db96d56Sopenharmony_ci self.assertEqual(['BMeta', 'AMeta'], new_calls) 6877db96d56Sopenharmony_ci new_calls.clear() 6887db96d56Sopenharmony_ci # BMeta.__prepare__ should've been called: 6897db96d56Sopenharmony_ci self.assertIn('BMeta_was_here', C.__dict__) 6907db96d56Sopenharmony_ci 6917db96d56Sopenharmony_ci # The order of the bases shouldn't matter: 6927db96d56Sopenharmony_ci class C2(B, A): 6937db96d56Sopenharmony_ci pass 6947db96d56Sopenharmony_ci self.assertEqual(['BMeta', 'AMeta'], new_calls) 6957db96d56Sopenharmony_ci new_calls.clear() 6967db96d56Sopenharmony_ci self.assertIn('BMeta_was_here', C2.__dict__) 6977db96d56Sopenharmony_ci 6987db96d56Sopenharmony_ci # Check correct metaclass calculation when a metaclass is declared: 6997db96d56Sopenharmony_ci class D(C, metaclass=type): 7007db96d56Sopenharmony_ci pass 7017db96d56Sopenharmony_ci self.assertEqual(['BMeta', 'AMeta'], new_calls) 7027db96d56Sopenharmony_ci new_calls.clear() 7037db96d56Sopenharmony_ci self.assertIn('BMeta_was_here', D.__dict__) 7047db96d56Sopenharmony_ci 7057db96d56Sopenharmony_ci class E(C, metaclass=AMeta): 7067db96d56Sopenharmony_ci pass 7077db96d56Sopenharmony_ci self.assertEqual(['BMeta', 'AMeta'], new_calls) 7087db96d56Sopenharmony_ci new_calls.clear() 7097db96d56Sopenharmony_ci self.assertIn('BMeta_was_here', E.__dict__) 7107db96d56Sopenharmony_ci 7117db96d56Sopenharmony_ci # Special case: the given metaclass isn't a class, 7127db96d56Sopenharmony_ci # so there is no metaclass calculation. 7137db96d56Sopenharmony_ci marker = object() 7147db96d56Sopenharmony_ci def func(*args, **kwargs): 7157db96d56Sopenharmony_ci return marker 7167db96d56Sopenharmony_ci class X(metaclass=func): 7177db96d56Sopenharmony_ci pass 7187db96d56Sopenharmony_ci class Y(object, metaclass=func): 7197db96d56Sopenharmony_ci pass 7207db96d56Sopenharmony_ci class Z(D, metaclass=func): 7217db96d56Sopenharmony_ci pass 7227db96d56Sopenharmony_ci self.assertIs(marker, X) 7237db96d56Sopenharmony_ci self.assertIs(marker, Y) 7247db96d56Sopenharmony_ci self.assertIs(marker, Z) 7257db96d56Sopenharmony_ci 7267db96d56Sopenharmony_ci # The given metaclass is a class, 7277db96d56Sopenharmony_ci # but not a descendant of type. 7287db96d56Sopenharmony_ci prepare_calls = [] # to track __prepare__ calls 7297db96d56Sopenharmony_ci class ANotMeta: 7307db96d56Sopenharmony_ci def __new__(mcls, *args, **kwargs): 7317db96d56Sopenharmony_ci new_calls.append('ANotMeta') 7327db96d56Sopenharmony_ci return super().__new__(mcls) 7337db96d56Sopenharmony_ci @classmethod 7347db96d56Sopenharmony_ci def __prepare__(mcls, name, bases): 7357db96d56Sopenharmony_ci prepare_calls.append('ANotMeta') 7367db96d56Sopenharmony_ci return {} 7377db96d56Sopenharmony_ci class BNotMeta(ANotMeta): 7387db96d56Sopenharmony_ci def __new__(mcls, *args, **kwargs): 7397db96d56Sopenharmony_ci new_calls.append('BNotMeta') 7407db96d56Sopenharmony_ci return super().__new__(mcls) 7417db96d56Sopenharmony_ci @classmethod 7427db96d56Sopenharmony_ci def __prepare__(mcls, name, bases): 7437db96d56Sopenharmony_ci prepare_calls.append('BNotMeta') 7447db96d56Sopenharmony_ci return super().__prepare__(name, bases) 7457db96d56Sopenharmony_ci 7467db96d56Sopenharmony_ci class A(metaclass=ANotMeta): 7477db96d56Sopenharmony_ci pass 7487db96d56Sopenharmony_ci self.assertIs(ANotMeta, type(A)) 7497db96d56Sopenharmony_ci self.assertEqual(['ANotMeta'], prepare_calls) 7507db96d56Sopenharmony_ci prepare_calls.clear() 7517db96d56Sopenharmony_ci self.assertEqual(['ANotMeta'], new_calls) 7527db96d56Sopenharmony_ci new_calls.clear() 7537db96d56Sopenharmony_ci 7547db96d56Sopenharmony_ci class B(metaclass=BNotMeta): 7557db96d56Sopenharmony_ci pass 7567db96d56Sopenharmony_ci self.assertIs(BNotMeta, type(B)) 7577db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 7587db96d56Sopenharmony_ci prepare_calls.clear() 7597db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 7607db96d56Sopenharmony_ci new_calls.clear() 7617db96d56Sopenharmony_ci 7627db96d56Sopenharmony_ci class C(A, B): 7637db96d56Sopenharmony_ci pass 7647db96d56Sopenharmony_ci self.assertIs(BNotMeta, type(C)) 7657db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 7667db96d56Sopenharmony_ci new_calls.clear() 7677db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 7687db96d56Sopenharmony_ci prepare_calls.clear() 7697db96d56Sopenharmony_ci 7707db96d56Sopenharmony_ci class C2(B, A): 7717db96d56Sopenharmony_ci pass 7727db96d56Sopenharmony_ci self.assertIs(BNotMeta, type(C2)) 7737db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 7747db96d56Sopenharmony_ci new_calls.clear() 7757db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 7767db96d56Sopenharmony_ci prepare_calls.clear() 7777db96d56Sopenharmony_ci 7787db96d56Sopenharmony_ci # This is a TypeError, because of a metaclass conflict: 7797db96d56Sopenharmony_ci # BNotMeta is neither a subclass, nor a superclass of type 7807db96d56Sopenharmony_ci with self.assertRaises(TypeError): 7817db96d56Sopenharmony_ci class D(C, metaclass=type): 7827db96d56Sopenharmony_ci pass 7837db96d56Sopenharmony_ci 7847db96d56Sopenharmony_ci class E(C, metaclass=ANotMeta): 7857db96d56Sopenharmony_ci pass 7867db96d56Sopenharmony_ci self.assertIs(BNotMeta, type(E)) 7877db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 7887db96d56Sopenharmony_ci new_calls.clear() 7897db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 7907db96d56Sopenharmony_ci prepare_calls.clear() 7917db96d56Sopenharmony_ci 7927db96d56Sopenharmony_ci class F(object(), C): 7937db96d56Sopenharmony_ci pass 7947db96d56Sopenharmony_ci self.assertIs(BNotMeta, type(F)) 7957db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 7967db96d56Sopenharmony_ci new_calls.clear() 7977db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 7987db96d56Sopenharmony_ci prepare_calls.clear() 7997db96d56Sopenharmony_ci 8007db96d56Sopenharmony_ci class F2(C, object()): 8017db96d56Sopenharmony_ci pass 8027db96d56Sopenharmony_ci self.assertIs(BNotMeta, type(F2)) 8037db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) 8047db96d56Sopenharmony_ci new_calls.clear() 8057db96d56Sopenharmony_ci self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) 8067db96d56Sopenharmony_ci prepare_calls.clear() 8077db96d56Sopenharmony_ci 8087db96d56Sopenharmony_ci # TypeError: BNotMeta is neither a 8097db96d56Sopenharmony_ci # subclass, nor a superclass of int 8107db96d56Sopenharmony_ci with self.assertRaises(TypeError): 8117db96d56Sopenharmony_ci class X(C, int()): 8127db96d56Sopenharmony_ci pass 8137db96d56Sopenharmony_ci with self.assertRaises(TypeError): 8147db96d56Sopenharmony_ci class X(int(), C): 8157db96d56Sopenharmony_ci pass 8167db96d56Sopenharmony_ci 8177db96d56Sopenharmony_ci def test_module_subclasses(self): 8187db96d56Sopenharmony_ci # Testing Python subclass of module... 8197db96d56Sopenharmony_ci log = [] 8207db96d56Sopenharmony_ci MT = type(sys) 8217db96d56Sopenharmony_ci class MM(MT): 8227db96d56Sopenharmony_ci def __init__(self, name): 8237db96d56Sopenharmony_ci MT.__init__(self, name) 8247db96d56Sopenharmony_ci def __getattribute__(self, name): 8257db96d56Sopenharmony_ci log.append(("getattr", name)) 8267db96d56Sopenharmony_ci return MT.__getattribute__(self, name) 8277db96d56Sopenharmony_ci def __setattr__(self, name, value): 8287db96d56Sopenharmony_ci log.append(("setattr", name, value)) 8297db96d56Sopenharmony_ci MT.__setattr__(self, name, value) 8307db96d56Sopenharmony_ci def __delattr__(self, name): 8317db96d56Sopenharmony_ci log.append(("delattr", name)) 8327db96d56Sopenharmony_ci MT.__delattr__(self, name) 8337db96d56Sopenharmony_ci a = MM("a") 8347db96d56Sopenharmony_ci a.foo = 12 8357db96d56Sopenharmony_ci x = a.foo 8367db96d56Sopenharmony_ci del a.foo 8377db96d56Sopenharmony_ci self.assertEqual(log, [("setattr", "foo", 12), 8387db96d56Sopenharmony_ci ("getattr", "foo"), 8397db96d56Sopenharmony_ci ("delattr", "foo")]) 8407db96d56Sopenharmony_ci 8417db96d56Sopenharmony_ci # http://python.org/sf/1174712 8427db96d56Sopenharmony_ci try: 8437db96d56Sopenharmony_ci class Module(types.ModuleType, str): 8447db96d56Sopenharmony_ci pass 8457db96d56Sopenharmony_ci except TypeError: 8467db96d56Sopenharmony_ci pass 8477db96d56Sopenharmony_ci else: 8487db96d56Sopenharmony_ci self.fail("inheriting from ModuleType and str at the same time " 8497db96d56Sopenharmony_ci "should fail") 8507db96d56Sopenharmony_ci 8517db96d56Sopenharmony_ci # Issue 34805: Verify that definition order is retained 8527db96d56Sopenharmony_ci def random_name(): 8537db96d56Sopenharmony_ci return ''.join(random.choices(string.ascii_letters, k=10)) 8547db96d56Sopenharmony_ci class A: 8557db96d56Sopenharmony_ci pass 8567db96d56Sopenharmony_ci subclasses = [type(random_name(), (A,), {}) for i in range(100)] 8577db96d56Sopenharmony_ci self.assertEqual(A.__subclasses__(), subclasses) 8587db96d56Sopenharmony_ci 8597db96d56Sopenharmony_ci def test_multiple_inheritance(self): 8607db96d56Sopenharmony_ci # Testing multiple inheritance... 8617db96d56Sopenharmony_ci class C(object): 8627db96d56Sopenharmony_ci def __init__(self): 8637db96d56Sopenharmony_ci self.__state = 0 8647db96d56Sopenharmony_ci def getstate(self): 8657db96d56Sopenharmony_ci return self.__state 8667db96d56Sopenharmony_ci def setstate(self, state): 8677db96d56Sopenharmony_ci self.__state = state 8687db96d56Sopenharmony_ci a = C() 8697db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 0) 8707db96d56Sopenharmony_ci a.setstate(10) 8717db96d56Sopenharmony_ci self.assertEqual(a.getstate(), 10) 8727db96d56Sopenharmony_ci class D(dict, C): 8737db96d56Sopenharmony_ci def __init__(self): 8747db96d56Sopenharmony_ci type({}).__init__(self) 8757db96d56Sopenharmony_ci C.__init__(self) 8767db96d56Sopenharmony_ci d = D() 8777db96d56Sopenharmony_ci self.assertEqual(list(d.keys()), []) 8787db96d56Sopenharmony_ci d["hello"] = "world" 8797db96d56Sopenharmony_ci self.assertEqual(list(d.items()), [("hello", "world")]) 8807db96d56Sopenharmony_ci self.assertEqual(d["hello"], "world") 8817db96d56Sopenharmony_ci self.assertEqual(d.getstate(), 0) 8827db96d56Sopenharmony_ci d.setstate(10) 8837db96d56Sopenharmony_ci self.assertEqual(d.getstate(), 10) 8847db96d56Sopenharmony_ci self.assertEqual(D.__mro__, (D, dict, C, object)) 8857db96d56Sopenharmony_ci 8867db96d56Sopenharmony_ci # SF bug #442833 8877db96d56Sopenharmony_ci class Node(object): 8887db96d56Sopenharmony_ci def __int__(self): 8897db96d56Sopenharmony_ci return int(self.foo()) 8907db96d56Sopenharmony_ci def foo(self): 8917db96d56Sopenharmony_ci return "23" 8927db96d56Sopenharmony_ci class Frag(Node, list): 8937db96d56Sopenharmony_ci def foo(self): 8947db96d56Sopenharmony_ci return "42" 8957db96d56Sopenharmony_ci self.assertEqual(Node().__int__(), 23) 8967db96d56Sopenharmony_ci self.assertEqual(int(Node()), 23) 8977db96d56Sopenharmony_ci self.assertEqual(Frag().__int__(), 42) 8987db96d56Sopenharmony_ci self.assertEqual(int(Frag()), 42) 8997db96d56Sopenharmony_ci 9007db96d56Sopenharmony_ci def test_diamond_inheritance(self): 9017db96d56Sopenharmony_ci # Testing multiple inheritance special cases... 9027db96d56Sopenharmony_ci class A(object): 9037db96d56Sopenharmony_ci def spam(self): return "A" 9047db96d56Sopenharmony_ci self.assertEqual(A().spam(), "A") 9057db96d56Sopenharmony_ci class B(A): 9067db96d56Sopenharmony_ci def boo(self): return "B" 9077db96d56Sopenharmony_ci def spam(self): return "B" 9087db96d56Sopenharmony_ci self.assertEqual(B().spam(), "B") 9097db96d56Sopenharmony_ci self.assertEqual(B().boo(), "B") 9107db96d56Sopenharmony_ci class C(A): 9117db96d56Sopenharmony_ci def boo(self): return "C" 9127db96d56Sopenharmony_ci self.assertEqual(C().spam(), "A") 9137db96d56Sopenharmony_ci self.assertEqual(C().boo(), "C") 9147db96d56Sopenharmony_ci class D(B, C): pass 9157db96d56Sopenharmony_ci self.assertEqual(D().spam(), "B") 9167db96d56Sopenharmony_ci self.assertEqual(D().boo(), "B") 9177db96d56Sopenharmony_ci self.assertEqual(D.__mro__, (D, B, C, A, object)) 9187db96d56Sopenharmony_ci class E(C, B): pass 9197db96d56Sopenharmony_ci self.assertEqual(E().spam(), "B") 9207db96d56Sopenharmony_ci self.assertEqual(E().boo(), "C") 9217db96d56Sopenharmony_ci self.assertEqual(E.__mro__, (E, C, B, A, object)) 9227db96d56Sopenharmony_ci # MRO order disagreement 9237db96d56Sopenharmony_ci try: 9247db96d56Sopenharmony_ci class F(D, E): pass 9257db96d56Sopenharmony_ci except TypeError: 9267db96d56Sopenharmony_ci pass 9277db96d56Sopenharmony_ci else: 9287db96d56Sopenharmony_ci self.fail("expected MRO order disagreement (F)") 9297db96d56Sopenharmony_ci try: 9307db96d56Sopenharmony_ci class G(E, D): pass 9317db96d56Sopenharmony_ci except TypeError: 9327db96d56Sopenharmony_ci pass 9337db96d56Sopenharmony_ci else: 9347db96d56Sopenharmony_ci self.fail("expected MRO order disagreement (G)") 9357db96d56Sopenharmony_ci 9367db96d56Sopenharmony_ci # see thread python-dev/2002-October/029035.html 9377db96d56Sopenharmony_ci def test_ex5_from_c3_switch(self): 9387db96d56Sopenharmony_ci # Testing ex5 from C3 switch discussion... 9397db96d56Sopenharmony_ci class A(object): pass 9407db96d56Sopenharmony_ci class B(object): pass 9417db96d56Sopenharmony_ci class C(object): pass 9427db96d56Sopenharmony_ci class X(A): pass 9437db96d56Sopenharmony_ci class Y(A): pass 9447db96d56Sopenharmony_ci class Z(X,B,Y,C): pass 9457db96d56Sopenharmony_ci self.assertEqual(Z.__mro__, (Z, X, B, Y, A, C, object)) 9467db96d56Sopenharmony_ci 9477db96d56Sopenharmony_ci # see "A Monotonic Superclass Linearization for Dylan", 9487db96d56Sopenharmony_ci # by Kim Barrett et al. (OOPSLA 1996) 9497db96d56Sopenharmony_ci def test_monotonicity(self): 9507db96d56Sopenharmony_ci # Testing MRO monotonicity... 9517db96d56Sopenharmony_ci class Boat(object): pass 9527db96d56Sopenharmony_ci class DayBoat(Boat): pass 9537db96d56Sopenharmony_ci class WheelBoat(Boat): pass 9547db96d56Sopenharmony_ci class EngineLess(DayBoat): pass 9557db96d56Sopenharmony_ci class SmallMultihull(DayBoat): pass 9567db96d56Sopenharmony_ci class PedalWheelBoat(EngineLess,WheelBoat): pass 9577db96d56Sopenharmony_ci class SmallCatamaran(SmallMultihull): pass 9587db96d56Sopenharmony_ci class Pedalo(PedalWheelBoat,SmallCatamaran): pass 9597db96d56Sopenharmony_ci 9607db96d56Sopenharmony_ci self.assertEqual(PedalWheelBoat.__mro__, 9617db96d56Sopenharmony_ci (PedalWheelBoat, EngineLess, DayBoat, WheelBoat, Boat, object)) 9627db96d56Sopenharmony_ci self.assertEqual(SmallCatamaran.__mro__, 9637db96d56Sopenharmony_ci (SmallCatamaran, SmallMultihull, DayBoat, Boat, object)) 9647db96d56Sopenharmony_ci self.assertEqual(Pedalo.__mro__, 9657db96d56Sopenharmony_ci (Pedalo, PedalWheelBoat, EngineLess, SmallCatamaran, 9667db96d56Sopenharmony_ci SmallMultihull, DayBoat, WheelBoat, Boat, object)) 9677db96d56Sopenharmony_ci 9687db96d56Sopenharmony_ci # see "A Monotonic Superclass Linearization for Dylan", 9697db96d56Sopenharmony_ci # by Kim Barrett et al. (OOPSLA 1996) 9707db96d56Sopenharmony_ci def test_consistency_with_epg(self): 9717db96d56Sopenharmony_ci # Testing consistency with EPG... 9727db96d56Sopenharmony_ci class Pane(object): pass 9737db96d56Sopenharmony_ci class ScrollingMixin(object): pass 9747db96d56Sopenharmony_ci class EditingMixin(object): pass 9757db96d56Sopenharmony_ci class ScrollablePane(Pane,ScrollingMixin): pass 9767db96d56Sopenharmony_ci class EditablePane(Pane,EditingMixin): pass 9777db96d56Sopenharmony_ci class EditableScrollablePane(ScrollablePane,EditablePane): pass 9787db96d56Sopenharmony_ci 9797db96d56Sopenharmony_ci self.assertEqual(EditableScrollablePane.__mro__, 9807db96d56Sopenharmony_ci (EditableScrollablePane, ScrollablePane, EditablePane, Pane, 9817db96d56Sopenharmony_ci ScrollingMixin, EditingMixin, object)) 9827db96d56Sopenharmony_ci 9837db96d56Sopenharmony_ci def test_mro_disagreement(self): 9847db96d56Sopenharmony_ci # Testing error messages for MRO disagreement... 9857db96d56Sopenharmony_ci mro_err_msg = """Cannot create a consistent method resolution 9867db96d56Sopenharmony_ciorder (MRO) for bases """ 9877db96d56Sopenharmony_ci 9887db96d56Sopenharmony_ci def raises(exc, expected, callable, *args): 9897db96d56Sopenharmony_ci try: 9907db96d56Sopenharmony_ci callable(*args) 9917db96d56Sopenharmony_ci except exc as msg: 9927db96d56Sopenharmony_ci # the exact msg is generally considered an impl detail 9937db96d56Sopenharmony_ci if support.check_impl_detail(): 9947db96d56Sopenharmony_ci if not str(msg).startswith(expected): 9957db96d56Sopenharmony_ci self.fail("Message %r, expected %r" % 9967db96d56Sopenharmony_ci (str(msg), expected)) 9977db96d56Sopenharmony_ci else: 9987db96d56Sopenharmony_ci self.fail("Expected %s" % exc) 9997db96d56Sopenharmony_ci 10007db96d56Sopenharmony_ci class A(object): pass 10017db96d56Sopenharmony_ci class B(A): pass 10027db96d56Sopenharmony_ci class C(object): pass 10037db96d56Sopenharmony_ci 10047db96d56Sopenharmony_ci # Test some very simple errors 10057db96d56Sopenharmony_ci raises(TypeError, "duplicate base class A", 10067db96d56Sopenharmony_ci type, "X", (A, A), {}) 10077db96d56Sopenharmony_ci raises(TypeError, mro_err_msg, 10087db96d56Sopenharmony_ci type, "X", (A, B), {}) 10097db96d56Sopenharmony_ci raises(TypeError, mro_err_msg, 10107db96d56Sopenharmony_ci type, "X", (A, C, B), {}) 10117db96d56Sopenharmony_ci # Test a slightly more complex error 10127db96d56Sopenharmony_ci class GridLayout(object): pass 10137db96d56Sopenharmony_ci class HorizontalGrid(GridLayout): pass 10147db96d56Sopenharmony_ci class VerticalGrid(GridLayout): pass 10157db96d56Sopenharmony_ci class HVGrid(HorizontalGrid, VerticalGrid): pass 10167db96d56Sopenharmony_ci class VHGrid(VerticalGrid, HorizontalGrid): pass 10177db96d56Sopenharmony_ci raises(TypeError, mro_err_msg, 10187db96d56Sopenharmony_ci type, "ConfusedGrid", (HVGrid, VHGrid), {}) 10197db96d56Sopenharmony_ci 10207db96d56Sopenharmony_ci def test_object_class(self): 10217db96d56Sopenharmony_ci # Testing object class... 10227db96d56Sopenharmony_ci a = object() 10237db96d56Sopenharmony_ci self.assertEqual(a.__class__, object) 10247db96d56Sopenharmony_ci self.assertEqual(type(a), object) 10257db96d56Sopenharmony_ci b = object() 10267db96d56Sopenharmony_ci self.assertNotEqual(a, b) 10277db96d56Sopenharmony_ci self.assertNotHasAttr(a, "foo") 10287db96d56Sopenharmony_ci try: 10297db96d56Sopenharmony_ci a.foo = 12 10307db96d56Sopenharmony_ci except (AttributeError, TypeError): 10317db96d56Sopenharmony_ci pass 10327db96d56Sopenharmony_ci else: 10337db96d56Sopenharmony_ci self.fail("object() should not allow setting a foo attribute") 10347db96d56Sopenharmony_ci self.assertNotHasAttr(object(), "__dict__") 10357db96d56Sopenharmony_ci 10367db96d56Sopenharmony_ci class Cdict(object): 10377db96d56Sopenharmony_ci pass 10387db96d56Sopenharmony_ci x = Cdict() 10397db96d56Sopenharmony_ci self.assertEqual(x.__dict__, {}) 10407db96d56Sopenharmony_ci x.foo = 1 10417db96d56Sopenharmony_ci self.assertEqual(x.foo, 1) 10427db96d56Sopenharmony_ci self.assertEqual(x.__dict__, {'foo': 1}) 10437db96d56Sopenharmony_ci 10447db96d56Sopenharmony_ci def test_object_class_assignment_between_heaptypes_and_nonheaptypes(self): 10457db96d56Sopenharmony_ci class SubType(types.ModuleType): 10467db96d56Sopenharmony_ci a = 1 10477db96d56Sopenharmony_ci 10487db96d56Sopenharmony_ci m = types.ModuleType("m") 10497db96d56Sopenharmony_ci self.assertTrue(m.__class__ is types.ModuleType) 10507db96d56Sopenharmony_ci self.assertFalse(hasattr(m, "a")) 10517db96d56Sopenharmony_ci 10527db96d56Sopenharmony_ci m.__class__ = SubType 10537db96d56Sopenharmony_ci self.assertTrue(m.__class__ is SubType) 10547db96d56Sopenharmony_ci self.assertTrue(hasattr(m, "a")) 10557db96d56Sopenharmony_ci 10567db96d56Sopenharmony_ci m.__class__ = types.ModuleType 10577db96d56Sopenharmony_ci self.assertTrue(m.__class__ is types.ModuleType) 10587db96d56Sopenharmony_ci self.assertFalse(hasattr(m, "a")) 10597db96d56Sopenharmony_ci 10607db96d56Sopenharmony_ci # Make sure that builtin immutable objects don't support __class__ 10617db96d56Sopenharmony_ci # assignment, because the object instances may be interned. 10627db96d56Sopenharmony_ci # We set __slots__ = () to ensure that the subclasses are 10637db96d56Sopenharmony_ci # memory-layout compatible, and thus otherwise reasonable candidates 10647db96d56Sopenharmony_ci # for __class__ assignment. 10657db96d56Sopenharmony_ci 10667db96d56Sopenharmony_ci # The following types have immutable instances, but are not 10677db96d56Sopenharmony_ci # subclassable and thus don't need to be checked: 10687db96d56Sopenharmony_ci # NoneType, bool 10697db96d56Sopenharmony_ci 10707db96d56Sopenharmony_ci class MyInt(int): 10717db96d56Sopenharmony_ci __slots__ = () 10727db96d56Sopenharmony_ci with self.assertRaises(TypeError): 10737db96d56Sopenharmony_ci (1).__class__ = MyInt 10747db96d56Sopenharmony_ci 10757db96d56Sopenharmony_ci class MyFloat(float): 10767db96d56Sopenharmony_ci __slots__ = () 10777db96d56Sopenharmony_ci with self.assertRaises(TypeError): 10787db96d56Sopenharmony_ci (1.0).__class__ = MyFloat 10797db96d56Sopenharmony_ci 10807db96d56Sopenharmony_ci class MyComplex(complex): 10817db96d56Sopenharmony_ci __slots__ = () 10827db96d56Sopenharmony_ci with self.assertRaises(TypeError): 10837db96d56Sopenharmony_ci (1 + 2j).__class__ = MyComplex 10847db96d56Sopenharmony_ci 10857db96d56Sopenharmony_ci class MyStr(str): 10867db96d56Sopenharmony_ci __slots__ = () 10877db96d56Sopenharmony_ci with self.assertRaises(TypeError): 10887db96d56Sopenharmony_ci "a".__class__ = MyStr 10897db96d56Sopenharmony_ci 10907db96d56Sopenharmony_ci class MyBytes(bytes): 10917db96d56Sopenharmony_ci __slots__ = () 10927db96d56Sopenharmony_ci with self.assertRaises(TypeError): 10937db96d56Sopenharmony_ci b"a".__class__ = MyBytes 10947db96d56Sopenharmony_ci 10957db96d56Sopenharmony_ci class MyTuple(tuple): 10967db96d56Sopenharmony_ci __slots__ = () 10977db96d56Sopenharmony_ci with self.assertRaises(TypeError): 10987db96d56Sopenharmony_ci ().__class__ = MyTuple 10997db96d56Sopenharmony_ci 11007db96d56Sopenharmony_ci class MyFrozenSet(frozenset): 11017db96d56Sopenharmony_ci __slots__ = () 11027db96d56Sopenharmony_ci with self.assertRaises(TypeError): 11037db96d56Sopenharmony_ci frozenset().__class__ = MyFrozenSet 11047db96d56Sopenharmony_ci 11057db96d56Sopenharmony_ci def test_slots(self): 11067db96d56Sopenharmony_ci # Testing __slots__... 11077db96d56Sopenharmony_ci class C0(object): 11087db96d56Sopenharmony_ci __slots__ = [] 11097db96d56Sopenharmony_ci x = C0() 11107db96d56Sopenharmony_ci self.assertNotHasAttr(x, "__dict__") 11117db96d56Sopenharmony_ci self.assertNotHasAttr(x, "foo") 11127db96d56Sopenharmony_ci 11137db96d56Sopenharmony_ci class C1(object): 11147db96d56Sopenharmony_ci __slots__ = ['a'] 11157db96d56Sopenharmony_ci x = C1() 11167db96d56Sopenharmony_ci self.assertNotHasAttr(x, "__dict__") 11177db96d56Sopenharmony_ci self.assertNotHasAttr(x, "a") 11187db96d56Sopenharmony_ci x.a = 1 11197db96d56Sopenharmony_ci self.assertEqual(x.a, 1) 11207db96d56Sopenharmony_ci x.a = None 11217db96d56Sopenharmony_ci self.assertEqual(x.a, None) 11227db96d56Sopenharmony_ci del x.a 11237db96d56Sopenharmony_ci self.assertNotHasAttr(x, "a") 11247db96d56Sopenharmony_ci 11257db96d56Sopenharmony_ci class C3(object): 11267db96d56Sopenharmony_ci __slots__ = ['a', 'b', 'c'] 11277db96d56Sopenharmony_ci x = C3() 11287db96d56Sopenharmony_ci self.assertNotHasAttr(x, "__dict__") 11297db96d56Sopenharmony_ci self.assertNotHasAttr(x, 'a') 11307db96d56Sopenharmony_ci self.assertNotHasAttr(x, 'b') 11317db96d56Sopenharmony_ci self.assertNotHasAttr(x, 'c') 11327db96d56Sopenharmony_ci x.a = 1 11337db96d56Sopenharmony_ci x.b = 2 11347db96d56Sopenharmony_ci x.c = 3 11357db96d56Sopenharmony_ci self.assertEqual(x.a, 1) 11367db96d56Sopenharmony_ci self.assertEqual(x.b, 2) 11377db96d56Sopenharmony_ci self.assertEqual(x.c, 3) 11387db96d56Sopenharmony_ci 11397db96d56Sopenharmony_ci class C4(object): 11407db96d56Sopenharmony_ci """Validate name mangling""" 11417db96d56Sopenharmony_ci __slots__ = ['__a'] 11427db96d56Sopenharmony_ci def __init__(self, value): 11437db96d56Sopenharmony_ci self.__a = value 11447db96d56Sopenharmony_ci def get(self): 11457db96d56Sopenharmony_ci return self.__a 11467db96d56Sopenharmony_ci x = C4(5) 11477db96d56Sopenharmony_ci self.assertNotHasAttr(x, '__dict__') 11487db96d56Sopenharmony_ci self.assertNotHasAttr(x, '__a') 11497db96d56Sopenharmony_ci self.assertEqual(x.get(), 5) 11507db96d56Sopenharmony_ci try: 11517db96d56Sopenharmony_ci x.__a = 6 11527db96d56Sopenharmony_ci except AttributeError: 11537db96d56Sopenharmony_ci pass 11547db96d56Sopenharmony_ci else: 11557db96d56Sopenharmony_ci self.fail("Double underscored names not mangled") 11567db96d56Sopenharmony_ci 11577db96d56Sopenharmony_ci # Make sure slot names are proper identifiers 11587db96d56Sopenharmony_ci try: 11597db96d56Sopenharmony_ci class C(object): 11607db96d56Sopenharmony_ci __slots__ = [None] 11617db96d56Sopenharmony_ci except TypeError: 11627db96d56Sopenharmony_ci pass 11637db96d56Sopenharmony_ci else: 11647db96d56Sopenharmony_ci self.fail("[None] slots not caught") 11657db96d56Sopenharmony_ci try: 11667db96d56Sopenharmony_ci class C(object): 11677db96d56Sopenharmony_ci __slots__ = ["foo bar"] 11687db96d56Sopenharmony_ci except TypeError: 11697db96d56Sopenharmony_ci pass 11707db96d56Sopenharmony_ci else: 11717db96d56Sopenharmony_ci self.fail("['foo bar'] slots not caught") 11727db96d56Sopenharmony_ci try: 11737db96d56Sopenharmony_ci class C(object): 11747db96d56Sopenharmony_ci __slots__ = ["foo\0bar"] 11757db96d56Sopenharmony_ci except TypeError: 11767db96d56Sopenharmony_ci pass 11777db96d56Sopenharmony_ci else: 11787db96d56Sopenharmony_ci self.fail("['foo\\0bar'] slots not caught") 11797db96d56Sopenharmony_ci try: 11807db96d56Sopenharmony_ci class C(object): 11817db96d56Sopenharmony_ci __slots__ = ["1"] 11827db96d56Sopenharmony_ci except TypeError: 11837db96d56Sopenharmony_ci pass 11847db96d56Sopenharmony_ci else: 11857db96d56Sopenharmony_ci self.fail("['1'] slots not caught") 11867db96d56Sopenharmony_ci try: 11877db96d56Sopenharmony_ci class C(object): 11887db96d56Sopenharmony_ci __slots__ = [""] 11897db96d56Sopenharmony_ci except TypeError: 11907db96d56Sopenharmony_ci pass 11917db96d56Sopenharmony_ci else: 11927db96d56Sopenharmony_ci self.fail("[''] slots not caught") 11937db96d56Sopenharmony_ci class C(object): 11947db96d56Sopenharmony_ci __slots__ = ["a", "a_b", "_a", "A0123456789Z"] 11957db96d56Sopenharmony_ci # XXX(nnorwitz): was there supposed to be something tested 11967db96d56Sopenharmony_ci # from the class above? 11977db96d56Sopenharmony_ci 11987db96d56Sopenharmony_ci # Test a single string is not expanded as a sequence. 11997db96d56Sopenharmony_ci class C(object): 12007db96d56Sopenharmony_ci __slots__ = "abc" 12017db96d56Sopenharmony_ci c = C() 12027db96d56Sopenharmony_ci c.abc = 5 12037db96d56Sopenharmony_ci self.assertEqual(c.abc, 5) 12047db96d56Sopenharmony_ci 12057db96d56Sopenharmony_ci # Test unicode slot names 12067db96d56Sopenharmony_ci # Test a single unicode string is not expanded as a sequence. 12077db96d56Sopenharmony_ci class C(object): 12087db96d56Sopenharmony_ci __slots__ = "abc" 12097db96d56Sopenharmony_ci c = C() 12107db96d56Sopenharmony_ci c.abc = 5 12117db96d56Sopenharmony_ci self.assertEqual(c.abc, 5) 12127db96d56Sopenharmony_ci 12137db96d56Sopenharmony_ci # _unicode_to_string used to modify slots in certain circumstances 12147db96d56Sopenharmony_ci slots = ("foo", "bar") 12157db96d56Sopenharmony_ci class C(object): 12167db96d56Sopenharmony_ci __slots__ = slots 12177db96d56Sopenharmony_ci x = C() 12187db96d56Sopenharmony_ci x.foo = 5 12197db96d56Sopenharmony_ci self.assertEqual(x.foo, 5) 12207db96d56Sopenharmony_ci self.assertIs(type(slots[0]), str) 12217db96d56Sopenharmony_ci # this used to leak references 12227db96d56Sopenharmony_ci try: 12237db96d56Sopenharmony_ci class C(object): 12247db96d56Sopenharmony_ci __slots__ = [chr(128)] 12257db96d56Sopenharmony_ci except (TypeError, UnicodeEncodeError): 12267db96d56Sopenharmony_ci pass 12277db96d56Sopenharmony_ci else: 12287db96d56Sopenharmony_ci self.fail("[chr(128)] slots not caught") 12297db96d56Sopenharmony_ci 12307db96d56Sopenharmony_ci # Test leaks 12317db96d56Sopenharmony_ci class Counted(object): 12327db96d56Sopenharmony_ci counter = 0 # counts the number of instances alive 12337db96d56Sopenharmony_ci def __init__(self): 12347db96d56Sopenharmony_ci Counted.counter += 1 12357db96d56Sopenharmony_ci def __del__(self): 12367db96d56Sopenharmony_ci Counted.counter -= 1 12377db96d56Sopenharmony_ci class C(object): 12387db96d56Sopenharmony_ci __slots__ = ['a', 'b', 'c'] 12397db96d56Sopenharmony_ci x = C() 12407db96d56Sopenharmony_ci x.a = Counted() 12417db96d56Sopenharmony_ci x.b = Counted() 12427db96d56Sopenharmony_ci x.c = Counted() 12437db96d56Sopenharmony_ci self.assertEqual(Counted.counter, 3) 12447db96d56Sopenharmony_ci del x 12457db96d56Sopenharmony_ci support.gc_collect() 12467db96d56Sopenharmony_ci self.assertEqual(Counted.counter, 0) 12477db96d56Sopenharmony_ci class D(C): 12487db96d56Sopenharmony_ci pass 12497db96d56Sopenharmony_ci x = D() 12507db96d56Sopenharmony_ci x.a = Counted() 12517db96d56Sopenharmony_ci x.z = Counted() 12527db96d56Sopenharmony_ci self.assertEqual(Counted.counter, 2) 12537db96d56Sopenharmony_ci del x 12547db96d56Sopenharmony_ci support.gc_collect() 12557db96d56Sopenharmony_ci self.assertEqual(Counted.counter, 0) 12567db96d56Sopenharmony_ci class E(D): 12577db96d56Sopenharmony_ci __slots__ = ['e'] 12587db96d56Sopenharmony_ci x = E() 12597db96d56Sopenharmony_ci x.a = Counted() 12607db96d56Sopenharmony_ci x.z = Counted() 12617db96d56Sopenharmony_ci x.e = Counted() 12627db96d56Sopenharmony_ci self.assertEqual(Counted.counter, 3) 12637db96d56Sopenharmony_ci del x 12647db96d56Sopenharmony_ci support.gc_collect() 12657db96d56Sopenharmony_ci self.assertEqual(Counted.counter, 0) 12667db96d56Sopenharmony_ci 12677db96d56Sopenharmony_ci # Test cyclical leaks [SF bug 519621] 12687db96d56Sopenharmony_ci class F(object): 12697db96d56Sopenharmony_ci __slots__ = ['a', 'b'] 12707db96d56Sopenharmony_ci s = F() 12717db96d56Sopenharmony_ci s.a = [Counted(), s] 12727db96d56Sopenharmony_ci self.assertEqual(Counted.counter, 1) 12737db96d56Sopenharmony_ci s = None 12747db96d56Sopenharmony_ci support.gc_collect() 12757db96d56Sopenharmony_ci self.assertEqual(Counted.counter, 0) 12767db96d56Sopenharmony_ci 12777db96d56Sopenharmony_ci # Test lookup leaks [SF bug 572567] 12787db96d56Sopenharmony_ci if hasattr(gc, 'get_objects'): 12797db96d56Sopenharmony_ci class G(object): 12807db96d56Sopenharmony_ci def __eq__(self, other): 12817db96d56Sopenharmony_ci return False 12827db96d56Sopenharmony_ci g = G() 12837db96d56Sopenharmony_ci orig_objects = len(gc.get_objects()) 12847db96d56Sopenharmony_ci for i in range(10): 12857db96d56Sopenharmony_ci g==g 12867db96d56Sopenharmony_ci new_objects = len(gc.get_objects()) 12877db96d56Sopenharmony_ci self.assertEqual(orig_objects, new_objects) 12887db96d56Sopenharmony_ci 12897db96d56Sopenharmony_ci class H(object): 12907db96d56Sopenharmony_ci __slots__ = ['a', 'b'] 12917db96d56Sopenharmony_ci def __init__(self): 12927db96d56Sopenharmony_ci self.a = 1 12937db96d56Sopenharmony_ci self.b = 2 12947db96d56Sopenharmony_ci def __del__(self_): 12957db96d56Sopenharmony_ci self.assertEqual(self_.a, 1) 12967db96d56Sopenharmony_ci self.assertEqual(self_.b, 2) 12977db96d56Sopenharmony_ci with support.captured_output('stderr') as s: 12987db96d56Sopenharmony_ci h = H() 12997db96d56Sopenharmony_ci del h 13007db96d56Sopenharmony_ci self.assertEqual(s.getvalue(), '') 13017db96d56Sopenharmony_ci 13027db96d56Sopenharmony_ci class X(object): 13037db96d56Sopenharmony_ci __slots__ = "a" 13047db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 13057db96d56Sopenharmony_ci del X().a 13067db96d56Sopenharmony_ci 13077db96d56Sopenharmony_ci # Inherit from object on purpose to check some backwards compatibility paths 13087db96d56Sopenharmony_ci class X(object): 13097db96d56Sopenharmony_ci __slots__ = "a" 13107db96d56Sopenharmony_ci with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"): 13117db96d56Sopenharmony_ci X().a 13127db96d56Sopenharmony_ci 13137db96d56Sopenharmony_ci # Test string subclass in `__slots__`, see gh-98783 13147db96d56Sopenharmony_ci class SubStr(str): 13157db96d56Sopenharmony_ci pass 13167db96d56Sopenharmony_ci class X(object): 13177db96d56Sopenharmony_ci __slots__ = (SubStr('x'),) 13187db96d56Sopenharmony_ci X().x = 1 13197db96d56Sopenharmony_ci with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"): 13207db96d56Sopenharmony_ci X().a 13217db96d56Sopenharmony_ci 13227db96d56Sopenharmony_ci def test_slots_special(self): 13237db96d56Sopenharmony_ci # Testing __dict__ and __weakref__ in __slots__... 13247db96d56Sopenharmony_ci class D(object): 13257db96d56Sopenharmony_ci __slots__ = ["__dict__"] 13267db96d56Sopenharmony_ci a = D() 13277db96d56Sopenharmony_ci self.assertHasAttr(a, "__dict__") 13287db96d56Sopenharmony_ci self.assertNotHasAttr(a, "__weakref__") 13297db96d56Sopenharmony_ci a.foo = 42 13307db96d56Sopenharmony_ci self.assertEqual(a.__dict__, {"foo": 42}) 13317db96d56Sopenharmony_ci 13327db96d56Sopenharmony_ci class W(object): 13337db96d56Sopenharmony_ci __slots__ = ["__weakref__"] 13347db96d56Sopenharmony_ci a = W() 13357db96d56Sopenharmony_ci self.assertHasAttr(a, "__weakref__") 13367db96d56Sopenharmony_ci self.assertNotHasAttr(a, "__dict__") 13377db96d56Sopenharmony_ci try: 13387db96d56Sopenharmony_ci a.foo = 42 13397db96d56Sopenharmony_ci except AttributeError: 13407db96d56Sopenharmony_ci pass 13417db96d56Sopenharmony_ci else: 13427db96d56Sopenharmony_ci self.fail("shouldn't be allowed to set a.foo") 13437db96d56Sopenharmony_ci 13447db96d56Sopenharmony_ci class C1(W, D): 13457db96d56Sopenharmony_ci __slots__ = [] 13467db96d56Sopenharmony_ci a = C1() 13477db96d56Sopenharmony_ci self.assertHasAttr(a, "__dict__") 13487db96d56Sopenharmony_ci self.assertHasAttr(a, "__weakref__") 13497db96d56Sopenharmony_ci a.foo = 42 13507db96d56Sopenharmony_ci self.assertEqual(a.__dict__, {"foo": 42}) 13517db96d56Sopenharmony_ci 13527db96d56Sopenharmony_ci class C2(D, W): 13537db96d56Sopenharmony_ci __slots__ = [] 13547db96d56Sopenharmony_ci a = C2() 13557db96d56Sopenharmony_ci self.assertHasAttr(a, "__dict__") 13567db96d56Sopenharmony_ci self.assertHasAttr(a, "__weakref__") 13577db96d56Sopenharmony_ci a.foo = 42 13587db96d56Sopenharmony_ci self.assertEqual(a.__dict__, {"foo": 42}) 13597db96d56Sopenharmony_ci 13607db96d56Sopenharmony_ci def test_slots_special2(self): 13617db96d56Sopenharmony_ci # Testing __qualname__ and __classcell__ in __slots__ 13627db96d56Sopenharmony_ci class Meta(type): 13637db96d56Sopenharmony_ci def __new__(cls, name, bases, namespace, attr): 13647db96d56Sopenharmony_ci self.assertIn(attr, namespace) 13657db96d56Sopenharmony_ci return super().__new__(cls, name, bases, namespace) 13667db96d56Sopenharmony_ci 13677db96d56Sopenharmony_ci class C1: 13687db96d56Sopenharmony_ci def __init__(self): 13697db96d56Sopenharmony_ci self.b = 42 13707db96d56Sopenharmony_ci class C2(C1, metaclass=Meta, attr="__classcell__"): 13717db96d56Sopenharmony_ci __slots__ = ["__classcell__"] 13727db96d56Sopenharmony_ci def __init__(self): 13737db96d56Sopenharmony_ci super().__init__() 13747db96d56Sopenharmony_ci self.assertIsInstance(C2.__dict__["__classcell__"], 13757db96d56Sopenharmony_ci types.MemberDescriptorType) 13767db96d56Sopenharmony_ci c = C2() 13777db96d56Sopenharmony_ci self.assertEqual(c.b, 42) 13787db96d56Sopenharmony_ci self.assertNotHasAttr(c, "__classcell__") 13797db96d56Sopenharmony_ci c.__classcell__ = 42 13807db96d56Sopenharmony_ci self.assertEqual(c.__classcell__, 42) 13817db96d56Sopenharmony_ci with self.assertRaises(TypeError): 13827db96d56Sopenharmony_ci class C3: 13837db96d56Sopenharmony_ci __classcell__ = 42 13847db96d56Sopenharmony_ci __slots__ = ["__classcell__"] 13857db96d56Sopenharmony_ci 13867db96d56Sopenharmony_ci class Q1(metaclass=Meta, attr="__qualname__"): 13877db96d56Sopenharmony_ci __slots__ = ["__qualname__"] 13887db96d56Sopenharmony_ci self.assertEqual(Q1.__qualname__, C1.__qualname__[:-2] + "Q1") 13897db96d56Sopenharmony_ci self.assertIsInstance(Q1.__dict__["__qualname__"], 13907db96d56Sopenharmony_ci types.MemberDescriptorType) 13917db96d56Sopenharmony_ci q = Q1() 13927db96d56Sopenharmony_ci self.assertNotHasAttr(q, "__qualname__") 13937db96d56Sopenharmony_ci q.__qualname__ = "q" 13947db96d56Sopenharmony_ci self.assertEqual(q.__qualname__, "q") 13957db96d56Sopenharmony_ci with self.assertRaises(TypeError): 13967db96d56Sopenharmony_ci class Q2: 13977db96d56Sopenharmony_ci __qualname__ = object() 13987db96d56Sopenharmony_ci __slots__ = ["__qualname__"] 13997db96d56Sopenharmony_ci 14007db96d56Sopenharmony_ci def test_slots_descriptor(self): 14017db96d56Sopenharmony_ci # Issue2115: slot descriptors did not correctly check 14027db96d56Sopenharmony_ci # the type of the given object 14037db96d56Sopenharmony_ci import abc 14047db96d56Sopenharmony_ci class MyABC(metaclass=abc.ABCMeta): 14057db96d56Sopenharmony_ci __slots__ = "a" 14067db96d56Sopenharmony_ci 14077db96d56Sopenharmony_ci class Unrelated(object): 14087db96d56Sopenharmony_ci pass 14097db96d56Sopenharmony_ci MyABC.register(Unrelated) 14107db96d56Sopenharmony_ci 14117db96d56Sopenharmony_ci u = Unrelated() 14127db96d56Sopenharmony_ci self.assertIsInstance(u, MyABC) 14137db96d56Sopenharmony_ci 14147db96d56Sopenharmony_ci # This used to crash 14157db96d56Sopenharmony_ci self.assertRaises(TypeError, MyABC.a.__set__, u, 3) 14167db96d56Sopenharmony_ci 14177db96d56Sopenharmony_ci def test_dynamics(self): 14187db96d56Sopenharmony_ci # Testing class attribute propagation... 14197db96d56Sopenharmony_ci class D(object): 14207db96d56Sopenharmony_ci pass 14217db96d56Sopenharmony_ci class E(D): 14227db96d56Sopenharmony_ci pass 14237db96d56Sopenharmony_ci class F(D): 14247db96d56Sopenharmony_ci pass 14257db96d56Sopenharmony_ci D.foo = 1 14267db96d56Sopenharmony_ci self.assertEqual(D.foo, 1) 14277db96d56Sopenharmony_ci # Test that dynamic attributes are inherited 14287db96d56Sopenharmony_ci self.assertEqual(E.foo, 1) 14297db96d56Sopenharmony_ci self.assertEqual(F.foo, 1) 14307db96d56Sopenharmony_ci # Test dynamic instances 14317db96d56Sopenharmony_ci class C(object): 14327db96d56Sopenharmony_ci pass 14337db96d56Sopenharmony_ci a = C() 14347db96d56Sopenharmony_ci self.assertNotHasAttr(a, "foobar") 14357db96d56Sopenharmony_ci C.foobar = 2 14367db96d56Sopenharmony_ci self.assertEqual(a.foobar, 2) 14377db96d56Sopenharmony_ci C.method = lambda self: 42 14387db96d56Sopenharmony_ci self.assertEqual(a.method(), 42) 14397db96d56Sopenharmony_ci C.__repr__ = lambda self: "C()" 14407db96d56Sopenharmony_ci self.assertEqual(repr(a), "C()") 14417db96d56Sopenharmony_ci C.__int__ = lambda self: 100 14427db96d56Sopenharmony_ci self.assertEqual(int(a), 100) 14437db96d56Sopenharmony_ci self.assertEqual(a.foobar, 2) 14447db96d56Sopenharmony_ci self.assertNotHasAttr(a, "spam") 14457db96d56Sopenharmony_ci def mygetattr(self, name): 14467db96d56Sopenharmony_ci if name == "spam": 14477db96d56Sopenharmony_ci return "spam" 14487db96d56Sopenharmony_ci raise AttributeError 14497db96d56Sopenharmony_ci C.__getattr__ = mygetattr 14507db96d56Sopenharmony_ci self.assertEqual(a.spam, "spam") 14517db96d56Sopenharmony_ci a.new = 12 14527db96d56Sopenharmony_ci self.assertEqual(a.new, 12) 14537db96d56Sopenharmony_ci def mysetattr(self, name, value): 14547db96d56Sopenharmony_ci if name == "spam": 14557db96d56Sopenharmony_ci raise AttributeError 14567db96d56Sopenharmony_ci return object.__setattr__(self, name, value) 14577db96d56Sopenharmony_ci C.__setattr__ = mysetattr 14587db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 14597db96d56Sopenharmony_ci a.spam = "not spam" 14607db96d56Sopenharmony_ci 14617db96d56Sopenharmony_ci self.assertEqual(a.spam, "spam") 14627db96d56Sopenharmony_ci class D(C): 14637db96d56Sopenharmony_ci pass 14647db96d56Sopenharmony_ci d = D() 14657db96d56Sopenharmony_ci d.foo = 1 14667db96d56Sopenharmony_ci self.assertEqual(d.foo, 1) 14677db96d56Sopenharmony_ci 14687db96d56Sopenharmony_ci # Test handling of int*seq and seq*int 14697db96d56Sopenharmony_ci class I(int): 14707db96d56Sopenharmony_ci pass 14717db96d56Sopenharmony_ci self.assertEqual("a"*I(2), "aa") 14727db96d56Sopenharmony_ci self.assertEqual(I(2)*"a", "aa") 14737db96d56Sopenharmony_ci self.assertEqual(2*I(3), 6) 14747db96d56Sopenharmony_ci self.assertEqual(I(3)*2, 6) 14757db96d56Sopenharmony_ci self.assertEqual(I(3)*I(2), 6) 14767db96d56Sopenharmony_ci 14777db96d56Sopenharmony_ci # Test comparison of classes with dynamic metaclasses 14787db96d56Sopenharmony_ci class dynamicmetaclass(type): 14797db96d56Sopenharmony_ci pass 14807db96d56Sopenharmony_ci class someclass(metaclass=dynamicmetaclass): 14817db96d56Sopenharmony_ci pass 14827db96d56Sopenharmony_ci self.assertNotEqual(someclass, object) 14837db96d56Sopenharmony_ci 14847db96d56Sopenharmony_ci def test_errors(self): 14857db96d56Sopenharmony_ci # Testing errors... 14867db96d56Sopenharmony_ci try: 14877db96d56Sopenharmony_ci class C(list, dict): 14887db96d56Sopenharmony_ci pass 14897db96d56Sopenharmony_ci except TypeError: 14907db96d56Sopenharmony_ci pass 14917db96d56Sopenharmony_ci else: 14927db96d56Sopenharmony_ci self.fail("inheritance from both list and dict should be illegal") 14937db96d56Sopenharmony_ci 14947db96d56Sopenharmony_ci try: 14957db96d56Sopenharmony_ci class C(object, None): 14967db96d56Sopenharmony_ci pass 14977db96d56Sopenharmony_ci except TypeError: 14987db96d56Sopenharmony_ci pass 14997db96d56Sopenharmony_ci else: 15007db96d56Sopenharmony_ci self.fail("inheritance from non-type should be illegal") 15017db96d56Sopenharmony_ci class Classic: 15027db96d56Sopenharmony_ci pass 15037db96d56Sopenharmony_ci 15047db96d56Sopenharmony_ci try: 15057db96d56Sopenharmony_ci class C(type(len)): 15067db96d56Sopenharmony_ci pass 15077db96d56Sopenharmony_ci except TypeError: 15087db96d56Sopenharmony_ci pass 15097db96d56Sopenharmony_ci else: 15107db96d56Sopenharmony_ci self.fail("inheritance from CFunction should be illegal") 15117db96d56Sopenharmony_ci 15127db96d56Sopenharmony_ci try: 15137db96d56Sopenharmony_ci class C(object): 15147db96d56Sopenharmony_ci __slots__ = 1 15157db96d56Sopenharmony_ci except TypeError: 15167db96d56Sopenharmony_ci pass 15177db96d56Sopenharmony_ci else: 15187db96d56Sopenharmony_ci self.fail("__slots__ = 1 should be illegal") 15197db96d56Sopenharmony_ci 15207db96d56Sopenharmony_ci try: 15217db96d56Sopenharmony_ci class C(object): 15227db96d56Sopenharmony_ci __slots__ = [1] 15237db96d56Sopenharmony_ci except TypeError: 15247db96d56Sopenharmony_ci pass 15257db96d56Sopenharmony_ci else: 15267db96d56Sopenharmony_ci self.fail("__slots__ = [1] should be illegal") 15277db96d56Sopenharmony_ci 15287db96d56Sopenharmony_ci class M1(type): 15297db96d56Sopenharmony_ci pass 15307db96d56Sopenharmony_ci class M2(type): 15317db96d56Sopenharmony_ci pass 15327db96d56Sopenharmony_ci class A1(object, metaclass=M1): 15337db96d56Sopenharmony_ci pass 15347db96d56Sopenharmony_ci class A2(object, metaclass=M2): 15357db96d56Sopenharmony_ci pass 15367db96d56Sopenharmony_ci try: 15377db96d56Sopenharmony_ci class B(A1, A2): 15387db96d56Sopenharmony_ci pass 15397db96d56Sopenharmony_ci except TypeError: 15407db96d56Sopenharmony_ci pass 15417db96d56Sopenharmony_ci else: 15427db96d56Sopenharmony_ci self.fail("finding the most derived metaclass should have failed") 15437db96d56Sopenharmony_ci 15447db96d56Sopenharmony_ci def test_classmethods(self): 15457db96d56Sopenharmony_ci # Testing class methods... 15467db96d56Sopenharmony_ci class C(object): 15477db96d56Sopenharmony_ci def foo(*a): return a 15487db96d56Sopenharmony_ci goo = classmethod(foo) 15497db96d56Sopenharmony_ci c = C() 15507db96d56Sopenharmony_ci self.assertEqual(C.goo(1), (C, 1)) 15517db96d56Sopenharmony_ci self.assertEqual(c.goo(1), (C, 1)) 15527db96d56Sopenharmony_ci self.assertEqual(c.foo(1), (c, 1)) 15537db96d56Sopenharmony_ci class D(C): 15547db96d56Sopenharmony_ci pass 15557db96d56Sopenharmony_ci d = D() 15567db96d56Sopenharmony_ci self.assertEqual(D.goo(1), (D, 1)) 15577db96d56Sopenharmony_ci self.assertEqual(d.goo(1), (D, 1)) 15587db96d56Sopenharmony_ci self.assertEqual(d.foo(1), (d, 1)) 15597db96d56Sopenharmony_ci self.assertEqual(D.foo(d, 1), (d, 1)) 15607db96d56Sopenharmony_ci # Test for a specific crash (SF bug 528132) 15617db96d56Sopenharmony_ci def f(cls, arg): 15627db96d56Sopenharmony_ci "f docstring" 15637db96d56Sopenharmony_ci return (cls, arg) 15647db96d56Sopenharmony_ci ff = classmethod(f) 15657db96d56Sopenharmony_ci self.assertEqual(ff.__get__(0, int)(42), (int, 42)) 15667db96d56Sopenharmony_ci self.assertEqual(ff.__get__(0)(42), (int, 42)) 15677db96d56Sopenharmony_ci 15687db96d56Sopenharmony_ci # Test super() with classmethods (SF bug 535444) 15697db96d56Sopenharmony_ci self.assertEqual(C.goo.__self__, C) 15707db96d56Sopenharmony_ci self.assertEqual(D.goo.__self__, D) 15717db96d56Sopenharmony_ci self.assertEqual(super(D,D).goo.__self__, D) 15727db96d56Sopenharmony_ci self.assertEqual(super(D,d).goo.__self__, D) 15737db96d56Sopenharmony_ci self.assertEqual(super(D,D).goo(), (D,)) 15747db96d56Sopenharmony_ci self.assertEqual(super(D,d).goo(), (D,)) 15757db96d56Sopenharmony_ci 15767db96d56Sopenharmony_ci # Verify that a non-callable will raise 15777db96d56Sopenharmony_ci meth = classmethod(1).__get__(1) 15787db96d56Sopenharmony_ci self.assertRaises(TypeError, meth) 15797db96d56Sopenharmony_ci 15807db96d56Sopenharmony_ci # Verify that classmethod() doesn't allow keyword args 15817db96d56Sopenharmony_ci try: 15827db96d56Sopenharmony_ci classmethod(f, kw=1) 15837db96d56Sopenharmony_ci except TypeError: 15847db96d56Sopenharmony_ci pass 15857db96d56Sopenharmony_ci else: 15867db96d56Sopenharmony_ci self.fail("classmethod shouldn't accept keyword args") 15877db96d56Sopenharmony_ci 15887db96d56Sopenharmony_ci cm = classmethod(f) 15897db96d56Sopenharmony_ci cm_dict = {'__annotations__': {}, 15907db96d56Sopenharmony_ci '__doc__': "f docstring", 15917db96d56Sopenharmony_ci '__module__': __name__, 15927db96d56Sopenharmony_ci '__name__': 'f', 15937db96d56Sopenharmony_ci '__qualname__': f.__qualname__} 15947db96d56Sopenharmony_ci self.assertEqual(cm.__dict__, cm_dict) 15957db96d56Sopenharmony_ci 15967db96d56Sopenharmony_ci cm.x = 42 15977db96d56Sopenharmony_ci self.assertEqual(cm.x, 42) 15987db96d56Sopenharmony_ci self.assertEqual(cm.__dict__, {"x" : 42, **cm_dict}) 15997db96d56Sopenharmony_ci del cm.x 16007db96d56Sopenharmony_ci self.assertNotHasAttr(cm, "x") 16017db96d56Sopenharmony_ci 16027db96d56Sopenharmony_ci @support.refcount_test 16037db96d56Sopenharmony_ci def test_refleaks_in_classmethod___init__(self): 16047db96d56Sopenharmony_ci gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') 16057db96d56Sopenharmony_ci cm = classmethod(None) 16067db96d56Sopenharmony_ci refs_before = gettotalrefcount() 16077db96d56Sopenharmony_ci for i in range(100): 16087db96d56Sopenharmony_ci cm.__init__(None) 16097db96d56Sopenharmony_ci self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) 16107db96d56Sopenharmony_ci 16117db96d56Sopenharmony_ci @support.impl_detail("the module 'xxsubtype' is internal") 16127db96d56Sopenharmony_ci def test_classmethods_in_c(self): 16137db96d56Sopenharmony_ci # Testing C-based class methods... 16147db96d56Sopenharmony_ci import xxsubtype as spam 16157db96d56Sopenharmony_ci a = (1, 2, 3) 16167db96d56Sopenharmony_ci d = {'abc': 123} 16177db96d56Sopenharmony_ci x, a1, d1 = spam.spamlist.classmeth(*a, **d) 16187db96d56Sopenharmony_ci self.assertEqual(x, spam.spamlist) 16197db96d56Sopenharmony_ci self.assertEqual(a, a1) 16207db96d56Sopenharmony_ci self.assertEqual(d, d1) 16217db96d56Sopenharmony_ci x, a1, d1 = spam.spamlist().classmeth(*a, **d) 16227db96d56Sopenharmony_ci self.assertEqual(x, spam.spamlist) 16237db96d56Sopenharmony_ci self.assertEqual(a, a1) 16247db96d56Sopenharmony_ci self.assertEqual(d, d1) 16257db96d56Sopenharmony_ci spam_cm = spam.spamlist.__dict__['classmeth'] 16267db96d56Sopenharmony_ci x2, a2, d2 = spam_cm(spam.spamlist, *a, **d) 16277db96d56Sopenharmony_ci self.assertEqual(x2, spam.spamlist) 16287db96d56Sopenharmony_ci self.assertEqual(a2, a1) 16297db96d56Sopenharmony_ci self.assertEqual(d2, d1) 16307db96d56Sopenharmony_ci class SubSpam(spam.spamlist): pass 16317db96d56Sopenharmony_ci x2, a2, d2 = spam_cm(SubSpam, *a, **d) 16327db96d56Sopenharmony_ci self.assertEqual(x2, SubSpam) 16337db96d56Sopenharmony_ci self.assertEqual(a2, a1) 16347db96d56Sopenharmony_ci self.assertEqual(d2, d1) 16357db96d56Sopenharmony_ci 16367db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 16377db96d56Sopenharmony_ci spam_cm() 16387db96d56Sopenharmony_ci self.assertEqual( 16397db96d56Sopenharmony_ci str(cm.exception), 16407db96d56Sopenharmony_ci "descriptor 'classmeth' of 'xxsubtype.spamlist' " 16417db96d56Sopenharmony_ci "object needs an argument") 16427db96d56Sopenharmony_ci 16437db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 16447db96d56Sopenharmony_ci spam_cm(spam.spamlist()) 16457db96d56Sopenharmony_ci self.assertEqual( 16467db96d56Sopenharmony_ci str(cm.exception), 16477db96d56Sopenharmony_ci "descriptor 'classmeth' for type 'xxsubtype.spamlist' " 16487db96d56Sopenharmony_ci "needs a type, not a 'xxsubtype.spamlist' as arg 2") 16497db96d56Sopenharmony_ci 16507db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 16517db96d56Sopenharmony_ci spam_cm(list) 16527db96d56Sopenharmony_ci expected_errmsg = ( 16537db96d56Sopenharmony_ci "descriptor 'classmeth' requires a subtype of 'xxsubtype.spamlist' " 16547db96d56Sopenharmony_ci "but received 'list'") 16557db96d56Sopenharmony_ci self.assertEqual(str(cm.exception), expected_errmsg) 16567db96d56Sopenharmony_ci 16577db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 16587db96d56Sopenharmony_ci spam_cm.__get__(None, list) 16597db96d56Sopenharmony_ci self.assertEqual(str(cm.exception), expected_errmsg) 16607db96d56Sopenharmony_ci 16617db96d56Sopenharmony_ci def test_staticmethods(self): 16627db96d56Sopenharmony_ci # Testing static methods... 16637db96d56Sopenharmony_ci class C(object): 16647db96d56Sopenharmony_ci def foo(*a): return a 16657db96d56Sopenharmony_ci goo = staticmethod(foo) 16667db96d56Sopenharmony_ci c = C() 16677db96d56Sopenharmony_ci self.assertEqual(C.goo(1), (1,)) 16687db96d56Sopenharmony_ci self.assertEqual(c.goo(1), (1,)) 16697db96d56Sopenharmony_ci self.assertEqual(c.foo(1), (c, 1,)) 16707db96d56Sopenharmony_ci class D(C): 16717db96d56Sopenharmony_ci pass 16727db96d56Sopenharmony_ci d = D() 16737db96d56Sopenharmony_ci self.assertEqual(D.goo(1), (1,)) 16747db96d56Sopenharmony_ci self.assertEqual(d.goo(1), (1,)) 16757db96d56Sopenharmony_ci self.assertEqual(d.foo(1), (d, 1)) 16767db96d56Sopenharmony_ci self.assertEqual(D.foo(d, 1), (d, 1)) 16777db96d56Sopenharmony_ci sm = staticmethod(None) 16787db96d56Sopenharmony_ci self.assertEqual(sm.__dict__, {'__doc__': None}) 16797db96d56Sopenharmony_ci sm.x = 42 16807db96d56Sopenharmony_ci self.assertEqual(sm.x, 42) 16817db96d56Sopenharmony_ci self.assertEqual(sm.__dict__, {"x" : 42, '__doc__': None}) 16827db96d56Sopenharmony_ci del sm.x 16837db96d56Sopenharmony_ci self.assertNotHasAttr(sm, "x") 16847db96d56Sopenharmony_ci 16857db96d56Sopenharmony_ci @support.refcount_test 16867db96d56Sopenharmony_ci def test_refleaks_in_staticmethod___init__(self): 16877db96d56Sopenharmony_ci gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') 16887db96d56Sopenharmony_ci sm = staticmethod(None) 16897db96d56Sopenharmony_ci refs_before = gettotalrefcount() 16907db96d56Sopenharmony_ci for i in range(100): 16917db96d56Sopenharmony_ci sm.__init__(None) 16927db96d56Sopenharmony_ci self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) 16937db96d56Sopenharmony_ci 16947db96d56Sopenharmony_ci @support.impl_detail("the module 'xxsubtype' is internal") 16957db96d56Sopenharmony_ci def test_staticmethods_in_c(self): 16967db96d56Sopenharmony_ci # Testing C-based static methods... 16977db96d56Sopenharmony_ci import xxsubtype as spam 16987db96d56Sopenharmony_ci a = (1, 2, 3) 16997db96d56Sopenharmony_ci d = {"abc": 123} 17007db96d56Sopenharmony_ci x, a1, d1 = spam.spamlist.staticmeth(*a, **d) 17017db96d56Sopenharmony_ci self.assertEqual(x, None) 17027db96d56Sopenharmony_ci self.assertEqual(a, a1) 17037db96d56Sopenharmony_ci self.assertEqual(d, d1) 17047db96d56Sopenharmony_ci x, a1, d2 = spam.spamlist().staticmeth(*a, **d) 17057db96d56Sopenharmony_ci self.assertEqual(x, None) 17067db96d56Sopenharmony_ci self.assertEqual(a, a1) 17077db96d56Sopenharmony_ci self.assertEqual(d, d1) 17087db96d56Sopenharmony_ci 17097db96d56Sopenharmony_ci def test_classic(self): 17107db96d56Sopenharmony_ci # Testing classic classes... 17117db96d56Sopenharmony_ci class C: 17127db96d56Sopenharmony_ci def foo(*a): return a 17137db96d56Sopenharmony_ci goo = classmethod(foo) 17147db96d56Sopenharmony_ci c = C() 17157db96d56Sopenharmony_ci self.assertEqual(C.goo(1), (C, 1)) 17167db96d56Sopenharmony_ci self.assertEqual(c.goo(1), (C, 1)) 17177db96d56Sopenharmony_ci self.assertEqual(c.foo(1), (c, 1)) 17187db96d56Sopenharmony_ci class D(C): 17197db96d56Sopenharmony_ci pass 17207db96d56Sopenharmony_ci d = D() 17217db96d56Sopenharmony_ci self.assertEqual(D.goo(1), (D, 1)) 17227db96d56Sopenharmony_ci self.assertEqual(d.goo(1), (D, 1)) 17237db96d56Sopenharmony_ci self.assertEqual(d.foo(1), (d, 1)) 17247db96d56Sopenharmony_ci self.assertEqual(D.foo(d, 1), (d, 1)) 17257db96d56Sopenharmony_ci class E: # *not* subclassing from C 17267db96d56Sopenharmony_ci foo = C.foo 17277db96d56Sopenharmony_ci self.assertEqual(E().foo.__func__, C.foo) # i.e., unbound 17287db96d56Sopenharmony_ci self.assertTrue(repr(C.foo.__get__(C())).startswith("<bound method ")) 17297db96d56Sopenharmony_ci 17307db96d56Sopenharmony_ci def test_compattr(self): 17317db96d56Sopenharmony_ci # Testing computed attributes... 17327db96d56Sopenharmony_ci class C(object): 17337db96d56Sopenharmony_ci class computed_attribute(object): 17347db96d56Sopenharmony_ci def __init__(self, get, set=None, delete=None): 17357db96d56Sopenharmony_ci self.__get = get 17367db96d56Sopenharmony_ci self.__set = set 17377db96d56Sopenharmony_ci self.__delete = delete 17387db96d56Sopenharmony_ci def __get__(self, obj, type=None): 17397db96d56Sopenharmony_ci return self.__get(obj) 17407db96d56Sopenharmony_ci def __set__(self, obj, value): 17417db96d56Sopenharmony_ci return self.__set(obj, value) 17427db96d56Sopenharmony_ci def __delete__(self, obj): 17437db96d56Sopenharmony_ci return self.__delete(obj) 17447db96d56Sopenharmony_ci def __init__(self): 17457db96d56Sopenharmony_ci self.__x = 0 17467db96d56Sopenharmony_ci def __get_x(self): 17477db96d56Sopenharmony_ci x = self.__x 17487db96d56Sopenharmony_ci self.__x = x+1 17497db96d56Sopenharmony_ci return x 17507db96d56Sopenharmony_ci def __set_x(self, x): 17517db96d56Sopenharmony_ci self.__x = x 17527db96d56Sopenharmony_ci def __delete_x(self): 17537db96d56Sopenharmony_ci del self.__x 17547db96d56Sopenharmony_ci x = computed_attribute(__get_x, __set_x, __delete_x) 17557db96d56Sopenharmony_ci a = C() 17567db96d56Sopenharmony_ci self.assertEqual(a.x, 0) 17577db96d56Sopenharmony_ci self.assertEqual(a.x, 1) 17587db96d56Sopenharmony_ci a.x = 10 17597db96d56Sopenharmony_ci self.assertEqual(a.x, 10) 17607db96d56Sopenharmony_ci self.assertEqual(a.x, 11) 17617db96d56Sopenharmony_ci del a.x 17627db96d56Sopenharmony_ci self.assertNotHasAttr(a, 'x') 17637db96d56Sopenharmony_ci 17647db96d56Sopenharmony_ci def test_newslots(self): 17657db96d56Sopenharmony_ci # Testing __new__ slot override... 17667db96d56Sopenharmony_ci class C(list): 17677db96d56Sopenharmony_ci def __new__(cls): 17687db96d56Sopenharmony_ci self = list.__new__(cls) 17697db96d56Sopenharmony_ci self.foo = 1 17707db96d56Sopenharmony_ci return self 17717db96d56Sopenharmony_ci def __init__(self): 17727db96d56Sopenharmony_ci self.foo = self.foo + 2 17737db96d56Sopenharmony_ci a = C() 17747db96d56Sopenharmony_ci self.assertEqual(a.foo, 3) 17757db96d56Sopenharmony_ci self.assertEqual(a.__class__, C) 17767db96d56Sopenharmony_ci class D(C): 17777db96d56Sopenharmony_ci pass 17787db96d56Sopenharmony_ci b = D() 17797db96d56Sopenharmony_ci self.assertEqual(b.foo, 3) 17807db96d56Sopenharmony_ci self.assertEqual(b.__class__, D) 17817db96d56Sopenharmony_ci 17827db96d56Sopenharmony_ci @unittest.expectedFailure 17837db96d56Sopenharmony_ci def test_bad_new(self): 17847db96d56Sopenharmony_ci self.assertRaises(TypeError, object.__new__) 17857db96d56Sopenharmony_ci self.assertRaises(TypeError, object.__new__, '') 17867db96d56Sopenharmony_ci self.assertRaises(TypeError, list.__new__, object) 17877db96d56Sopenharmony_ci self.assertRaises(TypeError, object.__new__, list) 17887db96d56Sopenharmony_ci class C(object): 17897db96d56Sopenharmony_ci __new__ = list.__new__ 17907db96d56Sopenharmony_ci self.assertRaises(TypeError, C) 17917db96d56Sopenharmony_ci class C(list): 17927db96d56Sopenharmony_ci __new__ = object.__new__ 17937db96d56Sopenharmony_ci self.assertRaises(TypeError, C) 17947db96d56Sopenharmony_ci 17957db96d56Sopenharmony_ci def test_object_new(self): 17967db96d56Sopenharmony_ci class A(object): 17977db96d56Sopenharmony_ci pass 17987db96d56Sopenharmony_ci object.__new__(A) 17997db96d56Sopenharmony_ci self.assertRaises(TypeError, object.__new__, A, 5) 18007db96d56Sopenharmony_ci object.__init__(A()) 18017db96d56Sopenharmony_ci self.assertRaises(TypeError, object.__init__, A(), 5) 18027db96d56Sopenharmony_ci 18037db96d56Sopenharmony_ci class A(object): 18047db96d56Sopenharmony_ci def __init__(self, foo): 18057db96d56Sopenharmony_ci self.foo = foo 18067db96d56Sopenharmony_ci object.__new__(A) 18077db96d56Sopenharmony_ci object.__new__(A, 5) 18087db96d56Sopenharmony_ci object.__init__(A(3)) 18097db96d56Sopenharmony_ci self.assertRaises(TypeError, object.__init__, A(3), 5) 18107db96d56Sopenharmony_ci 18117db96d56Sopenharmony_ci class A(object): 18127db96d56Sopenharmony_ci def __new__(cls, foo): 18137db96d56Sopenharmony_ci return object.__new__(cls) 18147db96d56Sopenharmony_ci object.__new__(A) 18157db96d56Sopenharmony_ci self.assertRaises(TypeError, object.__new__, A, 5) 18167db96d56Sopenharmony_ci object.__init__(A(3)) 18177db96d56Sopenharmony_ci object.__init__(A(3), 5) 18187db96d56Sopenharmony_ci 18197db96d56Sopenharmony_ci class A(object): 18207db96d56Sopenharmony_ci def __new__(cls, foo): 18217db96d56Sopenharmony_ci return object.__new__(cls) 18227db96d56Sopenharmony_ci def __init__(self, foo): 18237db96d56Sopenharmony_ci self.foo = foo 18247db96d56Sopenharmony_ci object.__new__(A) 18257db96d56Sopenharmony_ci self.assertRaises(TypeError, object.__new__, A, 5) 18267db96d56Sopenharmony_ci object.__init__(A(3)) 18277db96d56Sopenharmony_ci self.assertRaises(TypeError, object.__init__, A(3), 5) 18287db96d56Sopenharmony_ci 18297db96d56Sopenharmony_ci @unittest.expectedFailure 18307db96d56Sopenharmony_ci def test_restored_object_new(self): 18317db96d56Sopenharmony_ci class A(object): 18327db96d56Sopenharmony_ci def __new__(cls, *args, **kwargs): 18337db96d56Sopenharmony_ci raise AssertionError 18347db96d56Sopenharmony_ci self.assertRaises(AssertionError, A) 18357db96d56Sopenharmony_ci class B(A): 18367db96d56Sopenharmony_ci __new__ = object.__new__ 18377db96d56Sopenharmony_ci def __init__(self, foo): 18387db96d56Sopenharmony_ci self.foo = foo 18397db96d56Sopenharmony_ci with warnings.catch_warnings(): 18407db96d56Sopenharmony_ci warnings.simplefilter('error', DeprecationWarning) 18417db96d56Sopenharmony_ci b = B(3) 18427db96d56Sopenharmony_ci self.assertEqual(b.foo, 3) 18437db96d56Sopenharmony_ci self.assertEqual(b.__class__, B) 18447db96d56Sopenharmony_ci del B.__new__ 18457db96d56Sopenharmony_ci self.assertRaises(AssertionError, B) 18467db96d56Sopenharmony_ci del A.__new__ 18477db96d56Sopenharmony_ci with warnings.catch_warnings(): 18487db96d56Sopenharmony_ci warnings.simplefilter('error', DeprecationWarning) 18497db96d56Sopenharmony_ci b = B(3) 18507db96d56Sopenharmony_ci self.assertEqual(b.foo, 3) 18517db96d56Sopenharmony_ci self.assertEqual(b.__class__, B) 18527db96d56Sopenharmony_ci 18537db96d56Sopenharmony_ci def test_altmro(self): 18547db96d56Sopenharmony_ci # Testing mro() and overriding it... 18557db96d56Sopenharmony_ci class A(object): 18567db96d56Sopenharmony_ci def f(self): return "A" 18577db96d56Sopenharmony_ci class B(A): 18587db96d56Sopenharmony_ci pass 18597db96d56Sopenharmony_ci class C(A): 18607db96d56Sopenharmony_ci def f(self): return "C" 18617db96d56Sopenharmony_ci class D(B, C): 18627db96d56Sopenharmony_ci pass 18637db96d56Sopenharmony_ci self.assertEqual(A.mro(), [A, object]) 18647db96d56Sopenharmony_ci self.assertEqual(A.__mro__, (A, object)) 18657db96d56Sopenharmony_ci self.assertEqual(B.mro(), [B, A, object]) 18667db96d56Sopenharmony_ci self.assertEqual(B.__mro__, (B, A, object)) 18677db96d56Sopenharmony_ci self.assertEqual(C.mro(), [C, A, object]) 18687db96d56Sopenharmony_ci self.assertEqual(C.__mro__, (C, A, object)) 18697db96d56Sopenharmony_ci self.assertEqual(D.mro(), [D, B, C, A, object]) 18707db96d56Sopenharmony_ci self.assertEqual(D.__mro__, (D, B, C, A, object)) 18717db96d56Sopenharmony_ci self.assertEqual(D().f(), "C") 18727db96d56Sopenharmony_ci 18737db96d56Sopenharmony_ci class PerverseMetaType(type): 18747db96d56Sopenharmony_ci def mro(cls): 18757db96d56Sopenharmony_ci L = type.mro(cls) 18767db96d56Sopenharmony_ci L.reverse() 18777db96d56Sopenharmony_ci return L 18787db96d56Sopenharmony_ci class X(D,B,C,A, metaclass=PerverseMetaType): 18797db96d56Sopenharmony_ci pass 18807db96d56Sopenharmony_ci self.assertEqual(X.__mro__, (object, A, C, B, D, X)) 18817db96d56Sopenharmony_ci self.assertEqual(X().f(), "A") 18827db96d56Sopenharmony_ci 18837db96d56Sopenharmony_ci try: 18847db96d56Sopenharmony_ci class _metaclass(type): 18857db96d56Sopenharmony_ci def mro(self): 18867db96d56Sopenharmony_ci return [self, dict, object] 18877db96d56Sopenharmony_ci class X(object, metaclass=_metaclass): 18887db96d56Sopenharmony_ci pass 18897db96d56Sopenharmony_ci # In CPython, the class creation above already raises 18907db96d56Sopenharmony_ci # TypeError, as a protection against the fact that 18917db96d56Sopenharmony_ci # instances of X would segfault it. In other Python 18927db96d56Sopenharmony_ci # implementations it would be ok to let the class X 18937db96d56Sopenharmony_ci # be created, but instead get a clean TypeError on the 18947db96d56Sopenharmony_ci # __setitem__ below. 18957db96d56Sopenharmony_ci x = object.__new__(X) 18967db96d56Sopenharmony_ci x[5] = 6 18977db96d56Sopenharmony_ci except TypeError: 18987db96d56Sopenharmony_ci pass 18997db96d56Sopenharmony_ci else: 19007db96d56Sopenharmony_ci self.fail("devious mro() return not caught") 19017db96d56Sopenharmony_ci 19027db96d56Sopenharmony_ci try: 19037db96d56Sopenharmony_ci class _metaclass(type): 19047db96d56Sopenharmony_ci def mro(self): 19057db96d56Sopenharmony_ci return [1] 19067db96d56Sopenharmony_ci class X(object, metaclass=_metaclass): 19077db96d56Sopenharmony_ci pass 19087db96d56Sopenharmony_ci except TypeError: 19097db96d56Sopenharmony_ci pass 19107db96d56Sopenharmony_ci else: 19117db96d56Sopenharmony_ci self.fail("non-class mro() return not caught") 19127db96d56Sopenharmony_ci 19137db96d56Sopenharmony_ci try: 19147db96d56Sopenharmony_ci class _metaclass(type): 19157db96d56Sopenharmony_ci def mro(self): 19167db96d56Sopenharmony_ci return 1 19177db96d56Sopenharmony_ci class X(object, metaclass=_metaclass): 19187db96d56Sopenharmony_ci pass 19197db96d56Sopenharmony_ci except TypeError: 19207db96d56Sopenharmony_ci pass 19217db96d56Sopenharmony_ci else: 19227db96d56Sopenharmony_ci self.fail("non-sequence mro() return not caught") 19237db96d56Sopenharmony_ci 19247db96d56Sopenharmony_ci def test_overloading(self): 19257db96d56Sopenharmony_ci # Testing operator overloading... 19267db96d56Sopenharmony_ci 19277db96d56Sopenharmony_ci class B(object): 19287db96d56Sopenharmony_ci "Intermediate class because object doesn't have a __setattr__" 19297db96d56Sopenharmony_ci 19307db96d56Sopenharmony_ci class C(B): 19317db96d56Sopenharmony_ci def __getattr__(self, name): 19327db96d56Sopenharmony_ci if name == "foo": 19337db96d56Sopenharmony_ci return ("getattr", name) 19347db96d56Sopenharmony_ci else: 19357db96d56Sopenharmony_ci raise AttributeError 19367db96d56Sopenharmony_ci def __setattr__(self, name, value): 19377db96d56Sopenharmony_ci if name == "foo": 19387db96d56Sopenharmony_ci self.setattr = (name, value) 19397db96d56Sopenharmony_ci else: 19407db96d56Sopenharmony_ci return B.__setattr__(self, name, value) 19417db96d56Sopenharmony_ci def __delattr__(self, name): 19427db96d56Sopenharmony_ci if name == "foo": 19437db96d56Sopenharmony_ci self.delattr = name 19447db96d56Sopenharmony_ci else: 19457db96d56Sopenharmony_ci return B.__delattr__(self, name) 19467db96d56Sopenharmony_ci 19477db96d56Sopenharmony_ci def __getitem__(self, key): 19487db96d56Sopenharmony_ci return ("getitem", key) 19497db96d56Sopenharmony_ci def __setitem__(self, key, value): 19507db96d56Sopenharmony_ci self.setitem = (key, value) 19517db96d56Sopenharmony_ci def __delitem__(self, key): 19527db96d56Sopenharmony_ci self.delitem = key 19537db96d56Sopenharmony_ci 19547db96d56Sopenharmony_ci a = C() 19557db96d56Sopenharmony_ci self.assertEqual(a.foo, ("getattr", "foo")) 19567db96d56Sopenharmony_ci a.foo = 12 19577db96d56Sopenharmony_ci self.assertEqual(a.setattr, ("foo", 12)) 19587db96d56Sopenharmony_ci del a.foo 19597db96d56Sopenharmony_ci self.assertEqual(a.delattr, "foo") 19607db96d56Sopenharmony_ci 19617db96d56Sopenharmony_ci self.assertEqual(a[12], ("getitem", 12)) 19627db96d56Sopenharmony_ci a[12] = 21 19637db96d56Sopenharmony_ci self.assertEqual(a.setitem, (12, 21)) 19647db96d56Sopenharmony_ci del a[12] 19657db96d56Sopenharmony_ci self.assertEqual(a.delitem, 12) 19667db96d56Sopenharmony_ci 19677db96d56Sopenharmony_ci self.assertEqual(a[0:10], ("getitem", slice(0, 10))) 19687db96d56Sopenharmony_ci a[0:10] = "foo" 19697db96d56Sopenharmony_ci self.assertEqual(a.setitem, (slice(0, 10), "foo")) 19707db96d56Sopenharmony_ci del a[0:10] 19717db96d56Sopenharmony_ci self.assertEqual(a.delitem, (slice(0, 10))) 19727db96d56Sopenharmony_ci 19737db96d56Sopenharmony_ci def test_load_attr_extended_arg(self): 19747db96d56Sopenharmony_ci # https://github.com/python/cpython/issues/91625 19757db96d56Sopenharmony_ci class Numbers: 19767db96d56Sopenharmony_ci def __getattr__(self, attr): 19777db96d56Sopenharmony_ci return int(attr.lstrip("_")) 19787db96d56Sopenharmony_ci attrs = ", ".join(f"Z._{n:03d}" for n in range(280)) 19797db96d56Sopenharmony_ci code = f"def number_attrs(Z):\n return [ {attrs} ]" 19807db96d56Sopenharmony_ci ns = {} 19817db96d56Sopenharmony_ci exec(code, ns) 19827db96d56Sopenharmony_ci number_attrs = ns["number_attrs"] 19837db96d56Sopenharmony_ci # Warm up the the function for quickening (PEP 659) 19847db96d56Sopenharmony_ci for _ in range(30): 19857db96d56Sopenharmony_ci self.assertEqual(number_attrs(Numbers()), list(range(280))) 19867db96d56Sopenharmony_ci 19877db96d56Sopenharmony_ci def test_methods(self): 19887db96d56Sopenharmony_ci # Testing methods... 19897db96d56Sopenharmony_ci class C(object): 19907db96d56Sopenharmony_ci def __init__(self, x): 19917db96d56Sopenharmony_ci self.x = x 19927db96d56Sopenharmony_ci def foo(self): 19937db96d56Sopenharmony_ci return self.x 19947db96d56Sopenharmony_ci c1 = C(1) 19957db96d56Sopenharmony_ci self.assertEqual(c1.foo(), 1) 19967db96d56Sopenharmony_ci class D(C): 19977db96d56Sopenharmony_ci boo = C.foo 19987db96d56Sopenharmony_ci goo = c1.foo 19997db96d56Sopenharmony_ci d2 = D(2) 20007db96d56Sopenharmony_ci self.assertEqual(d2.foo(), 2) 20017db96d56Sopenharmony_ci self.assertEqual(d2.boo(), 2) 20027db96d56Sopenharmony_ci self.assertEqual(d2.goo(), 1) 20037db96d56Sopenharmony_ci class E(object): 20047db96d56Sopenharmony_ci foo = C.foo 20057db96d56Sopenharmony_ci self.assertEqual(E().foo.__func__, C.foo) # i.e., unbound 20067db96d56Sopenharmony_ci self.assertTrue(repr(C.foo.__get__(C(1))).startswith("<bound method ")) 20077db96d56Sopenharmony_ci 20087db96d56Sopenharmony_ci @support.impl_detail("testing error message from implementation") 20097db96d56Sopenharmony_ci def test_methods_in_c(self): 20107db96d56Sopenharmony_ci # This test checks error messages in builtin method descriptor. 20117db96d56Sopenharmony_ci # It is allowed that other Python implementations use 20127db96d56Sopenharmony_ci # different error messages. 20137db96d56Sopenharmony_ci set_add = set.add 20147db96d56Sopenharmony_ci 20157db96d56Sopenharmony_ci expected_errmsg = "unbound method set.add() needs an argument" 20167db96d56Sopenharmony_ci 20177db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 20187db96d56Sopenharmony_ci set_add() 20197db96d56Sopenharmony_ci self.assertEqual(cm.exception.args[0], expected_errmsg) 20207db96d56Sopenharmony_ci 20217db96d56Sopenharmony_ci expected_errmsg = "descriptor 'add' for 'set' objects doesn't apply to a 'int' object" 20227db96d56Sopenharmony_ci 20237db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 20247db96d56Sopenharmony_ci set_add(0) 20257db96d56Sopenharmony_ci self.assertEqual(cm.exception.args[0], expected_errmsg) 20267db96d56Sopenharmony_ci 20277db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 20287db96d56Sopenharmony_ci set_add.__get__(0) 20297db96d56Sopenharmony_ci self.assertEqual(cm.exception.args[0], expected_errmsg) 20307db96d56Sopenharmony_ci 20317db96d56Sopenharmony_ci def test_special_method_lookup(self): 20327db96d56Sopenharmony_ci # The lookup of special methods bypasses __getattr__ and 20337db96d56Sopenharmony_ci # __getattribute__, but they still can be descriptors. 20347db96d56Sopenharmony_ci 20357db96d56Sopenharmony_ci def run_context(manager): 20367db96d56Sopenharmony_ci with manager: 20377db96d56Sopenharmony_ci pass 20387db96d56Sopenharmony_ci def iden(self): 20397db96d56Sopenharmony_ci return self 20407db96d56Sopenharmony_ci def hello(self): 20417db96d56Sopenharmony_ci return b"hello" 20427db96d56Sopenharmony_ci def empty_seq(self): 20437db96d56Sopenharmony_ci return [] 20447db96d56Sopenharmony_ci def zero(self): 20457db96d56Sopenharmony_ci return 0 20467db96d56Sopenharmony_ci def complex_num(self): 20477db96d56Sopenharmony_ci return 1j 20487db96d56Sopenharmony_ci def stop(self): 20497db96d56Sopenharmony_ci raise StopIteration 20507db96d56Sopenharmony_ci def return_true(self, thing=None): 20517db96d56Sopenharmony_ci return True 20527db96d56Sopenharmony_ci def do_isinstance(obj): 20537db96d56Sopenharmony_ci return isinstance(int, obj) 20547db96d56Sopenharmony_ci def do_issubclass(obj): 20557db96d56Sopenharmony_ci return issubclass(int, obj) 20567db96d56Sopenharmony_ci def do_dict_missing(checker): 20577db96d56Sopenharmony_ci class DictSub(checker.__class__, dict): 20587db96d56Sopenharmony_ci pass 20597db96d56Sopenharmony_ci self.assertEqual(DictSub()["hi"], 4) 20607db96d56Sopenharmony_ci def some_number(self_, key): 20617db96d56Sopenharmony_ci self.assertEqual(key, "hi") 20627db96d56Sopenharmony_ci return 4 20637db96d56Sopenharmony_ci def swallow(*args): pass 20647db96d56Sopenharmony_ci def format_impl(self, spec): 20657db96d56Sopenharmony_ci return "hello" 20667db96d56Sopenharmony_ci 20677db96d56Sopenharmony_ci # It would be nice to have every special method tested here, but I'm 20687db96d56Sopenharmony_ci # only listing the ones I can remember outside of typeobject.c, since it 20697db96d56Sopenharmony_ci # does it right. 20707db96d56Sopenharmony_ci specials = [ 20717db96d56Sopenharmony_ci ("__bytes__", bytes, hello, set(), {}), 20727db96d56Sopenharmony_ci ("__reversed__", reversed, empty_seq, set(), {}), 20737db96d56Sopenharmony_ci ("__length_hint__", list, zero, set(), 20747db96d56Sopenharmony_ci {"__iter__" : iden, "__next__" : stop}), 20757db96d56Sopenharmony_ci ("__sizeof__", sys.getsizeof, zero, set(), {}), 20767db96d56Sopenharmony_ci ("__instancecheck__", do_isinstance, return_true, set(), {}), 20777db96d56Sopenharmony_ci ("__missing__", do_dict_missing, some_number, 20787db96d56Sopenharmony_ci set(("__class__",)), {}), 20797db96d56Sopenharmony_ci ("__subclasscheck__", do_issubclass, return_true, 20807db96d56Sopenharmony_ci set(("__bases__",)), {}), 20817db96d56Sopenharmony_ci ("__enter__", run_context, iden, set(), {"__exit__" : swallow}), 20827db96d56Sopenharmony_ci ("__exit__", run_context, swallow, set(), {"__enter__" : iden}), 20837db96d56Sopenharmony_ci ("__complex__", complex, complex_num, set(), {}), 20847db96d56Sopenharmony_ci ("__format__", format, format_impl, set(), {}), 20857db96d56Sopenharmony_ci ("__floor__", math.floor, zero, set(), {}), 20867db96d56Sopenharmony_ci ("__trunc__", math.trunc, zero, set(), {}), 20877db96d56Sopenharmony_ci ("__ceil__", math.ceil, zero, set(), {}), 20887db96d56Sopenharmony_ci ("__dir__", dir, empty_seq, set(), {}), 20897db96d56Sopenharmony_ci ("__round__", round, zero, set(), {}), 20907db96d56Sopenharmony_ci ] 20917db96d56Sopenharmony_ci 20927db96d56Sopenharmony_ci class Checker(object): 20937db96d56Sopenharmony_ci def __getattr__(self, attr, test=self): 20947db96d56Sopenharmony_ci test.fail("__getattr__ called with {0}".format(attr)) 20957db96d56Sopenharmony_ci def __getattribute__(self, attr, test=self): 20967db96d56Sopenharmony_ci if attr not in ok: 20977db96d56Sopenharmony_ci test.fail("__getattribute__ called with {0}".format(attr)) 20987db96d56Sopenharmony_ci return object.__getattribute__(self, attr) 20997db96d56Sopenharmony_ci class SpecialDescr(object): 21007db96d56Sopenharmony_ci def __init__(self, impl): 21017db96d56Sopenharmony_ci self.impl = impl 21027db96d56Sopenharmony_ci def __get__(self, obj, owner): 21037db96d56Sopenharmony_ci record.append(1) 21047db96d56Sopenharmony_ci return self.impl.__get__(obj, owner) 21057db96d56Sopenharmony_ci class MyException(Exception): 21067db96d56Sopenharmony_ci pass 21077db96d56Sopenharmony_ci class ErrDescr(object): 21087db96d56Sopenharmony_ci def __get__(self, obj, owner): 21097db96d56Sopenharmony_ci raise MyException 21107db96d56Sopenharmony_ci 21117db96d56Sopenharmony_ci for name, runner, meth_impl, ok, env in specials: 21127db96d56Sopenharmony_ci class X(Checker): 21137db96d56Sopenharmony_ci pass 21147db96d56Sopenharmony_ci for attr, obj in env.items(): 21157db96d56Sopenharmony_ci setattr(X, attr, obj) 21167db96d56Sopenharmony_ci setattr(X, name, meth_impl) 21177db96d56Sopenharmony_ci runner(X()) 21187db96d56Sopenharmony_ci 21197db96d56Sopenharmony_ci record = [] 21207db96d56Sopenharmony_ci class X(Checker): 21217db96d56Sopenharmony_ci pass 21227db96d56Sopenharmony_ci for attr, obj in env.items(): 21237db96d56Sopenharmony_ci setattr(X, attr, obj) 21247db96d56Sopenharmony_ci setattr(X, name, SpecialDescr(meth_impl)) 21257db96d56Sopenharmony_ci runner(X()) 21267db96d56Sopenharmony_ci self.assertEqual(record, [1], name) 21277db96d56Sopenharmony_ci 21287db96d56Sopenharmony_ci class X(Checker): 21297db96d56Sopenharmony_ci pass 21307db96d56Sopenharmony_ci for attr, obj in env.items(): 21317db96d56Sopenharmony_ci setattr(X, attr, obj) 21327db96d56Sopenharmony_ci setattr(X, name, ErrDescr()) 21337db96d56Sopenharmony_ci self.assertRaises(MyException, runner, X()) 21347db96d56Sopenharmony_ci 21357db96d56Sopenharmony_ci def test_specials(self): 21367db96d56Sopenharmony_ci # Testing special operators... 21377db96d56Sopenharmony_ci # Test operators like __hash__ for which a built-in default exists 21387db96d56Sopenharmony_ci 21397db96d56Sopenharmony_ci # Test the default behavior for static classes 21407db96d56Sopenharmony_ci class C(object): 21417db96d56Sopenharmony_ci def __getitem__(self, i): 21427db96d56Sopenharmony_ci if 0 <= i < 10: return i 21437db96d56Sopenharmony_ci raise IndexError 21447db96d56Sopenharmony_ci c1 = C() 21457db96d56Sopenharmony_ci c2 = C() 21467db96d56Sopenharmony_ci self.assertFalse(not c1) 21477db96d56Sopenharmony_ci self.assertNotEqual(id(c1), id(c2)) 21487db96d56Sopenharmony_ci hash(c1) 21497db96d56Sopenharmony_ci hash(c2) 21507db96d56Sopenharmony_ci self.assertEqual(c1, c1) 21517db96d56Sopenharmony_ci self.assertTrue(c1 != c2) 21527db96d56Sopenharmony_ci self.assertFalse(c1 != c1) 21537db96d56Sopenharmony_ci self.assertFalse(c1 == c2) 21547db96d56Sopenharmony_ci # Note that the module name appears in str/repr, and that varies 21557db96d56Sopenharmony_ci # depending on whether this test is run standalone or from a framework. 21567db96d56Sopenharmony_ci self.assertGreaterEqual(str(c1).find('C object at '), 0) 21577db96d56Sopenharmony_ci self.assertEqual(str(c1), repr(c1)) 21587db96d56Sopenharmony_ci self.assertNotIn(-1, c1) 21597db96d56Sopenharmony_ci for i in range(10): 21607db96d56Sopenharmony_ci self.assertIn(i, c1) 21617db96d56Sopenharmony_ci self.assertNotIn(10, c1) 21627db96d56Sopenharmony_ci # Test the default behavior for dynamic classes 21637db96d56Sopenharmony_ci class D(object): 21647db96d56Sopenharmony_ci def __getitem__(self, i): 21657db96d56Sopenharmony_ci if 0 <= i < 10: return i 21667db96d56Sopenharmony_ci raise IndexError 21677db96d56Sopenharmony_ci d1 = D() 21687db96d56Sopenharmony_ci d2 = D() 21697db96d56Sopenharmony_ci self.assertFalse(not d1) 21707db96d56Sopenharmony_ci self.assertNotEqual(id(d1), id(d2)) 21717db96d56Sopenharmony_ci hash(d1) 21727db96d56Sopenharmony_ci hash(d2) 21737db96d56Sopenharmony_ci self.assertEqual(d1, d1) 21747db96d56Sopenharmony_ci self.assertNotEqual(d1, d2) 21757db96d56Sopenharmony_ci self.assertFalse(d1 != d1) 21767db96d56Sopenharmony_ci self.assertFalse(d1 == d2) 21777db96d56Sopenharmony_ci # Note that the module name appears in str/repr, and that varies 21787db96d56Sopenharmony_ci # depending on whether this test is run standalone or from a framework. 21797db96d56Sopenharmony_ci self.assertGreaterEqual(str(d1).find('D object at '), 0) 21807db96d56Sopenharmony_ci self.assertEqual(str(d1), repr(d1)) 21817db96d56Sopenharmony_ci self.assertNotIn(-1, d1) 21827db96d56Sopenharmony_ci for i in range(10): 21837db96d56Sopenharmony_ci self.assertIn(i, d1) 21847db96d56Sopenharmony_ci self.assertNotIn(10, d1) 21857db96d56Sopenharmony_ci # Test overridden behavior 21867db96d56Sopenharmony_ci class Proxy(object): 21877db96d56Sopenharmony_ci def __init__(self, x): 21887db96d56Sopenharmony_ci self.x = x 21897db96d56Sopenharmony_ci def __bool__(self): 21907db96d56Sopenharmony_ci return not not self.x 21917db96d56Sopenharmony_ci def __hash__(self): 21927db96d56Sopenharmony_ci return hash(self.x) 21937db96d56Sopenharmony_ci def __eq__(self, other): 21947db96d56Sopenharmony_ci return self.x == other 21957db96d56Sopenharmony_ci def __ne__(self, other): 21967db96d56Sopenharmony_ci return self.x != other 21977db96d56Sopenharmony_ci def __ge__(self, other): 21987db96d56Sopenharmony_ci return self.x >= other 21997db96d56Sopenharmony_ci def __gt__(self, other): 22007db96d56Sopenharmony_ci return self.x > other 22017db96d56Sopenharmony_ci def __le__(self, other): 22027db96d56Sopenharmony_ci return self.x <= other 22037db96d56Sopenharmony_ci def __lt__(self, other): 22047db96d56Sopenharmony_ci return self.x < other 22057db96d56Sopenharmony_ci def __str__(self): 22067db96d56Sopenharmony_ci return "Proxy:%s" % self.x 22077db96d56Sopenharmony_ci def __repr__(self): 22087db96d56Sopenharmony_ci return "Proxy(%r)" % self.x 22097db96d56Sopenharmony_ci def __contains__(self, value): 22107db96d56Sopenharmony_ci return value in self.x 22117db96d56Sopenharmony_ci p0 = Proxy(0) 22127db96d56Sopenharmony_ci p1 = Proxy(1) 22137db96d56Sopenharmony_ci p_1 = Proxy(-1) 22147db96d56Sopenharmony_ci self.assertFalse(p0) 22157db96d56Sopenharmony_ci self.assertFalse(not p1) 22167db96d56Sopenharmony_ci self.assertEqual(hash(p0), hash(0)) 22177db96d56Sopenharmony_ci self.assertEqual(p0, p0) 22187db96d56Sopenharmony_ci self.assertNotEqual(p0, p1) 22197db96d56Sopenharmony_ci self.assertFalse(p0 != p0) 22207db96d56Sopenharmony_ci self.assertEqual(not p0, p1) 22217db96d56Sopenharmony_ci self.assertTrue(p0 < p1) 22227db96d56Sopenharmony_ci self.assertTrue(p0 <= p1) 22237db96d56Sopenharmony_ci self.assertTrue(p1 > p0) 22247db96d56Sopenharmony_ci self.assertTrue(p1 >= p0) 22257db96d56Sopenharmony_ci self.assertEqual(str(p0), "Proxy:0") 22267db96d56Sopenharmony_ci self.assertEqual(repr(p0), "Proxy(0)") 22277db96d56Sopenharmony_ci p10 = Proxy(range(10)) 22287db96d56Sopenharmony_ci self.assertNotIn(-1, p10) 22297db96d56Sopenharmony_ci for i in range(10): 22307db96d56Sopenharmony_ci self.assertIn(i, p10) 22317db96d56Sopenharmony_ci self.assertNotIn(10, p10) 22327db96d56Sopenharmony_ci 22337db96d56Sopenharmony_ci def test_weakrefs(self): 22347db96d56Sopenharmony_ci # Testing weak references... 22357db96d56Sopenharmony_ci import weakref 22367db96d56Sopenharmony_ci class C(object): 22377db96d56Sopenharmony_ci pass 22387db96d56Sopenharmony_ci c = C() 22397db96d56Sopenharmony_ci r = weakref.ref(c) 22407db96d56Sopenharmony_ci self.assertEqual(r(), c) 22417db96d56Sopenharmony_ci del c 22427db96d56Sopenharmony_ci support.gc_collect() 22437db96d56Sopenharmony_ci self.assertEqual(r(), None) 22447db96d56Sopenharmony_ci del r 22457db96d56Sopenharmony_ci class NoWeak(object): 22467db96d56Sopenharmony_ci __slots__ = ['foo'] 22477db96d56Sopenharmony_ci no = NoWeak() 22487db96d56Sopenharmony_ci try: 22497db96d56Sopenharmony_ci weakref.ref(no) 22507db96d56Sopenharmony_ci except TypeError as msg: 22517db96d56Sopenharmony_ci self.assertIn("weak reference", str(msg)) 22527db96d56Sopenharmony_ci else: 22537db96d56Sopenharmony_ci self.fail("weakref.ref(no) should be illegal") 22547db96d56Sopenharmony_ci class Weak(object): 22557db96d56Sopenharmony_ci __slots__ = ['foo', '__weakref__'] 22567db96d56Sopenharmony_ci yes = Weak() 22577db96d56Sopenharmony_ci r = weakref.ref(yes) 22587db96d56Sopenharmony_ci self.assertEqual(r(), yes) 22597db96d56Sopenharmony_ci del yes 22607db96d56Sopenharmony_ci support.gc_collect() 22617db96d56Sopenharmony_ci self.assertEqual(r(), None) 22627db96d56Sopenharmony_ci del r 22637db96d56Sopenharmony_ci 22647db96d56Sopenharmony_ci def test_properties(self): 22657db96d56Sopenharmony_ci # Testing property... 22667db96d56Sopenharmony_ci class C(object): 22677db96d56Sopenharmony_ci def getx(self): 22687db96d56Sopenharmony_ci return self.__x 22697db96d56Sopenharmony_ci def setx(self, value): 22707db96d56Sopenharmony_ci self.__x = value 22717db96d56Sopenharmony_ci def delx(self): 22727db96d56Sopenharmony_ci del self.__x 22737db96d56Sopenharmony_ci x = property(getx, setx, delx, doc="I'm the x property.") 22747db96d56Sopenharmony_ci a = C() 22757db96d56Sopenharmony_ci self.assertNotHasAttr(a, "x") 22767db96d56Sopenharmony_ci a.x = 42 22777db96d56Sopenharmony_ci self.assertEqual(a._C__x, 42) 22787db96d56Sopenharmony_ci self.assertEqual(a.x, 42) 22797db96d56Sopenharmony_ci del a.x 22807db96d56Sopenharmony_ci self.assertNotHasAttr(a, "x") 22817db96d56Sopenharmony_ci self.assertNotHasAttr(a, "_C__x") 22827db96d56Sopenharmony_ci C.x.__set__(a, 100) 22837db96d56Sopenharmony_ci self.assertEqual(C.x.__get__(a), 100) 22847db96d56Sopenharmony_ci C.x.__delete__(a) 22857db96d56Sopenharmony_ci self.assertNotHasAttr(a, "x") 22867db96d56Sopenharmony_ci 22877db96d56Sopenharmony_ci raw = C.__dict__['x'] 22887db96d56Sopenharmony_ci self.assertIsInstance(raw, property) 22897db96d56Sopenharmony_ci 22907db96d56Sopenharmony_ci attrs = dir(raw) 22917db96d56Sopenharmony_ci self.assertIn("__doc__", attrs) 22927db96d56Sopenharmony_ci self.assertIn("fget", attrs) 22937db96d56Sopenharmony_ci self.assertIn("fset", attrs) 22947db96d56Sopenharmony_ci self.assertIn("fdel", attrs) 22957db96d56Sopenharmony_ci 22967db96d56Sopenharmony_ci self.assertEqual(raw.__doc__, "I'm the x property.") 22977db96d56Sopenharmony_ci self.assertIs(raw.fget, C.__dict__['getx']) 22987db96d56Sopenharmony_ci self.assertIs(raw.fset, C.__dict__['setx']) 22997db96d56Sopenharmony_ci self.assertIs(raw.fdel, C.__dict__['delx']) 23007db96d56Sopenharmony_ci 23017db96d56Sopenharmony_ci for attr in "fget", "fset", "fdel": 23027db96d56Sopenharmony_ci try: 23037db96d56Sopenharmony_ci setattr(raw, attr, 42) 23047db96d56Sopenharmony_ci except AttributeError as msg: 23057db96d56Sopenharmony_ci if str(msg).find('readonly') < 0: 23067db96d56Sopenharmony_ci self.fail("when setting readonly attr %r on a property, " 23077db96d56Sopenharmony_ci "got unexpected AttributeError msg %r" % (attr, str(msg))) 23087db96d56Sopenharmony_ci else: 23097db96d56Sopenharmony_ci self.fail("expected AttributeError from trying to set readonly %r " 23107db96d56Sopenharmony_ci "attr on a property" % attr) 23117db96d56Sopenharmony_ci 23127db96d56Sopenharmony_ci raw.__doc__ = 42 23137db96d56Sopenharmony_ci self.assertEqual(raw.__doc__, 42) 23147db96d56Sopenharmony_ci 23157db96d56Sopenharmony_ci class D(object): 23167db96d56Sopenharmony_ci __getitem__ = property(lambda s: 1/0) 23177db96d56Sopenharmony_ci 23187db96d56Sopenharmony_ci d = D() 23197db96d56Sopenharmony_ci try: 23207db96d56Sopenharmony_ci for i in d: 23217db96d56Sopenharmony_ci str(i) 23227db96d56Sopenharmony_ci except ZeroDivisionError: 23237db96d56Sopenharmony_ci pass 23247db96d56Sopenharmony_ci else: 23257db96d56Sopenharmony_ci self.fail("expected ZeroDivisionError from bad property") 23267db96d56Sopenharmony_ci 23277db96d56Sopenharmony_ci @unittest.skipIf(sys.flags.optimize >= 2, 23287db96d56Sopenharmony_ci "Docstrings are omitted with -O2 and above") 23297db96d56Sopenharmony_ci def test_properties_doc_attrib(self): 23307db96d56Sopenharmony_ci class E(object): 23317db96d56Sopenharmony_ci def getter(self): 23327db96d56Sopenharmony_ci "getter method" 23337db96d56Sopenharmony_ci return 0 23347db96d56Sopenharmony_ci def setter(self_, value): 23357db96d56Sopenharmony_ci "setter method" 23367db96d56Sopenharmony_ci pass 23377db96d56Sopenharmony_ci prop = property(getter) 23387db96d56Sopenharmony_ci self.assertEqual(prop.__doc__, "getter method") 23397db96d56Sopenharmony_ci prop2 = property(fset=setter) 23407db96d56Sopenharmony_ci self.assertEqual(prop2.__doc__, None) 23417db96d56Sopenharmony_ci 23427db96d56Sopenharmony_ci @support.cpython_only 23437db96d56Sopenharmony_ci def test_testcapi_no_segfault(self): 23447db96d56Sopenharmony_ci # this segfaulted in 2.5b2 23457db96d56Sopenharmony_ci try: 23467db96d56Sopenharmony_ci import _testcapi 23477db96d56Sopenharmony_ci except ImportError: 23487db96d56Sopenharmony_ci pass 23497db96d56Sopenharmony_ci else: 23507db96d56Sopenharmony_ci class X(object): 23517db96d56Sopenharmony_ci p = property(_testcapi.test_with_docstring) 23527db96d56Sopenharmony_ci 23537db96d56Sopenharmony_ci def test_properties_plus(self): 23547db96d56Sopenharmony_ci class C(object): 23557db96d56Sopenharmony_ci foo = property(doc="hello") 23567db96d56Sopenharmony_ci @foo.getter 23577db96d56Sopenharmony_ci def foo(self): 23587db96d56Sopenharmony_ci return self._foo 23597db96d56Sopenharmony_ci @foo.setter 23607db96d56Sopenharmony_ci def foo(self, value): 23617db96d56Sopenharmony_ci self._foo = abs(value) 23627db96d56Sopenharmony_ci @foo.deleter 23637db96d56Sopenharmony_ci def foo(self): 23647db96d56Sopenharmony_ci del self._foo 23657db96d56Sopenharmony_ci c = C() 23667db96d56Sopenharmony_ci self.assertEqual(C.foo.__doc__, "hello") 23677db96d56Sopenharmony_ci self.assertNotHasAttr(c, "foo") 23687db96d56Sopenharmony_ci c.foo = -42 23697db96d56Sopenharmony_ci self.assertHasAttr(c, '_foo') 23707db96d56Sopenharmony_ci self.assertEqual(c._foo, 42) 23717db96d56Sopenharmony_ci self.assertEqual(c.foo, 42) 23727db96d56Sopenharmony_ci del c.foo 23737db96d56Sopenharmony_ci self.assertNotHasAttr(c, '_foo') 23747db96d56Sopenharmony_ci self.assertNotHasAttr(c, "foo") 23757db96d56Sopenharmony_ci 23767db96d56Sopenharmony_ci class D(C): 23777db96d56Sopenharmony_ci @C.foo.deleter 23787db96d56Sopenharmony_ci def foo(self): 23797db96d56Sopenharmony_ci try: 23807db96d56Sopenharmony_ci del self._foo 23817db96d56Sopenharmony_ci except AttributeError: 23827db96d56Sopenharmony_ci pass 23837db96d56Sopenharmony_ci d = D() 23847db96d56Sopenharmony_ci d.foo = 24 23857db96d56Sopenharmony_ci self.assertEqual(d.foo, 24) 23867db96d56Sopenharmony_ci del d.foo 23877db96d56Sopenharmony_ci del d.foo 23887db96d56Sopenharmony_ci 23897db96d56Sopenharmony_ci class E(object): 23907db96d56Sopenharmony_ci @property 23917db96d56Sopenharmony_ci def foo(self): 23927db96d56Sopenharmony_ci return self._foo 23937db96d56Sopenharmony_ci @foo.setter 23947db96d56Sopenharmony_ci def foo(self, value): 23957db96d56Sopenharmony_ci raise RuntimeError 23967db96d56Sopenharmony_ci @foo.setter 23977db96d56Sopenharmony_ci def foo(self, value): 23987db96d56Sopenharmony_ci self._foo = abs(value) 23997db96d56Sopenharmony_ci @foo.deleter 24007db96d56Sopenharmony_ci def foo(self, value=None): 24017db96d56Sopenharmony_ci del self._foo 24027db96d56Sopenharmony_ci 24037db96d56Sopenharmony_ci e = E() 24047db96d56Sopenharmony_ci e.foo = -42 24057db96d56Sopenharmony_ci self.assertEqual(e.foo, 42) 24067db96d56Sopenharmony_ci del e.foo 24077db96d56Sopenharmony_ci 24087db96d56Sopenharmony_ci class F(E): 24097db96d56Sopenharmony_ci @E.foo.deleter 24107db96d56Sopenharmony_ci def foo(self): 24117db96d56Sopenharmony_ci del self._foo 24127db96d56Sopenharmony_ci @foo.setter 24137db96d56Sopenharmony_ci def foo(self, value): 24147db96d56Sopenharmony_ci self._foo = max(0, value) 24157db96d56Sopenharmony_ci f = F() 24167db96d56Sopenharmony_ci f.foo = -10 24177db96d56Sopenharmony_ci self.assertEqual(f.foo, 0) 24187db96d56Sopenharmony_ci del f.foo 24197db96d56Sopenharmony_ci 24207db96d56Sopenharmony_ci def test_dict_constructors(self): 24217db96d56Sopenharmony_ci # Testing dict constructor ... 24227db96d56Sopenharmony_ci d = dict() 24237db96d56Sopenharmony_ci self.assertEqual(d, {}) 24247db96d56Sopenharmony_ci d = dict({}) 24257db96d56Sopenharmony_ci self.assertEqual(d, {}) 24267db96d56Sopenharmony_ci d = dict({1: 2, 'a': 'b'}) 24277db96d56Sopenharmony_ci self.assertEqual(d, {1: 2, 'a': 'b'}) 24287db96d56Sopenharmony_ci self.assertEqual(d, dict(list(d.items()))) 24297db96d56Sopenharmony_ci self.assertEqual(d, dict(iter(d.items()))) 24307db96d56Sopenharmony_ci d = dict({'one':1, 'two':2}) 24317db96d56Sopenharmony_ci self.assertEqual(d, dict(one=1, two=2)) 24327db96d56Sopenharmony_ci self.assertEqual(d, dict(**d)) 24337db96d56Sopenharmony_ci self.assertEqual(d, dict({"one": 1}, two=2)) 24347db96d56Sopenharmony_ci self.assertEqual(d, dict([("two", 2)], one=1)) 24357db96d56Sopenharmony_ci self.assertEqual(d, dict([("one", 100), ("two", 200)], **d)) 24367db96d56Sopenharmony_ci self.assertEqual(d, dict(**d)) 24377db96d56Sopenharmony_ci 24387db96d56Sopenharmony_ci for badarg in 0, 0, 0j, "0", [0], (0,): 24397db96d56Sopenharmony_ci try: 24407db96d56Sopenharmony_ci dict(badarg) 24417db96d56Sopenharmony_ci except TypeError: 24427db96d56Sopenharmony_ci pass 24437db96d56Sopenharmony_ci except ValueError: 24447db96d56Sopenharmony_ci if badarg == "0": 24457db96d56Sopenharmony_ci # It's a sequence, and its elements are also sequences (gotta 24467db96d56Sopenharmony_ci # love strings <wink>), but they aren't of length 2, so this 24477db96d56Sopenharmony_ci # one seemed better as a ValueError than a TypeError. 24487db96d56Sopenharmony_ci pass 24497db96d56Sopenharmony_ci else: 24507db96d56Sopenharmony_ci self.fail("no TypeError from dict(%r)" % badarg) 24517db96d56Sopenharmony_ci else: 24527db96d56Sopenharmony_ci self.fail("no TypeError from dict(%r)" % badarg) 24537db96d56Sopenharmony_ci 24547db96d56Sopenharmony_ci with self.assertRaises(TypeError): 24557db96d56Sopenharmony_ci dict({}, {}) 24567db96d56Sopenharmony_ci 24577db96d56Sopenharmony_ci class Mapping: 24587db96d56Sopenharmony_ci # Lacks a .keys() method; will be added later. 24597db96d56Sopenharmony_ci dict = {1:2, 3:4, 'a':1j} 24607db96d56Sopenharmony_ci 24617db96d56Sopenharmony_ci try: 24627db96d56Sopenharmony_ci dict(Mapping()) 24637db96d56Sopenharmony_ci except TypeError: 24647db96d56Sopenharmony_ci pass 24657db96d56Sopenharmony_ci else: 24667db96d56Sopenharmony_ci self.fail("no TypeError from dict(incomplete mapping)") 24677db96d56Sopenharmony_ci 24687db96d56Sopenharmony_ci Mapping.keys = lambda self: list(self.dict.keys()) 24697db96d56Sopenharmony_ci Mapping.__getitem__ = lambda self, i: self.dict[i] 24707db96d56Sopenharmony_ci d = dict(Mapping()) 24717db96d56Sopenharmony_ci self.assertEqual(d, Mapping.dict) 24727db96d56Sopenharmony_ci 24737db96d56Sopenharmony_ci # Init from sequence of iterable objects, each producing a 2-sequence. 24747db96d56Sopenharmony_ci class AddressBookEntry: 24757db96d56Sopenharmony_ci def __init__(self, first, last): 24767db96d56Sopenharmony_ci self.first = first 24777db96d56Sopenharmony_ci self.last = last 24787db96d56Sopenharmony_ci def __iter__(self): 24797db96d56Sopenharmony_ci return iter([self.first, self.last]) 24807db96d56Sopenharmony_ci 24817db96d56Sopenharmony_ci d = dict([AddressBookEntry('Tim', 'Warsaw'), 24827db96d56Sopenharmony_ci AddressBookEntry('Barry', 'Peters'), 24837db96d56Sopenharmony_ci AddressBookEntry('Tim', 'Peters'), 24847db96d56Sopenharmony_ci AddressBookEntry('Barry', 'Warsaw')]) 24857db96d56Sopenharmony_ci self.assertEqual(d, {'Barry': 'Warsaw', 'Tim': 'Peters'}) 24867db96d56Sopenharmony_ci 24877db96d56Sopenharmony_ci d = dict(zip(range(4), range(1, 5))) 24887db96d56Sopenharmony_ci self.assertEqual(d, dict([(i, i+1) for i in range(4)])) 24897db96d56Sopenharmony_ci 24907db96d56Sopenharmony_ci # Bad sequence lengths. 24917db96d56Sopenharmony_ci for bad in [('tooshort',)], [('too', 'long', 'by 1')]: 24927db96d56Sopenharmony_ci try: 24937db96d56Sopenharmony_ci dict(bad) 24947db96d56Sopenharmony_ci except ValueError: 24957db96d56Sopenharmony_ci pass 24967db96d56Sopenharmony_ci else: 24977db96d56Sopenharmony_ci self.fail("no ValueError from dict(%r)" % bad) 24987db96d56Sopenharmony_ci 24997db96d56Sopenharmony_ci def test_dir(self): 25007db96d56Sopenharmony_ci # Testing dir() ... 25017db96d56Sopenharmony_ci junk = 12 25027db96d56Sopenharmony_ci self.assertEqual(dir(), ['junk', 'self']) 25037db96d56Sopenharmony_ci del junk 25047db96d56Sopenharmony_ci 25057db96d56Sopenharmony_ci # Just make sure these don't blow up! 25067db96d56Sopenharmony_ci for arg in 2, 2, 2j, 2e0, [2], "2", b"2", (2,), {2:2}, type, self.test_dir: 25077db96d56Sopenharmony_ci dir(arg) 25087db96d56Sopenharmony_ci 25097db96d56Sopenharmony_ci # Test dir on new-style classes. Since these have object as a 25107db96d56Sopenharmony_ci # base class, a lot more gets sucked in. 25117db96d56Sopenharmony_ci def interesting(strings): 25127db96d56Sopenharmony_ci return [s for s in strings if not s.startswith('_')] 25137db96d56Sopenharmony_ci 25147db96d56Sopenharmony_ci class C(object): 25157db96d56Sopenharmony_ci Cdata = 1 25167db96d56Sopenharmony_ci def Cmethod(self): pass 25177db96d56Sopenharmony_ci 25187db96d56Sopenharmony_ci cstuff = ['Cdata', 'Cmethod'] 25197db96d56Sopenharmony_ci self.assertEqual(interesting(dir(C)), cstuff) 25207db96d56Sopenharmony_ci 25217db96d56Sopenharmony_ci c = C() 25227db96d56Sopenharmony_ci self.assertEqual(interesting(dir(c)), cstuff) 25237db96d56Sopenharmony_ci ## self.assertIn('__self__', dir(C.Cmethod)) 25247db96d56Sopenharmony_ci 25257db96d56Sopenharmony_ci c.cdata = 2 25267db96d56Sopenharmony_ci c.cmethod = lambda self: 0 25277db96d56Sopenharmony_ci self.assertEqual(interesting(dir(c)), cstuff + ['cdata', 'cmethod']) 25287db96d56Sopenharmony_ci ## self.assertIn('__self__', dir(c.Cmethod)) 25297db96d56Sopenharmony_ci 25307db96d56Sopenharmony_ci class A(C): 25317db96d56Sopenharmony_ci Adata = 1 25327db96d56Sopenharmony_ci def Amethod(self): pass 25337db96d56Sopenharmony_ci 25347db96d56Sopenharmony_ci astuff = ['Adata', 'Amethod'] + cstuff 25357db96d56Sopenharmony_ci self.assertEqual(interesting(dir(A)), astuff) 25367db96d56Sopenharmony_ci ## self.assertIn('__self__', dir(A.Amethod)) 25377db96d56Sopenharmony_ci a = A() 25387db96d56Sopenharmony_ci self.assertEqual(interesting(dir(a)), astuff) 25397db96d56Sopenharmony_ci a.adata = 42 25407db96d56Sopenharmony_ci a.amethod = lambda self: 3 25417db96d56Sopenharmony_ci self.assertEqual(interesting(dir(a)), astuff + ['adata', 'amethod']) 25427db96d56Sopenharmony_ci ## self.assertIn('__self__', dir(a.Amethod)) 25437db96d56Sopenharmony_ci 25447db96d56Sopenharmony_ci # Try a module subclass. 25457db96d56Sopenharmony_ci class M(type(sys)): 25467db96d56Sopenharmony_ci pass 25477db96d56Sopenharmony_ci minstance = M("m") 25487db96d56Sopenharmony_ci minstance.b = 2 25497db96d56Sopenharmony_ci minstance.a = 1 25507db96d56Sopenharmony_ci default_attributes = ['__name__', '__doc__', '__package__', 25517db96d56Sopenharmony_ci '__loader__', '__spec__'] 25527db96d56Sopenharmony_ci names = [x for x in dir(minstance) if x not in default_attributes] 25537db96d56Sopenharmony_ci self.assertEqual(names, ['a', 'b']) 25547db96d56Sopenharmony_ci 25557db96d56Sopenharmony_ci class M2(M): 25567db96d56Sopenharmony_ci def getdict(self): 25577db96d56Sopenharmony_ci return "Not a dict!" 25587db96d56Sopenharmony_ci __dict__ = property(getdict) 25597db96d56Sopenharmony_ci 25607db96d56Sopenharmony_ci m2instance = M2("m2") 25617db96d56Sopenharmony_ci m2instance.b = 2 25627db96d56Sopenharmony_ci m2instance.a = 1 25637db96d56Sopenharmony_ci self.assertEqual(m2instance.__dict__, "Not a dict!") 25647db96d56Sopenharmony_ci with self.assertRaises(TypeError): 25657db96d56Sopenharmony_ci dir(m2instance) 25667db96d56Sopenharmony_ci 25677db96d56Sopenharmony_ci # Two essentially featureless objects, (Ellipsis just inherits stuff 25687db96d56Sopenharmony_ci # from object. 25697db96d56Sopenharmony_ci self.assertEqual(dir(object()), dir(Ellipsis)) 25707db96d56Sopenharmony_ci 25717db96d56Sopenharmony_ci # Nasty test case for proxied objects 25727db96d56Sopenharmony_ci class Wrapper(object): 25737db96d56Sopenharmony_ci def __init__(self, obj): 25747db96d56Sopenharmony_ci self.__obj = obj 25757db96d56Sopenharmony_ci def __repr__(self): 25767db96d56Sopenharmony_ci return "Wrapper(%s)" % repr(self.__obj) 25777db96d56Sopenharmony_ci def __getitem__(self, key): 25787db96d56Sopenharmony_ci return Wrapper(self.__obj[key]) 25797db96d56Sopenharmony_ci def __len__(self): 25807db96d56Sopenharmony_ci return len(self.__obj) 25817db96d56Sopenharmony_ci def __getattr__(self, name): 25827db96d56Sopenharmony_ci return Wrapper(getattr(self.__obj, name)) 25837db96d56Sopenharmony_ci 25847db96d56Sopenharmony_ci class C(object): 25857db96d56Sopenharmony_ci def __getclass(self): 25867db96d56Sopenharmony_ci return Wrapper(type(self)) 25877db96d56Sopenharmony_ci __class__ = property(__getclass) 25887db96d56Sopenharmony_ci 25897db96d56Sopenharmony_ci dir(C()) # This used to segfault 25907db96d56Sopenharmony_ci 25917db96d56Sopenharmony_ci def test_supers(self): 25927db96d56Sopenharmony_ci # Testing super... 25937db96d56Sopenharmony_ci 25947db96d56Sopenharmony_ci class A(object): 25957db96d56Sopenharmony_ci def meth(self, a): 25967db96d56Sopenharmony_ci return "A(%r)" % a 25977db96d56Sopenharmony_ci 25987db96d56Sopenharmony_ci self.assertEqual(A().meth(1), "A(1)") 25997db96d56Sopenharmony_ci 26007db96d56Sopenharmony_ci class B(A): 26017db96d56Sopenharmony_ci def __init__(self): 26027db96d56Sopenharmony_ci self.__super = super(B, self) 26037db96d56Sopenharmony_ci def meth(self, a): 26047db96d56Sopenharmony_ci return "B(%r)" % a + self.__super.meth(a) 26057db96d56Sopenharmony_ci 26067db96d56Sopenharmony_ci self.assertEqual(B().meth(2), "B(2)A(2)") 26077db96d56Sopenharmony_ci 26087db96d56Sopenharmony_ci class C(A): 26097db96d56Sopenharmony_ci def meth(self, a): 26107db96d56Sopenharmony_ci return "C(%r)" % a + self.__super.meth(a) 26117db96d56Sopenharmony_ci C._C__super = super(C) 26127db96d56Sopenharmony_ci 26137db96d56Sopenharmony_ci self.assertEqual(C().meth(3), "C(3)A(3)") 26147db96d56Sopenharmony_ci 26157db96d56Sopenharmony_ci class D(C, B): 26167db96d56Sopenharmony_ci def meth(self, a): 26177db96d56Sopenharmony_ci return "D(%r)" % a + super(D, self).meth(a) 26187db96d56Sopenharmony_ci 26197db96d56Sopenharmony_ci self.assertEqual(D().meth(4), "D(4)C(4)B(4)A(4)") 26207db96d56Sopenharmony_ci 26217db96d56Sopenharmony_ci # Test for subclassing super 26227db96d56Sopenharmony_ci 26237db96d56Sopenharmony_ci class mysuper(super): 26247db96d56Sopenharmony_ci def __init__(self, *args): 26257db96d56Sopenharmony_ci return super(mysuper, self).__init__(*args) 26267db96d56Sopenharmony_ci 26277db96d56Sopenharmony_ci class E(D): 26287db96d56Sopenharmony_ci def meth(self, a): 26297db96d56Sopenharmony_ci return "E(%r)" % a + mysuper(E, self).meth(a) 26307db96d56Sopenharmony_ci 26317db96d56Sopenharmony_ci self.assertEqual(E().meth(5), "E(5)D(5)C(5)B(5)A(5)") 26327db96d56Sopenharmony_ci 26337db96d56Sopenharmony_ci class F(E): 26347db96d56Sopenharmony_ci def meth(self, a): 26357db96d56Sopenharmony_ci s = self.__super # == mysuper(F, self) 26367db96d56Sopenharmony_ci return "F(%r)[%s]" % (a, s.__class__.__name__) + s.meth(a) 26377db96d56Sopenharmony_ci F._F__super = mysuper(F) 26387db96d56Sopenharmony_ci 26397db96d56Sopenharmony_ci self.assertEqual(F().meth(6), "F(6)[mysuper]E(6)D(6)C(6)B(6)A(6)") 26407db96d56Sopenharmony_ci 26417db96d56Sopenharmony_ci # Make sure certain errors are raised 26427db96d56Sopenharmony_ci 26437db96d56Sopenharmony_ci try: 26447db96d56Sopenharmony_ci super(D, 42) 26457db96d56Sopenharmony_ci except TypeError: 26467db96d56Sopenharmony_ci pass 26477db96d56Sopenharmony_ci else: 26487db96d56Sopenharmony_ci self.fail("shouldn't allow super(D, 42)") 26497db96d56Sopenharmony_ci 26507db96d56Sopenharmony_ci try: 26517db96d56Sopenharmony_ci super(D, C()) 26527db96d56Sopenharmony_ci except TypeError: 26537db96d56Sopenharmony_ci pass 26547db96d56Sopenharmony_ci else: 26557db96d56Sopenharmony_ci self.fail("shouldn't allow super(D, C())") 26567db96d56Sopenharmony_ci 26577db96d56Sopenharmony_ci try: 26587db96d56Sopenharmony_ci super(D).__get__(12) 26597db96d56Sopenharmony_ci except TypeError: 26607db96d56Sopenharmony_ci pass 26617db96d56Sopenharmony_ci else: 26627db96d56Sopenharmony_ci self.fail("shouldn't allow super(D).__get__(12)") 26637db96d56Sopenharmony_ci 26647db96d56Sopenharmony_ci try: 26657db96d56Sopenharmony_ci super(D).__get__(C()) 26667db96d56Sopenharmony_ci except TypeError: 26677db96d56Sopenharmony_ci pass 26687db96d56Sopenharmony_ci else: 26697db96d56Sopenharmony_ci self.fail("shouldn't allow super(D).__get__(C())") 26707db96d56Sopenharmony_ci 26717db96d56Sopenharmony_ci # Make sure data descriptors can be overridden and accessed via super 26727db96d56Sopenharmony_ci # (new feature in Python 2.3) 26737db96d56Sopenharmony_ci 26747db96d56Sopenharmony_ci class DDbase(object): 26757db96d56Sopenharmony_ci def getx(self): return 42 26767db96d56Sopenharmony_ci x = property(getx) 26777db96d56Sopenharmony_ci 26787db96d56Sopenharmony_ci class DDsub(DDbase): 26797db96d56Sopenharmony_ci def getx(self): return "hello" 26807db96d56Sopenharmony_ci x = property(getx) 26817db96d56Sopenharmony_ci 26827db96d56Sopenharmony_ci dd = DDsub() 26837db96d56Sopenharmony_ci self.assertEqual(dd.x, "hello") 26847db96d56Sopenharmony_ci self.assertEqual(super(DDsub, dd).x, 42) 26857db96d56Sopenharmony_ci 26867db96d56Sopenharmony_ci # Ensure that super() lookup of descriptor from classmethod 26877db96d56Sopenharmony_ci # works (SF ID# 743627) 26887db96d56Sopenharmony_ci 26897db96d56Sopenharmony_ci class Base(object): 26907db96d56Sopenharmony_ci aProp = property(lambda self: "foo") 26917db96d56Sopenharmony_ci 26927db96d56Sopenharmony_ci class Sub(Base): 26937db96d56Sopenharmony_ci @classmethod 26947db96d56Sopenharmony_ci def test(klass): 26957db96d56Sopenharmony_ci return super(Sub,klass).aProp 26967db96d56Sopenharmony_ci 26977db96d56Sopenharmony_ci self.assertEqual(Sub.test(), Base.aProp) 26987db96d56Sopenharmony_ci 26997db96d56Sopenharmony_ci # Verify that super() doesn't allow keyword args 27007db96d56Sopenharmony_ci with self.assertRaises(TypeError): 27017db96d56Sopenharmony_ci super(Base, kw=1) 27027db96d56Sopenharmony_ci 27037db96d56Sopenharmony_ci def test_basic_inheritance(self): 27047db96d56Sopenharmony_ci # Testing inheritance from basic types... 27057db96d56Sopenharmony_ci 27067db96d56Sopenharmony_ci class hexint(int): 27077db96d56Sopenharmony_ci def __repr__(self): 27087db96d56Sopenharmony_ci return hex(self) 27097db96d56Sopenharmony_ci def __add__(self, other): 27107db96d56Sopenharmony_ci return hexint(int.__add__(self, other)) 27117db96d56Sopenharmony_ci # (Note that overriding __radd__ doesn't work, 27127db96d56Sopenharmony_ci # because the int type gets first dibs.) 27137db96d56Sopenharmony_ci self.assertEqual(repr(hexint(7) + 9), "0x10") 27147db96d56Sopenharmony_ci self.assertEqual(repr(hexint(1000) + 7), "0x3ef") 27157db96d56Sopenharmony_ci a = hexint(12345) 27167db96d56Sopenharmony_ci self.assertEqual(a, 12345) 27177db96d56Sopenharmony_ci self.assertEqual(int(a), 12345) 27187db96d56Sopenharmony_ci self.assertIs(int(a).__class__, int) 27197db96d56Sopenharmony_ci self.assertEqual(hash(a), hash(12345)) 27207db96d56Sopenharmony_ci self.assertIs((+a).__class__, int) 27217db96d56Sopenharmony_ci self.assertIs((a >> 0).__class__, int) 27227db96d56Sopenharmony_ci self.assertIs((a << 0).__class__, int) 27237db96d56Sopenharmony_ci self.assertIs((hexint(0) << 12).__class__, int) 27247db96d56Sopenharmony_ci self.assertIs((hexint(0) >> 12).__class__, int) 27257db96d56Sopenharmony_ci 27267db96d56Sopenharmony_ci class octlong(int): 27277db96d56Sopenharmony_ci __slots__ = [] 27287db96d56Sopenharmony_ci def __str__(self): 27297db96d56Sopenharmony_ci return oct(self) 27307db96d56Sopenharmony_ci def __add__(self, other): 27317db96d56Sopenharmony_ci return self.__class__(super(octlong, self).__add__(other)) 27327db96d56Sopenharmony_ci __radd__ = __add__ 27337db96d56Sopenharmony_ci self.assertEqual(str(octlong(3) + 5), "0o10") 27347db96d56Sopenharmony_ci # (Note that overriding __radd__ here only seems to work 27357db96d56Sopenharmony_ci # because the example uses a short int left argument.) 27367db96d56Sopenharmony_ci self.assertEqual(str(5 + octlong(3000)), "0o5675") 27377db96d56Sopenharmony_ci a = octlong(12345) 27387db96d56Sopenharmony_ci self.assertEqual(a, 12345) 27397db96d56Sopenharmony_ci self.assertEqual(int(a), 12345) 27407db96d56Sopenharmony_ci self.assertEqual(hash(a), hash(12345)) 27417db96d56Sopenharmony_ci self.assertIs(int(a).__class__, int) 27427db96d56Sopenharmony_ci self.assertIs((+a).__class__, int) 27437db96d56Sopenharmony_ci self.assertIs((-a).__class__, int) 27447db96d56Sopenharmony_ci self.assertIs((-octlong(0)).__class__, int) 27457db96d56Sopenharmony_ci self.assertIs((a >> 0).__class__, int) 27467db96d56Sopenharmony_ci self.assertIs((a << 0).__class__, int) 27477db96d56Sopenharmony_ci self.assertIs((a - 0).__class__, int) 27487db96d56Sopenharmony_ci self.assertIs((a * 1).__class__, int) 27497db96d56Sopenharmony_ci self.assertIs((a ** 1).__class__, int) 27507db96d56Sopenharmony_ci self.assertIs((a // 1).__class__, int) 27517db96d56Sopenharmony_ci self.assertIs((1 * a).__class__, int) 27527db96d56Sopenharmony_ci self.assertIs((a | 0).__class__, int) 27537db96d56Sopenharmony_ci self.assertIs((a ^ 0).__class__, int) 27547db96d56Sopenharmony_ci self.assertIs((a & -1).__class__, int) 27557db96d56Sopenharmony_ci self.assertIs((octlong(0) << 12).__class__, int) 27567db96d56Sopenharmony_ci self.assertIs((octlong(0) >> 12).__class__, int) 27577db96d56Sopenharmony_ci self.assertIs(abs(octlong(0)).__class__, int) 27587db96d56Sopenharmony_ci 27597db96d56Sopenharmony_ci # Because octlong overrides __add__, we can't check the absence of +0 27607db96d56Sopenharmony_ci # optimizations using octlong. 27617db96d56Sopenharmony_ci class longclone(int): 27627db96d56Sopenharmony_ci pass 27637db96d56Sopenharmony_ci a = longclone(1) 27647db96d56Sopenharmony_ci self.assertIs((a + 0).__class__, int) 27657db96d56Sopenharmony_ci self.assertIs((0 + a).__class__, int) 27667db96d56Sopenharmony_ci 27677db96d56Sopenharmony_ci # Check that negative clones don't segfault 27687db96d56Sopenharmony_ci a = longclone(-1) 27697db96d56Sopenharmony_ci self.assertEqual(a.__dict__, {}) 27707db96d56Sopenharmony_ci self.assertEqual(int(a), -1) # self.assertTrue PyNumber_Long() copies the sign bit 27717db96d56Sopenharmony_ci 27727db96d56Sopenharmony_ci class precfloat(float): 27737db96d56Sopenharmony_ci __slots__ = ['prec'] 27747db96d56Sopenharmony_ci def __init__(self, value=0.0, prec=12): 27757db96d56Sopenharmony_ci self.prec = int(prec) 27767db96d56Sopenharmony_ci def __repr__(self): 27777db96d56Sopenharmony_ci return "%.*g" % (self.prec, self) 27787db96d56Sopenharmony_ci self.assertEqual(repr(precfloat(1.1)), "1.1") 27797db96d56Sopenharmony_ci a = precfloat(12345) 27807db96d56Sopenharmony_ci self.assertEqual(a, 12345.0) 27817db96d56Sopenharmony_ci self.assertEqual(float(a), 12345.0) 27827db96d56Sopenharmony_ci self.assertIs(float(a).__class__, float) 27837db96d56Sopenharmony_ci self.assertEqual(hash(a), hash(12345.0)) 27847db96d56Sopenharmony_ci self.assertIs((+a).__class__, float) 27857db96d56Sopenharmony_ci 27867db96d56Sopenharmony_ci class madcomplex(complex): 27877db96d56Sopenharmony_ci def __repr__(self): 27887db96d56Sopenharmony_ci return "%.17gj%+.17g" % (self.imag, self.real) 27897db96d56Sopenharmony_ci a = madcomplex(-3, 4) 27907db96d56Sopenharmony_ci self.assertEqual(repr(a), "4j-3") 27917db96d56Sopenharmony_ci base = complex(-3, 4) 27927db96d56Sopenharmony_ci self.assertEqual(base.__class__, complex) 27937db96d56Sopenharmony_ci self.assertEqual(a, base) 27947db96d56Sopenharmony_ci self.assertEqual(complex(a), base) 27957db96d56Sopenharmony_ci self.assertEqual(complex(a).__class__, complex) 27967db96d56Sopenharmony_ci a = madcomplex(a) # just trying another form of the constructor 27977db96d56Sopenharmony_ci self.assertEqual(repr(a), "4j-3") 27987db96d56Sopenharmony_ci self.assertEqual(a, base) 27997db96d56Sopenharmony_ci self.assertEqual(complex(a), base) 28007db96d56Sopenharmony_ci self.assertEqual(complex(a).__class__, complex) 28017db96d56Sopenharmony_ci self.assertEqual(hash(a), hash(base)) 28027db96d56Sopenharmony_ci self.assertEqual((+a).__class__, complex) 28037db96d56Sopenharmony_ci self.assertEqual((a + 0).__class__, complex) 28047db96d56Sopenharmony_ci self.assertEqual(a + 0, base) 28057db96d56Sopenharmony_ci self.assertEqual((a - 0).__class__, complex) 28067db96d56Sopenharmony_ci self.assertEqual(a - 0, base) 28077db96d56Sopenharmony_ci self.assertEqual((a * 1).__class__, complex) 28087db96d56Sopenharmony_ci self.assertEqual(a * 1, base) 28097db96d56Sopenharmony_ci self.assertEqual((a / 1).__class__, complex) 28107db96d56Sopenharmony_ci self.assertEqual(a / 1, base) 28117db96d56Sopenharmony_ci 28127db96d56Sopenharmony_ci class madtuple(tuple): 28137db96d56Sopenharmony_ci _rev = None 28147db96d56Sopenharmony_ci def rev(self): 28157db96d56Sopenharmony_ci if self._rev is not None: 28167db96d56Sopenharmony_ci return self._rev 28177db96d56Sopenharmony_ci L = list(self) 28187db96d56Sopenharmony_ci L.reverse() 28197db96d56Sopenharmony_ci self._rev = self.__class__(L) 28207db96d56Sopenharmony_ci return self._rev 28217db96d56Sopenharmony_ci a = madtuple((1,2,3,4,5,6,7,8,9,0)) 28227db96d56Sopenharmony_ci self.assertEqual(a, (1,2,3,4,5,6,7,8,9,0)) 28237db96d56Sopenharmony_ci self.assertEqual(a.rev(), madtuple((0,9,8,7,6,5,4,3,2,1))) 28247db96d56Sopenharmony_ci self.assertEqual(a.rev().rev(), madtuple((1,2,3,4,5,6,7,8,9,0))) 28257db96d56Sopenharmony_ci for i in range(512): 28267db96d56Sopenharmony_ci t = madtuple(range(i)) 28277db96d56Sopenharmony_ci u = t.rev() 28287db96d56Sopenharmony_ci v = u.rev() 28297db96d56Sopenharmony_ci self.assertEqual(v, t) 28307db96d56Sopenharmony_ci a = madtuple((1,2,3,4,5)) 28317db96d56Sopenharmony_ci self.assertEqual(tuple(a), (1,2,3,4,5)) 28327db96d56Sopenharmony_ci self.assertIs(tuple(a).__class__, tuple) 28337db96d56Sopenharmony_ci self.assertEqual(hash(a), hash((1,2,3,4,5))) 28347db96d56Sopenharmony_ci self.assertIs(a[:].__class__, tuple) 28357db96d56Sopenharmony_ci self.assertIs((a * 1).__class__, tuple) 28367db96d56Sopenharmony_ci self.assertIs((a * 0).__class__, tuple) 28377db96d56Sopenharmony_ci self.assertIs((a + ()).__class__, tuple) 28387db96d56Sopenharmony_ci a = madtuple(()) 28397db96d56Sopenharmony_ci self.assertEqual(tuple(a), ()) 28407db96d56Sopenharmony_ci self.assertIs(tuple(a).__class__, tuple) 28417db96d56Sopenharmony_ci self.assertIs((a + a).__class__, tuple) 28427db96d56Sopenharmony_ci self.assertIs((a * 0).__class__, tuple) 28437db96d56Sopenharmony_ci self.assertIs((a * 1).__class__, tuple) 28447db96d56Sopenharmony_ci self.assertIs((a * 2).__class__, tuple) 28457db96d56Sopenharmony_ci self.assertIs(a[:].__class__, tuple) 28467db96d56Sopenharmony_ci 28477db96d56Sopenharmony_ci class madstring(str): 28487db96d56Sopenharmony_ci _rev = None 28497db96d56Sopenharmony_ci def rev(self): 28507db96d56Sopenharmony_ci if self._rev is not None: 28517db96d56Sopenharmony_ci return self._rev 28527db96d56Sopenharmony_ci L = list(self) 28537db96d56Sopenharmony_ci L.reverse() 28547db96d56Sopenharmony_ci self._rev = self.__class__("".join(L)) 28557db96d56Sopenharmony_ci return self._rev 28567db96d56Sopenharmony_ci s = madstring("abcdefghijklmnopqrstuvwxyz") 28577db96d56Sopenharmony_ci self.assertEqual(s, "abcdefghijklmnopqrstuvwxyz") 28587db96d56Sopenharmony_ci self.assertEqual(s.rev(), madstring("zyxwvutsrqponmlkjihgfedcba")) 28597db96d56Sopenharmony_ci self.assertEqual(s.rev().rev(), madstring("abcdefghijklmnopqrstuvwxyz")) 28607db96d56Sopenharmony_ci for i in range(256): 28617db96d56Sopenharmony_ci s = madstring("".join(map(chr, range(i)))) 28627db96d56Sopenharmony_ci t = s.rev() 28637db96d56Sopenharmony_ci u = t.rev() 28647db96d56Sopenharmony_ci self.assertEqual(u, s) 28657db96d56Sopenharmony_ci s = madstring("12345") 28667db96d56Sopenharmony_ci self.assertEqual(str(s), "12345") 28677db96d56Sopenharmony_ci self.assertIs(str(s).__class__, str) 28687db96d56Sopenharmony_ci 28697db96d56Sopenharmony_ci base = "\x00" * 5 28707db96d56Sopenharmony_ci s = madstring(base) 28717db96d56Sopenharmony_ci self.assertEqual(s, base) 28727db96d56Sopenharmony_ci self.assertEqual(str(s), base) 28737db96d56Sopenharmony_ci self.assertIs(str(s).__class__, str) 28747db96d56Sopenharmony_ci self.assertEqual(hash(s), hash(base)) 28757db96d56Sopenharmony_ci self.assertEqual({s: 1}[base], 1) 28767db96d56Sopenharmony_ci self.assertEqual({base: 1}[s], 1) 28777db96d56Sopenharmony_ci self.assertIs((s + "").__class__, str) 28787db96d56Sopenharmony_ci self.assertEqual(s + "", base) 28797db96d56Sopenharmony_ci self.assertIs(("" + s).__class__, str) 28807db96d56Sopenharmony_ci self.assertEqual("" + s, base) 28817db96d56Sopenharmony_ci self.assertIs((s * 0).__class__, str) 28827db96d56Sopenharmony_ci self.assertEqual(s * 0, "") 28837db96d56Sopenharmony_ci self.assertIs((s * 1).__class__, str) 28847db96d56Sopenharmony_ci self.assertEqual(s * 1, base) 28857db96d56Sopenharmony_ci self.assertIs((s * 2).__class__, str) 28867db96d56Sopenharmony_ci self.assertEqual(s * 2, base + base) 28877db96d56Sopenharmony_ci self.assertIs(s[:].__class__, str) 28887db96d56Sopenharmony_ci self.assertEqual(s[:], base) 28897db96d56Sopenharmony_ci self.assertIs(s[0:0].__class__, str) 28907db96d56Sopenharmony_ci self.assertEqual(s[0:0], "") 28917db96d56Sopenharmony_ci self.assertIs(s.strip().__class__, str) 28927db96d56Sopenharmony_ci self.assertEqual(s.strip(), base) 28937db96d56Sopenharmony_ci self.assertIs(s.lstrip().__class__, str) 28947db96d56Sopenharmony_ci self.assertEqual(s.lstrip(), base) 28957db96d56Sopenharmony_ci self.assertIs(s.rstrip().__class__, str) 28967db96d56Sopenharmony_ci self.assertEqual(s.rstrip(), base) 28977db96d56Sopenharmony_ci identitytab = {} 28987db96d56Sopenharmony_ci self.assertIs(s.translate(identitytab).__class__, str) 28997db96d56Sopenharmony_ci self.assertEqual(s.translate(identitytab), base) 29007db96d56Sopenharmony_ci self.assertIs(s.replace("x", "x").__class__, str) 29017db96d56Sopenharmony_ci self.assertEqual(s.replace("x", "x"), base) 29027db96d56Sopenharmony_ci self.assertIs(s.ljust(len(s)).__class__, str) 29037db96d56Sopenharmony_ci self.assertEqual(s.ljust(len(s)), base) 29047db96d56Sopenharmony_ci self.assertIs(s.rjust(len(s)).__class__, str) 29057db96d56Sopenharmony_ci self.assertEqual(s.rjust(len(s)), base) 29067db96d56Sopenharmony_ci self.assertIs(s.center(len(s)).__class__, str) 29077db96d56Sopenharmony_ci self.assertEqual(s.center(len(s)), base) 29087db96d56Sopenharmony_ci self.assertIs(s.lower().__class__, str) 29097db96d56Sopenharmony_ci self.assertEqual(s.lower(), base) 29107db96d56Sopenharmony_ci 29117db96d56Sopenharmony_ci class madunicode(str): 29127db96d56Sopenharmony_ci _rev = None 29137db96d56Sopenharmony_ci def rev(self): 29147db96d56Sopenharmony_ci if self._rev is not None: 29157db96d56Sopenharmony_ci return self._rev 29167db96d56Sopenharmony_ci L = list(self) 29177db96d56Sopenharmony_ci L.reverse() 29187db96d56Sopenharmony_ci self._rev = self.__class__("".join(L)) 29197db96d56Sopenharmony_ci return self._rev 29207db96d56Sopenharmony_ci u = madunicode("ABCDEF") 29217db96d56Sopenharmony_ci self.assertEqual(u, "ABCDEF") 29227db96d56Sopenharmony_ci self.assertEqual(u.rev(), madunicode("FEDCBA")) 29237db96d56Sopenharmony_ci self.assertEqual(u.rev().rev(), madunicode("ABCDEF")) 29247db96d56Sopenharmony_ci base = "12345" 29257db96d56Sopenharmony_ci u = madunicode(base) 29267db96d56Sopenharmony_ci self.assertEqual(str(u), base) 29277db96d56Sopenharmony_ci self.assertIs(str(u).__class__, str) 29287db96d56Sopenharmony_ci self.assertEqual(hash(u), hash(base)) 29297db96d56Sopenharmony_ci self.assertEqual({u: 1}[base], 1) 29307db96d56Sopenharmony_ci self.assertEqual({base: 1}[u], 1) 29317db96d56Sopenharmony_ci self.assertIs(u.strip().__class__, str) 29327db96d56Sopenharmony_ci self.assertEqual(u.strip(), base) 29337db96d56Sopenharmony_ci self.assertIs(u.lstrip().__class__, str) 29347db96d56Sopenharmony_ci self.assertEqual(u.lstrip(), base) 29357db96d56Sopenharmony_ci self.assertIs(u.rstrip().__class__, str) 29367db96d56Sopenharmony_ci self.assertEqual(u.rstrip(), base) 29377db96d56Sopenharmony_ci self.assertIs(u.replace("x", "x").__class__, str) 29387db96d56Sopenharmony_ci self.assertEqual(u.replace("x", "x"), base) 29397db96d56Sopenharmony_ci self.assertIs(u.replace("xy", "xy").__class__, str) 29407db96d56Sopenharmony_ci self.assertEqual(u.replace("xy", "xy"), base) 29417db96d56Sopenharmony_ci self.assertIs(u.center(len(u)).__class__, str) 29427db96d56Sopenharmony_ci self.assertEqual(u.center(len(u)), base) 29437db96d56Sopenharmony_ci self.assertIs(u.ljust(len(u)).__class__, str) 29447db96d56Sopenharmony_ci self.assertEqual(u.ljust(len(u)), base) 29457db96d56Sopenharmony_ci self.assertIs(u.rjust(len(u)).__class__, str) 29467db96d56Sopenharmony_ci self.assertEqual(u.rjust(len(u)), base) 29477db96d56Sopenharmony_ci self.assertIs(u.lower().__class__, str) 29487db96d56Sopenharmony_ci self.assertEqual(u.lower(), base) 29497db96d56Sopenharmony_ci self.assertIs(u.upper().__class__, str) 29507db96d56Sopenharmony_ci self.assertEqual(u.upper(), base) 29517db96d56Sopenharmony_ci self.assertIs(u.capitalize().__class__, str) 29527db96d56Sopenharmony_ci self.assertEqual(u.capitalize(), base) 29537db96d56Sopenharmony_ci self.assertIs(u.title().__class__, str) 29547db96d56Sopenharmony_ci self.assertEqual(u.title(), base) 29557db96d56Sopenharmony_ci self.assertIs((u + "").__class__, str) 29567db96d56Sopenharmony_ci self.assertEqual(u + "", base) 29577db96d56Sopenharmony_ci self.assertIs(("" + u).__class__, str) 29587db96d56Sopenharmony_ci self.assertEqual("" + u, base) 29597db96d56Sopenharmony_ci self.assertIs((u * 0).__class__, str) 29607db96d56Sopenharmony_ci self.assertEqual(u * 0, "") 29617db96d56Sopenharmony_ci self.assertIs((u * 1).__class__, str) 29627db96d56Sopenharmony_ci self.assertEqual(u * 1, base) 29637db96d56Sopenharmony_ci self.assertIs((u * 2).__class__, str) 29647db96d56Sopenharmony_ci self.assertEqual(u * 2, base + base) 29657db96d56Sopenharmony_ci self.assertIs(u[:].__class__, str) 29667db96d56Sopenharmony_ci self.assertEqual(u[:], base) 29677db96d56Sopenharmony_ci self.assertIs(u[0:0].__class__, str) 29687db96d56Sopenharmony_ci self.assertEqual(u[0:0], "") 29697db96d56Sopenharmony_ci 29707db96d56Sopenharmony_ci class sublist(list): 29717db96d56Sopenharmony_ci pass 29727db96d56Sopenharmony_ci a = sublist(range(5)) 29737db96d56Sopenharmony_ci self.assertEqual(a, list(range(5))) 29747db96d56Sopenharmony_ci a.append("hello") 29757db96d56Sopenharmony_ci self.assertEqual(a, list(range(5)) + ["hello"]) 29767db96d56Sopenharmony_ci a[5] = 5 29777db96d56Sopenharmony_ci self.assertEqual(a, list(range(6))) 29787db96d56Sopenharmony_ci a.extend(range(6, 20)) 29797db96d56Sopenharmony_ci self.assertEqual(a, list(range(20))) 29807db96d56Sopenharmony_ci a[-5:] = [] 29817db96d56Sopenharmony_ci self.assertEqual(a, list(range(15))) 29827db96d56Sopenharmony_ci del a[10:15] 29837db96d56Sopenharmony_ci self.assertEqual(len(a), 10) 29847db96d56Sopenharmony_ci self.assertEqual(a, list(range(10))) 29857db96d56Sopenharmony_ci self.assertEqual(list(a), list(range(10))) 29867db96d56Sopenharmony_ci self.assertEqual(a[0], 0) 29877db96d56Sopenharmony_ci self.assertEqual(a[9], 9) 29887db96d56Sopenharmony_ci self.assertEqual(a[-10], 0) 29897db96d56Sopenharmony_ci self.assertEqual(a[-1], 9) 29907db96d56Sopenharmony_ci self.assertEqual(a[:5], list(range(5))) 29917db96d56Sopenharmony_ci 29927db96d56Sopenharmony_ci ## class CountedInput(file): 29937db96d56Sopenharmony_ci ## """Counts lines read by self.readline(). 29947db96d56Sopenharmony_ci ## 29957db96d56Sopenharmony_ci ## self.lineno is the 0-based ordinal of the last line read, up to 29967db96d56Sopenharmony_ci ## a maximum of one greater than the number of lines in the file. 29977db96d56Sopenharmony_ci ## 29987db96d56Sopenharmony_ci ## self.ateof is true if and only if the final "" line has been read, 29997db96d56Sopenharmony_ci ## at which point self.lineno stops incrementing, and further calls 30007db96d56Sopenharmony_ci ## to readline() continue to return "". 30017db96d56Sopenharmony_ci ## """ 30027db96d56Sopenharmony_ci ## 30037db96d56Sopenharmony_ci ## lineno = 0 30047db96d56Sopenharmony_ci ## ateof = 0 30057db96d56Sopenharmony_ci ## def readline(self): 30067db96d56Sopenharmony_ci ## if self.ateof: 30077db96d56Sopenharmony_ci ## return "" 30087db96d56Sopenharmony_ci ## s = file.readline(self) 30097db96d56Sopenharmony_ci ## # Next line works too. 30107db96d56Sopenharmony_ci ## # s = super(CountedInput, self).readline() 30117db96d56Sopenharmony_ci ## self.lineno += 1 30127db96d56Sopenharmony_ci ## if s == "": 30137db96d56Sopenharmony_ci ## self.ateof = 1 30147db96d56Sopenharmony_ci ## return s 30157db96d56Sopenharmony_ci ## 30167db96d56Sopenharmony_ci ## f = file(name=os_helper.TESTFN, mode='w') 30177db96d56Sopenharmony_ci ## lines = ['a\n', 'b\n', 'c\n'] 30187db96d56Sopenharmony_ci ## try: 30197db96d56Sopenharmony_ci ## f.writelines(lines) 30207db96d56Sopenharmony_ci ## f.close() 30217db96d56Sopenharmony_ci ## f = CountedInput(os_helper.TESTFN) 30227db96d56Sopenharmony_ci ## for (i, expected) in zip(range(1, 5) + [4], lines + 2 * [""]): 30237db96d56Sopenharmony_ci ## got = f.readline() 30247db96d56Sopenharmony_ci ## self.assertEqual(expected, got) 30257db96d56Sopenharmony_ci ## self.assertEqual(f.lineno, i) 30267db96d56Sopenharmony_ci ## self.assertEqual(f.ateof, (i > len(lines))) 30277db96d56Sopenharmony_ci ## f.close() 30287db96d56Sopenharmony_ci ## finally: 30297db96d56Sopenharmony_ci ## try: 30307db96d56Sopenharmony_ci ## f.close() 30317db96d56Sopenharmony_ci ## except: 30327db96d56Sopenharmony_ci ## pass 30337db96d56Sopenharmony_ci ## os_helper.unlink(os_helper.TESTFN) 30347db96d56Sopenharmony_ci 30357db96d56Sopenharmony_ci def test_keywords(self): 30367db96d56Sopenharmony_ci # Testing keyword args to basic type constructors ... 30377db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, 'keyword argument'): 30387db96d56Sopenharmony_ci int(x=1) 30397db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, 'keyword argument'): 30407db96d56Sopenharmony_ci float(x=2) 30417db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, 'keyword argument'): 30427db96d56Sopenharmony_ci bool(x=2) 30437db96d56Sopenharmony_ci self.assertEqual(complex(imag=42, real=666), complex(666, 42)) 30447db96d56Sopenharmony_ci self.assertEqual(str(object=500), '500') 30457db96d56Sopenharmony_ci self.assertEqual(str(object=b'abc', errors='strict'), 'abc') 30467db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, 'keyword argument'): 30477db96d56Sopenharmony_ci tuple(sequence=range(3)) 30487db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, 'keyword argument'): 30497db96d56Sopenharmony_ci list(sequence=(0, 1, 2)) 30507db96d56Sopenharmony_ci # note: as of Python 2.3, dict() no longer has an "items" keyword arg 30517db96d56Sopenharmony_ci 30527db96d56Sopenharmony_ci for constructor in (int, float, int, complex, str, str, 30537db96d56Sopenharmony_ci tuple, list): 30547db96d56Sopenharmony_ci try: 30557db96d56Sopenharmony_ci constructor(bogus_keyword_arg=1) 30567db96d56Sopenharmony_ci except TypeError: 30577db96d56Sopenharmony_ci pass 30587db96d56Sopenharmony_ci else: 30597db96d56Sopenharmony_ci self.fail("expected TypeError from bogus keyword argument to %r" 30607db96d56Sopenharmony_ci % constructor) 30617db96d56Sopenharmony_ci 30627db96d56Sopenharmony_ci def test_str_subclass_as_dict_key(self): 30637db96d56Sopenharmony_ci # Testing a str subclass used as dict key .. 30647db96d56Sopenharmony_ci 30657db96d56Sopenharmony_ci class cistr(str): 30667db96d56Sopenharmony_ci """Subclass of str that computes __eq__ case-insensitively. 30677db96d56Sopenharmony_ci 30687db96d56Sopenharmony_ci Also computes a hash code of the string in canonical form. 30697db96d56Sopenharmony_ci """ 30707db96d56Sopenharmony_ci 30717db96d56Sopenharmony_ci def __init__(self, value): 30727db96d56Sopenharmony_ci self.canonical = value.lower() 30737db96d56Sopenharmony_ci self.hashcode = hash(self.canonical) 30747db96d56Sopenharmony_ci 30757db96d56Sopenharmony_ci def __eq__(self, other): 30767db96d56Sopenharmony_ci if not isinstance(other, cistr): 30777db96d56Sopenharmony_ci other = cistr(other) 30787db96d56Sopenharmony_ci return self.canonical == other.canonical 30797db96d56Sopenharmony_ci 30807db96d56Sopenharmony_ci def __hash__(self): 30817db96d56Sopenharmony_ci return self.hashcode 30827db96d56Sopenharmony_ci 30837db96d56Sopenharmony_ci self.assertEqual(cistr('ABC'), 'abc') 30847db96d56Sopenharmony_ci self.assertEqual('aBc', cistr('ABC')) 30857db96d56Sopenharmony_ci self.assertEqual(str(cistr('ABC')), 'ABC') 30867db96d56Sopenharmony_ci 30877db96d56Sopenharmony_ci d = {cistr('one'): 1, cistr('two'): 2, cistr('tHree'): 3} 30887db96d56Sopenharmony_ci self.assertEqual(d[cistr('one')], 1) 30897db96d56Sopenharmony_ci self.assertEqual(d[cistr('tWo')], 2) 30907db96d56Sopenharmony_ci self.assertEqual(d[cistr('THrEE')], 3) 30917db96d56Sopenharmony_ci self.assertIn(cistr('ONe'), d) 30927db96d56Sopenharmony_ci self.assertEqual(d.get(cistr('thrEE')), 3) 30937db96d56Sopenharmony_ci 30947db96d56Sopenharmony_ci def test_classic_comparisons(self): 30957db96d56Sopenharmony_ci # Testing classic comparisons... 30967db96d56Sopenharmony_ci class classic: 30977db96d56Sopenharmony_ci pass 30987db96d56Sopenharmony_ci 30997db96d56Sopenharmony_ci for base in (classic, int, object): 31007db96d56Sopenharmony_ci class C(base): 31017db96d56Sopenharmony_ci def __init__(self, value): 31027db96d56Sopenharmony_ci self.value = int(value) 31037db96d56Sopenharmony_ci def __eq__(self, other): 31047db96d56Sopenharmony_ci if isinstance(other, C): 31057db96d56Sopenharmony_ci return self.value == other.value 31067db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 31077db96d56Sopenharmony_ci return self.value == other 31087db96d56Sopenharmony_ci return NotImplemented 31097db96d56Sopenharmony_ci def __ne__(self, other): 31107db96d56Sopenharmony_ci if isinstance(other, C): 31117db96d56Sopenharmony_ci return self.value != other.value 31127db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 31137db96d56Sopenharmony_ci return self.value != other 31147db96d56Sopenharmony_ci return NotImplemented 31157db96d56Sopenharmony_ci def __lt__(self, other): 31167db96d56Sopenharmony_ci if isinstance(other, C): 31177db96d56Sopenharmony_ci return self.value < other.value 31187db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 31197db96d56Sopenharmony_ci return self.value < other 31207db96d56Sopenharmony_ci return NotImplemented 31217db96d56Sopenharmony_ci def __le__(self, other): 31227db96d56Sopenharmony_ci if isinstance(other, C): 31237db96d56Sopenharmony_ci return self.value <= other.value 31247db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 31257db96d56Sopenharmony_ci return self.value <= other 31267db96d56Sopenharmony_ci return NotImplemented 31277db96d56Sopenharmony_ci def __gt__(self, other): 31287db96d56Sopenharmony_ci if isinstance(other, C): 31297db96d56Sopenharmony_ci return self.value > other.value 31307db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 31317db96d56Sopenharmony_ci return self.value > other 31327db96d56Sopenharmony_ci return NotImplemented 31337db96d56Sopenharmony_ci def __ge__(self, other): 31347db96d56Sopenharmony_ci if isinstance(other, C): 31357db96d56Sopenharmony_ci return self.value >= other.value 31367db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 31377db96d56Sopenharmony_ci return self.value >= other 31387db96d56Sopenharmony_ci return NotImplemented 31397db96d56Sopenharmony_ci 31407db96d56Sopenharmony_ci c1 = C(1) 31417db96d56Sopenharmony_ci c2 = C(2) 31427db96d56Sopenharmony_ci c3 = C(3) 31437db96d56Sopenharmony_ci self.assertEqual(c1, 1) 31447db96d56Sopenharmony_ci c = {1: c1, 2: c2, 3: c3} 31457db96d56Sopenharmony_ci for x in 1, 2, 3: 31467db96d56Sopenharmony_ci for y in 1, 2, 3: 31477db96d56Sopenharmony_ci for op in "<", "<=", "==", "!=", ">", ">=": 31487db96d56Sopenharmony_ci self.assertEqual(eval("c[x] %s c[y]" % op), 31497db96d56Sopenharmony_ci eval("x %s y" % op), 31507db96d56Sopenharmony_ci "x=%d, y=%d" % (x, y)) 31517db96d56Sopenharmony_ci self.assertEqual(eval("c[x] %s y" % op), 31527db96d56Sopenharmony_ci eval("x %s y" % op), 31537db96d56Sopenharmony_ci "x=%d, y=%d" % (x, y)) 31547db96d56Sopenharmony_ci self.assertEqual(eval("x %s c[y]" % op), 31557db96d56Sopenharmony_ci eval("x %s y" % op), 31567db96d56Sopenharmony_ci "x=%d, y=%d" % (x, y)) 31577db96d56Sopenharmony_ci 31587db96d56Sopenharmony_ci def test_rich_comparisons(self): 31597db96d56Sopenharmony_ci # Testing rich comparisons... 31607db96d56Sopenharmony_ci class Z(complex): 31617db96d56Sopenharmony_ci pass 31627db96d56Sopenharmony_ci z = Z(1) 31637db96d56Sopenharmony_ci self.assertEqual(z, 1+0j) 31647db96d56Sopenharmony_ci self.assertEqual(1+0j, z) 31657db96d56Sopenharmony_ci class ZZ(complex): 31667db96d56Sopenharmony_ci def __eq__(self, other): 31677db96d56Sopenharmony_ci try: 31687db96d56Sopenharmony_ci return abs(self - other) <= 1e-6 31697db96d56Sopenharmony_ci except: 31707db96d56Sopenharmony_ci return NotImplemented 31717db96d56Sopenharmony_ci zz = ZZ(1.0000003) 31727db96d56Sopenharmony_ci self.assertEqual(zz, 1+0j) 31737db96d56Sopenharmony_ci self.assertEqual(1+0j, zz) 31747db96d56Sopenharmony_ci 31757db96d56Sopenharmony_ci class classic: 31767db96d56Sopenharmony_ci pass 31777db96d56Sopenharmony_ci for base in (classic, int, object, list): 31787db96d56Sopenharmony_ci class C(base): 31797db96d56Sopenharmony_ci def __init__(self, value): 31807db96d56Sopenharmony_ci self.value = int(value) 31817db96d56Sopenharmony_ci def __cmp__(self_, other): 31827db96d56Sopenharmony_ci self.fail("shouldn't call __cmp__") 31837db96d56Sopenharmony_ci def __eq__(self, other): 31847db96d56Sopenharmony_ci if isinstance(other, C): 31857db96d56Sopenharmony_ci return self.value == other.value 31867db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 31877db96d56Sopenharmony_ci return self.value == other 31887db96d56Sopenharmony_ci return NotImplemented 31897db96d56Sopenharmony_ci def __ne__(self, other): 31907db96d56Sopenharmony_ci if isinstance(other, C): 31917db96d56Sopenharmony_ci return self.value != other.value 31927db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 31937db96d56Sopenharmony_ci return self.value != other 31947db96d56Sopenharmony_ci return NotImplemented 31957db96d56Sopenharmony_ci def __lt__(self, other): 31967db96d56Sopenharmony_ci if isinstance(other, C): 31977db96d56Sopenharmony_ci return self.value < other.value 31987db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 31997db96d56Sopenharmony_ci return self.value < other 32007db96d56Sopenharmony_ci return NotImplemented 32017db96d56Sopenharmony_ci def __le__(self, other): 32027db96d56Sopenharmony_ci if isinstance(other, C): 32037db96d56Sopenharmony_ci return self.value <= other.value 32047db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 32057db96d56Sopenharmony_ci return self.value <= other 32067db96d56Sopenharmony_ci return NotImplemented 32077db96d56Sopenharmony_ci def __gt__(self, other): 32087db96d56Sopenharmony_ci if isinstance(other, C): 32097db96d56Sopenharmony_ci return self.value > other.value 32107db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 32117db96d56Sopenharmony_ci return self.value > other 32127db96d56Sopenharmony_ci return NotImplemented 32137db96d56Sopenharmony_ci def __ge__(self, other): 32147db96d56Sopenharmony_ci if isinstance(other, C): 32157db96d56Sopenharmony_ci return self.value >= other.value 32167db96d56Sopenharmony_ci if isinstance(other, int) or isinstance(other, int): 32177db96d56Sopenharmony_ci return self.value >= other 32187db96d56Sopenharmony_ci return NotImplemented 32197db96d56Sopenharmony_ci c1 = C(1) 32207db96d56Sopenharmony_ci c2 = C(2) 32217db96d56Sopenharmony_ci c3 = C(3) 32227db96d56Sopenharmony_ci self.assertEqual(c1, 1) 32237db96d56Sopenharmony_ci c = {1: c1, 2: c2, 3: c3} 32247db96d56Sopenharmony_ci for x in 1, 2, 3: 32257db96d56Sopenharmony_ci for y in 1, 2, 3: 32267db96d56Sopenharmony_ci for op in "<", "<=", "==", "!=", ">", ">=": 32277db96d56Sopenharmony_ci self.assertEqual(eval("c[x] %s c[y]" % op), 32287db96d56Sopenharmony_ci eval("x %s y" % op), 32297db96d56Sopenharmony_ci "x=%d, y=%d" % (x, y)) 32307db96d56Sopenharmony_ci self.assertEqual(eval("c[x] %s y" % op), 32317db96d56Sopenharmony_ci eval("x %s y" % op), 32327db96d56Sopenharmony_ci "x=%d, y=%d" % (x, y)) 32337db96d56Sopenharmony_ci self.assertEqual(eval("x %s c[y]" % op), 32347db96d56Sopenharmony_ci eval("x %s y" % op), 32357db96d56Sopenharmony_ci "x=%d, y=%d" % (x, y)) 32367db96d56Sopenharmony_ci 32377db96d56Sopenharmony_ci def test_descrdoc(self): 32387db96d56Sopenharmony_ci # Testing descriptor doc strings... 32397db96d56Sopenharmony_ci from _io import FileIO 32407db96d56Sopenharmony_ci def check(descr, what): 32417db96d56Sopenharmony_ci self.assertEqual(descr.__doc__, what) 32427db96d56Sopenharmony_ci check(FileIO.closed, "True if the file is closed") # getset descriptor 32437db96d56Sopenharmony_ci check(complex.real, "the real part of a complex number") # member descriptor 32447db96d56Sopenharmony_ci 32457db96d56Sopenharmony_ci def test_doc_descriptor(self): 32467db96d56Sopenharmony_ci # Testing __doc__ descriptor... 32477db96d56Sopenharmony_ci # SF bug 542984 32487db96d56Sopenharmony_ci class DocDescr(object): 32497db96d56Sopenharmony_ci def __get__(self, object, otype): 32507db96d56Sopenharmony_ci if object: 32517db96d56Sopenharmony_ci object = object.__class__.__name__ + ' instance' 32527db96d56Sopenharmony_ci if otype: 32537db96d56Sopenharmony_ci otype = otype.__name__ 32547db96d56Sopenharmony_ci return 'object=%s; type=%s' % (object, otype) 32557db96d56Sopenharmony_ci class OldClass: 32567db96d56Sopenharmony_ci __doc__ = DocDescr() 32577db96d56Sopenharmony_ci class NewClass(object): 32587db96d56Sopenharmony_ci __doc__ = DocDescr() 32597db96d56Sopenharmony_ci self.assertEqual(OldClass.__doc__, 'object=None; type=OldClass') 32607db96d56Sopenharmony_ci self.assertEqual(OldClass().__doc__, 'object=OldClass instance; type=OldClass') 32617db96d56Sopenharmony_ci self.assertEqual(NewClass.__doc__, 'object=None; type=NewClass') 32627db96d56Sopenharmony_ci self.assertEqual(NewClass().__doc__, 'object=NewClass instance; type=NewClass') 32637db96d56Sopenharmony_ci 32647db96d56Sopenharmony_ci def test_set_class(self): 32657db96d56Sopenharmony_ci # Testing __class__ assignment... 32667db96d56Sopenharmony_ci class C(object): pass 32677db96d56Sopenharmony_ci class D(object): pass 32687db96d56Sopenharmony_ci class E(object): pass 32697db96d56Sopenharmony_ci class F(D, E): pass 32707db96d56Sopenharmony_ci for cls in C, D, E, F: 32717db96d56Sopenharmony_ci for cls2 in C, D, E, F: 32727db96d56Sopenharmony_ci x = cls() 32737db96d56Sopenharmony_ci x.__class__ = cls2 32747db96d56Sopenharmony_ci self.assertIs(x.__class__, cls2) 32757db96d56Sopenharmony_ci x.__class__ = cls 32767db96d56Sopenharmony_ci self.assertIs(x.__class__, cls) 32777db96d56Sopenharmony_ci def cant(x, C): 32787db96d56Sopenharmony_ci try: 32797db96d56Sopenharmony_ci x.__class__ = C 32807db96d56Sopenharmony_ci except TypeError: 32817db96d56Sopenharmony_ci pass 32827db96d56Sopenharmony_ci else: 32837db96d56Sopenharmony_ci self.fail("shouldn't allow %r.__class__ = %r" % (x, C)) 32847db96d56Sopenharmony_ci try: 32857db96d56Sopenharmony_ci delattr(x, "__class__") 32867db96d56Sopenharmony_ci except (TypeError, AttributeError): 32877db96d56Sopenharmony_ci pass 32887db96d56Sopenharmony_ci else: 32897db96d56Sopenharmony_ci self.fail("shouldn't allow del %r.__class__" % x) 32907db96d56Sopenharmony_ci cant(C(), list) 32917db96d56Sopenharmony_ci cant(list(), C) 32927db96d56Sopenharmony_ci cant(C(), 1) 32937db96d56Sopenharmony_ci cant(C(), object) 32947db96d56Sopenharmony_ci cant(object(), list) 32957db96d56Sopenharmony_ci cant(list(), object) 32967db96d56Sopenharmony_ci class Int(int): __slots__ = [] 32977db96d56Sopenharmony_ci cant(True, int) 32987db96d56Sopenharmony_ci cant(2, bool) 32997db96d56Sopenharmony_ci o = object() 33007db96d56Sopenharmony_ci cant(o, type(1)) 33017db96d56Sopenharmony_ci cant(o, type(None)) 33027db96d56Sopenharmony_ci del o 33037db96d56Sopenharmony_ci class G(object): 33047db96d56Sopenharmony_ci __slots__ = ["a", "b"] 33057db96d56Sopenharmony_ci class H(object): 33067db96d56Sopenharmony_ci __slots__ = ["b", "a"] 33077db96d56Sopenharmony_ci class I(object): 33087db96d56Sopenharmony_ci __slots__ = ["a", "b"] 33097db96d56Sopenharmony_ci class J(object): 33107db96d56Sopenharmony_ci __slots__ = ["c", "b"] 33117db96d56Sopenharmony_ci class K(object): 33127db96d56Sopenharmony_ci __slots__ = ["a", "b", "d"] 33137db96d56Sopenharmony_ci class L(H): 33147db96d56Sopenharmony_ci __slots__ = ["e"] 33157db96d56Sopenharmony_ci class M(I): 33167db96d56Sopenharmony_ci __slots__ = ["e"] 33177db96d56Sopenharmony_ci class N(J): 33187db96d56Sopenharmony_ci __slots__ = ["__weakref__"] 33197db96d56Sopenharmony_ci class P(J): 33207db96d56Sopenharmony_ci __slots__ = ["__dict__"] 33217db96d56Sopenharmony_ci class Q(J): 33227db96d56Sopenharmony_ci pass 33237db96d56Sopenharmony_ci class R(J): 33247db96d56Sopenharmony_ci __slots__ = ["__dict__", "__weakref__"] 33257db96d56Sopenharmony_ci 33267db96d56Sopenharmony_ci for cls, cls2 in ((G, H), (G, I), (I, H), (Q, R), (R, Q)): 33277db96d56Sopenharmony_ci x = cls() 33287db96d56Sopenharmony_ci x.a = 1 33297db96d56Sopenharmony_ci x.__class__ = cls2 33307db96d56Sopenharmony_ci self.assertIs(x.__class__, cls2, 33317db96d56Sopenharmony_ci "assigning %r as __class__ for %r silently failed" % (cls2, x)) 33327db96d56Sopenharmony_ci self.assertEqual(x.a, 1) 33337db96d56Sopenharmony_ci x.__class__ = cls 33347db96d56Sopenharmony_ci self.assertIs(x.__class__, cls, 33357db96d56Sopenharmony_ci "assigning %r as __class__ for %r silently failed" % (cls, x)) 33367db96d56Sopenharmony_ci self.assertEqual(x.a, 1) 33377db96d56Sopenharmony_ci for cls in G, J, K, L, M, N, P, R, list, Int: 33387db96d56Sopenharmony_ci for cls2 in G, J, K, L, M, N, P, R, list, Int: 33397db96d56Sopenharmony_ci if cls is cls2: 33407db96d56Sopenharmony_ci continue 33417db96d56Sopenharmony_ci cant(cls(), cls2) 33427db96d56Sopenharmony_ci 33437db96d56Sopenharmony_ci # Issue5283: when __class__ changes in __del__, the wrong 33447db96d56Sopenharmony_ci # type gets DECREF'd. 33457db96d56Sopenharmony_ci class O(object): 33467db96d56Sopenharmony_ci pass 33477db96d56Sopenharmony_ci class A(object): 33487db96d56Sopenharmony_ci def __del__(self): 33497db96d56Sopenharmony_ci self.__class__ = O 33507db96d56Sopenharmony_ci l = [A() for x in range(100)] 33517db96d56Sopenharmony_ci del l 33527db96d56Sopenharmony_ci 33537db96d56Sopenharmony_ci def test_set_dict(self): 33547db96d56Sopenharmony_ci # Testing __dict__ assignment... 33557db96d56Sopenharmony_ci class C(object): pass 33567db96d56Sopenharmony_ci a = C() 33577db96d56Sopenharmony_ci a.__dict__ = {'b': 1} 33587db96d56Sopenharmony_ci self.assertEqual(a.b, 1) 33597db96d56Sopenharmony_ci def cant(x, dict): 33607db96d56Sopenharmony_ci try: 33617db96d56Sopenharmony_ci x.__dict__ = dict 33627db96d56Sopenharmony_ci except (AttributeError, TypeError): 33637db96d56Sopenharmony_ci pass 33647db96d56Sopenharmony_ci else: 33657db96d56Sopenharmony_ci self.fail("shouldn't allow %r.__dict__ = %r" % (x, dict)) 33667db96d56Sopenharmony_ci cant(a, None) 33677db96d56Sopenharmony_ci cant(a, []) 33687db96d56Sopenharmony_ci cant(a, 1) 33697db96d56Sopenharmony_ci del a.__dict__ # Deleting __dict__ is allowed 33707db96d56Sopenharmony_ci 33717db96d56Sopenharmony_ci class Base(object): 33727db96d56Sopenharmony_ci pass 33737db96d56Sopenharmony_ci def verify_dict_readonly(x): 33747db96d56Sopenharmony_ci """ 33757db96d56Sopenharmony_ci x has to be an instance of a class inheriting from Base. 33767db96d56Sopenharmony_ci """ 33777db96d56Sopenharmony_ci cant(x, {}) 33787db96d56Sopenharmony_ci try: 33797db96d56Sopenharmony_ci del x.__dict__ 33807db96d56Sopenharmony_ci except (AttributeError, TypeError): 33817db96d56Sopenharmony_ci pass 33827db96d56Sopenharmony_ci else: 33837db96d56Sopenharmony_ci self.fail("shouldn't allow del %r.__dict__" % x) 33847db96d56Sopenharmony_ci dict_descr = Base.__dict__["__dict__"] 33857db96d56Sopenharmony_ci try: 33867db96d56Sopenharmony_ci dict_descr.__set__(x, {}) 33877db96d56Sopenharmony_ci except (AttributeError, TypeError): 33887db96d56Sopenharmony_ci pass 33897db96d56Sopenharmony_ci else: 33907db96d56Sopenharmony_ci self.fail("dict_descr allowed access to %r's dict" % x) 33917db96d56Sopenharmony_ci 33927db96d56Sopenharmony_ci # Classes don't allow __dict__ assignment and have readonly dicts 33937db96d56Sopenharmony_ci class Meta1(type, Base): 33947db96d56Sopenharmony_ci pass 33957db96d56Sopenharmony_ci class Meta2(Base, type): 33967db96d56Sopenharmony_ci pass 33977db96d56Sopenharmony_ci class D(object, metaclass=Meta1): 33987db96d56Sopenharmony_ci pass 33997db96d56Sopenharmony_ci class E(object, metaclass=Meta2): 34007db96d56Sopenharmony_ci pass 34017db96d56Sopenharmony_ci for cls in C, D, E: 34027db96d56Sopenharmony_ci verify_dict_readonly(cls) 34037db96d56Sopenharmony_ci class_dict = cls.__dict__ 34047db96d56Sopenharmony_ci try: 34057db96d56Sopenharmony_ci class_dict["spam"] = "eggs" 34067db96d56Sopenharmony_ci except TypeError: 34077db96d56Sopenharmony_ci pass 34087db96d56Sopenharmony_ci else: 34097db96d56Sopenharmony_ci self.fail("%r's __dict__ can be modified" % cls) 34107db96d56Sopenharmony_ci 34117db96d56Sopenharmony_ci # Modules also disallow __dict__ assignment 34127db96d56Sopenharmony_ci class Module1(types.ModuleType, Base): 34137db96d56Sopenharmony_ci pass 34147db96d56Sopenharmony_ci class Module2(Base, types.ModuleType): 34157db96d56Sopenharmony_ci pass 34167db96d56Sopenharmony_ci for ModuleType in Module1, Module2: 34177db96d56Sopenharmony_ci mod = ModuleType("spam") 34187db96d56Sopenharmony_ci verify_dict_readonly(mod) 34197db96d56Sopenharmony_ci mod.__dict__["spam"] = "eggs" 34207db96d56Sopenharmony_ci 34217db96d56Sopenharmony_ci # Exception's __dict__ can be replaced, but not deleted 34227db96d56Sopenharmony_ci # (at least not any more than regular exception's __dict__ can 34237db96d56Sopenharmony_ci # be deleted; on CPython it is not the case, whereas on PyPy they 34247db96d56Sopenharmony_ci # can, just like any other new-style instance's __dict__.) 34257db96d56Sopenharmony_ci def can_delete_dict(e): 34267db96d56Sopenharmony_ci try: 34277db96d56Sopenharmony_ci del e.__dict__ 34287db96d56Sopenharmony_ci except (TypeError, AttributeError): 34297db96d56Sopenharmony_ci return False 34307db96d56Sopenharmony_ci else: 34317db96d56Sopenharmony_ci return True 34327db96d56Sopenharmony_ci class Exception1(Exception, Base): 34337db96d56Sopenharmony_ci pass 34347db96d56Sopenharmony_ci class Exception2(Base, Exception): 34357db96d56Sopenharmony_ci pass 34367db96d56Sopenharmony_ci for ExceptionType in Exception, Exception1, Exception2: 34377db96d56Sopenharmony_ci e = ExceptionType() 34387db96d56Sopenharmony_ci e.__dict__ = {"a": 1} 34397db96d56Sopenharmony_ci self.assertEqual(e.a, 1) 34407db96d56Sopenharmony_ci self.assertEqual(can_delete_dict(e), can_delete_dict(ValueError())) 34417db96d56Sopenharmony_ci 34427db96d56Sopenharmony_ci def test_binary_operator_override(self): 34437db96d56Sopenharmony_ci # Testing overrides of binary operations... 34447db96d56Sopenharmony_ci class I(int): 34457db96d56Sopenharmony_ci def __repr__(self): 34467db96d56Sopenharmony_ci return "I(%r)" % int(self) 34477db96d56Sopenharmony_ci def __add__(self, other): 34487db96d56Sopenharmony_ci return I(int(self) + int(other)) 34497db96d56Sopenharmony_ci __radd__ = __add__ 34507db96d56Sopenharmony_ci def __pow__(self, other, mod=None): 34517db96d56Sopenharmony_ci if mod is None: 34527db96d56Sopenharmony_ci return I(pow(int(self), int(other))) 34537db96d56Sopenharmony_ci else: 34547db96d56Sopenharmony_ci return I(pow(int(self), int(other), int(mod))) 34557db96d56Sopenharmony_ci def __rpow__(self, other, mod=None): 34567db96d56Sopenharmony_ci if mod is None: 34577db96d56Sopenharmony_ci return I(pow(int(other), int(self), mod)) 34587db96d56Sopenharmony_ci else: 34597db96d56Sopenharmony_ci return I(pow(int(other), int(self), int(mod))) 34607db96d56Sopenharmony_ci 34617db96d56Sopenharmony_ci self.assertEqual(repr(I(1) + I(2)), "I(3)") 34627db96d56Sopenharmony_ci self.assertEqual(repr(I(1) + 2), "I(3)") 34637db96d56Sopenharmony_ci self.assertEqual(repr(1 + I(2)), "I(3)") 34647db96d56Sopenharmony_ci self.assertEqual(repr(I(2) ** I(3)), "I(8)") 34657db96d56Sopenharmony_ci self.assertEqual(repr(2 ** I(3)), "I(8)") 34667db96d56Sopenharmony_ci self.assertEqual(repr(I(2) ** 3), "I(8)") 34677db96d56Sopenharmony_ci self.assertEqual(repr(pow(I(2), I(3), I(5))), "I(3)") 34687db96d56Sopenharmony_ci class S(str): 34697db96d56Sopenharmony_ci def __eq__(self, other): 34707db96d56Sopenharmony_ci return self.lower() == other.lower() 34717db96d56Sopenharmony_ci 34727db96d56Sopenharmony_ci def test_subclass_propagation(self): 34737db96d56Sopenharmony_ci # Testing propagation of slot functions to subclasses... 34747db96d56Sopenharmony_ci class A(object): 34757db96d56Sopenharmony_ci pass 34767db96d56Sopenharmony_ci class B(A): 34777db96d56Sopenharmony_ci pass 34787db96d56Sopenharmony_ci class C(A): 34797db96d56Sopenharmony_ci pass 34807db96d56Sopenharmony_ci class D(B, C): 34817db96d56Sopenharmony_ci pass 34827db96d56Sopenharmony_ci d = D() 34837db96d56Sopenharmony_ci orig_hash = hash(d) # related to id(d) in platform-dependent ways 34847db96d56Sopenharmony_ci A.__hash__ = lambda self: 42 34857db96d56Sopenharmony_ci self.assertEqual(hash(d), 42) 34867db96d56Sopenharmony_ci C.__hash__ = lambda self: 314 34877db96d56Sopenharmony_ci self.assertEqual(hash(d), 314) 34887db96d56Sopenharmony_ci B.__hash__ = lambda self: 144 34897db96d56Sopenharmony_ci self.assertEqual(hash(d), 144) 34907db96d56Sopenharmony_ci D.__hash__ = lambda self: 100 34917db96d56Sopenharmony_ci self.assertEqual(hash(d), 100) 34927db96d56Sopenharmony_ci D.__hash__ = None 34937db96d56Sopenharmony_ci self.assertRaises(TypeError, hash, d) 34947db96d56Sopenharmony_ci del D.__hash__ 34957db96d56Sopenharmony_ci self.assertEqual(hash(d), 144) 34967db96d56Sopenharmony_ci B.__hash__ = None 34977db96d56Sopenharmony_ci self.assertRaises(TypeError, hash, d) 34987db96d56Sopenharmony_ci del B.__hash__ 34997db96d56Sopenharmony_ci self.assertEqual(hash(d), 314) 35007db96d56Sopenharmony_ci C.__hash__ = None 35017db96d56Sopenharmony_ci self.assertRaises(TypeError, hash, d) 35027db96d56Sopenharmony_ci del C.__hash__ 35037db96d56Sopenharmony_ci self.assertEqual(hash(d), 42) 35047db96d56Sopenharmony_ci A.__hash__ = None 35057db96d56Sopenharmony_ci self.assertRaises(TypeError, hash, d) 35067db96d56Sopenharmony_ci del A.__hash__ 35077db96d56Sopenharmony_ci self.assertEqual(hash(d), orig_hash) 35087db96d56Sopenharmony_ci d.foo = 42 35097db96d56Sopenharmony_ci d.bar = 42 35107db96d56Sopenharmony_ci self.assertEqual(d.foo, 42) 35117db96d56Sopenharmony_ci self.assertEqual(d.bar, 42) 35127db96d56Sopenharmony_ci def __getattribute__(self, name): 35137db96d56Sopenharmony_ci if name == "foo": 35147db96d56Sopenharmony_ci return 24 35157db96d56Sopenharmony_ci return object.__getattribute__(self, name) 35167db96d56Sopenharmony_ci A.__getattribute__ = __getattribute__ 35177db96d56Sopenharmony_ci self.assertEqual(d.foo, 24) 35187db96d56Sopenharmony_ci self.assertEqual(d.bar, 42) 35197db96d56Sopenharmony_ci def __getattr__(self, name): 35207db96d56Sopenharmony_ci if name in ("spam", "foo", "bar"): 35217db96d56Sopenharmony_ci return "hello" 35227db96d56Sopenharmony_ci raise AttributeError(name) 35237db96d56Sopenharmony_ci B.__getattr__ = __getattr__ 35247db96d56Sopenharmony_ci self.assertEqual(d.spam, "hello") 35257db96d56Sopenharmony_ci self.assertEqual(d.foo, 24) 35267db96d56Sopenharmony_ci self.assertEqual(d.bar, 42) 35277db96d56Sopenharmony_ci del A.__getattribute__ 35287db96d56Sopenharmony_ci self.assertEqual(d.foo, 42) 35297db96d56Sopenharmony_ci del d.foo 35307db96d56Sopenharmony_ci self.assertEqual(d.foo, "hello") 35317db96d56Sopenharmony_ci self.assertEqual(d.bar, 42) 35327db96d56Sopenharmony_ci del B.__getattr__ 35337db96d56Sopenharmony_ci try: 35347db96d56Sopenharmony_ci d.foo 35357db96d56Sopenharmony_ci except AttributeError: 35367db96d56Sopenharmony_ci pass 35377db96d56Sopenharmony_ci else: 35387db96d56Sopenharmony_ci self.fail("d.foo should be undefined now") 35397db96d56Sopenharmony_ci 35407db96d56Sopenharmony_ci # Test a nasty bug in recurse_down_subclasses() 35417db96d56Sopenharmony_ci class A(object): 35427db96d56Sopenharmony_ci pass 35437db96d56Sopenharmony_ci class B(A): 35447db96d56Sopenharmony_ci pass 35457db96d56Sopenharmony_ci del B 35467db96d56Sopenharmony_ci support.gc_collect() 35477db96d56Sopenharmony_ci A.__setitem__ = lambda *a: None # crash 35487db96d56Sopenharmony_ci 35497db96d56Sopenharmony_ci def test_buffer_inheritance(self): 35507db96d56Sopenharmony_ci # Testing that buffer interface is inherited ... 35517db96d56Sopenharmony_ci 35527db96d56Sopenharmony_ci import binascii 35537db96d56Sopenharmony_ci # SF bug [#470040] ParseTuple t# vs subclasses. 35547db96d56Sopenharmony_ci 35557db96d56Sopenharmony_ci class MyBytes(bytes): 35567db96d56Sopenharmony_ci pass 35577db96d56Sopenharmony_ci base = b'abc' 35587db96d56Sopenharmony_ci m = MyBytes(base) 35597db96d56Sopenharmony_ci # b2a_hex uses the buffer interface to get its argument's value, via 35607db96d56Sopenharmony_ci # PyArg_ParseTuple 't#' code. 35617db96d56Sopenharmony_ci self.assertEqual(binascii.b2a_hex(m), binascii.b2a_hex(base)) 35627db96d56Sopenharmony_ci 35637db96d56Sopenharmony_ci class MyInt(int): 35647db96d56Sopenharmony_ci pass 35657db96d56Sopenharmony_ci m = MyInt(42) 35667db96d56Sopenharmony_ci try: 35677db96d56Sopenharmony_ci binascii.b2a_hex(m) 35687db96d56Sopenharmony_ci self.fail('subclass of int should not have a buffer interface') 35697db96d56Sopenharmony_ci except TypeError: 35707db96d56Sopenharmony_ci pass 35717db96d56Sopenharmony_ci 35727db96d56Sopenharmony_ci def test_str_of_str_subclass(self): 35737db96d56Sopenharmony_ci # Testing __str__ defined in subclass of str ... 35747db96d56Sopenharmony_ci import binascii 35757db96d56Sopenharmony_ci import io 35767db96d56Sopenharmony_ci 35777db96d56Sopenharmony_ci class octetstring(str): 35787db96d56Sopenharmony_ci def __str__(self): 35797db96d56Sopenharmony_ci return binascii.b2a_hex(self.encode('ascii')).decode("ascii") 35807db96d56Sopenharmony_ci def __repr__(self): 35817db96d56Sopenharmony_ci return self + " repr" 35827db96d56Sopenharmony_ci 35837db96d56Sopenharmony_ci o = octetstring('A') 35847db96d56Sopenharmony_ci self.assertEqual(type(o), octetstring) 35857db96d56Sopenharmony_ci self.assertEqual(type(str(o)), str) 35867db96d56Sopenharmony_ci self.assertEqual(type(repr(o)), str) 35877db96d56Sopenharmony_ci self.assertEqual(ord(o), 0x41) 35887db96d56Sopenharmony_ci self.assertEqual(str(o), '41') 35897db96d56Sopenharmony_ci self.assertEqual(repr(o), 'A repr') 35907db96d56Sopenharmony_ci self.assertEqual(o.__str__(), '41') 35917db96d56Sopenharmony_ci self.assertEqual(o.__repr__(), 'A repr') 35927db96d56Sopenharmony_ci 35937db96d56Sopenharmony_ci def test_repr_with_module_str_subclass(self): 35947db96d56Sopenharmony_ci # gh-98783 35957db96d56Sopenharmony_ci class StrSub(str): 35967db96d56Sopenharmony_ci pass 35977db96d56Sopenharmony_ci class Some: 35987db96d56Sopenharmony_ci pass 35997db96d56Sopenharmony_ci Some.__module__ = StrSub('example') 36007db96d56Sopenharmony_ci self.assertIsInstance(repr(Some), str) # should not crash 36017db96d56Sopenharmony_ci self.assertIsInstance(repr(Some()), str) # should not crash 36027db96d56Sopenharmony_ci 36037db96d56Sopenharmony_ci def test_keyword_arguments(self): 36047db96d56Sopenharmony_ci # Testing keyword arguments to __init__, __call__... 36057db96d56Sopenharmony_ci def f(a): return a 36067db96d56Sopenharmony_ci self.assertEqual(f.__call__(a=42), 42) 36077db96d56Sopenharmony_ci ba = bytearray() 36087db96d56Sopenharmony_ci bytearray.__init__(ba, 'abc\xbd\u20ac', 36097db96d56Sopenharmony_ci encoding='latin1', errors='replace') 36107db96d56Sopenharmony_ci self.assertEqual(ba, b'abc\xbd?') 36117db96d56Sopenharmony_ci 36127db96d56Sopenharmony_ci def test_recursive_call(self): 36137db96d56Sopenharmony_ci # Testing recursive __call__() by setting to instance of class... 36147db96d56Sopenharmony_ci class A(object): 36157db96d56Sopenharmony_ci pass 36167db96d56Sopenharmony_ci 36177db96d56Sopenharmony_ci A.__call__ = A() 36187db96d56Sopenharmony_ci with self.assertRaises(RecursionError): 36197db96d56Sopenharmony_ci A()() 36207db96d56Sopenharmony_ci 36217db96d56Sopenharmony_ci def test_delete_hook(self): 36227db96d56Sopenharmony_ci # Testing __del__ hook... 36237db96d56Sopenharmony_ci log = [] 36247db96d56Sopenharmony_ci class C(object): 36257db96d56Sopenharmony_ci def __del__(self): 36267db96d56Sopenharmony_ci log.append(1) 36277db96d56Sopenharmony_ci c = C() 36287db96d56Sopenharmony_ci self.assertEqual(log, []) 36297db96d56Sopenharmony_ci del c 36307db96d56Sopenharmony_ci support.gc_collect() 36317db96d56Sopenharmony_ci self.assertEqual(log, [1]) 36327db96d56Sopenharmony_ci 36337db96d56Sopenharmony_ci class D(object): pass 36347db96d56Sopenharmony_ci d = D() 36357db96d56Sopenharmony_ci try: del d[0] 36367db96d56Sopenharmony_ci except TypeError: pass 36377db96d56Sopenharmony_ci else: self.fail("invalid del() didn't raise TypeError") 36387db96d56Sopenharmony_ci 36397db96d56Sopenharmony_ci def test_hash_inheritance(self): 36407db96d56Sopenharmony_ci # Testing hash of mutable subclasses... 36417db96d56Sopenharmony_ci 36427db96d56Sopenharmony_ci class mydict(dict): 36437db96d56Sopenharmony_ci pass 36447db96d56Sopenharmony_ci d = mydict() 36457db96d56Sopenharmony_ci try: 36467db96d56Sopenharmony_ci hash(d) 36477db96d56Sopenharmony_ci except TypeError: 36487db96d56Sopenharmony_ci pass 36497db96d56Sopenharmony_ci else: 36507db96d56Sopenharmony_ci self.fail("hash() of dict subclass should fail") 36517db96d56Sopenharmony_ci 36527db96d56Sopenharmony_ci class mylist(list): 36537db96d56Sopenharmony_ci pass 36547db96d56Sopenharmony_ci d = mylist() 36557db96d56Sopenharmony_ci try: 36567db96d56Sopenharmony_ci hash(d) 36577db96d56Sopenharmony_ci except TypeError: 36587db96d56Sopenharmony_ci pass 36597db96d56Sopenharmony_ci else: 36607db96d56Sopenharmony_ci self.fail("hash() of list subclass should fail") 36617db96d56Sopenharmony_ci 36627db96d56Sopenharmony_ci def test_str_operations(self): 36637db96d56Sopenharmony_ci try: 'a' + 5 36647db96d56Sopenharmony_ci except TypeError: pass 36657db96d56Sopenharmony_ci else: self.fail("'' + 5 doesn't raise TypeError") 36667db96d56Sopenharmony_ci 36677db96d56Sopenharmony_ci try: ''.split('') 36687db96d56Sopenharmony_ci except ValueError: pass 36697db96d56Sopenharmony_ci else: self.fail("''.split('') doesn't raise ValueError") 36707db96d56Sopenharmony_ci 36717db96d56Sopenharmony_ci try: ''.join([0]) 36727db96d56Sopenharmony_ci except TypeError: pass 36737db96d56Sopenharmony_ci else: self.fail("''.join([0]) doesn't raise TypeError") 36747db96d56Sopenharmony_ci 36757db96d56Sopenharmony_ci try: ''.rindex('5') 36767db96d56Sopenharmony_ci except ValueError: pass 36777db96d56Sopenharmony_ci else: self.fail("''.rindex('5') doesn't raise ValueError") 36787db96d56Sopenharmony_ci 36797db96d56Sopenharmony_ci try: '%(n)s' % None 36807db96d56Sopenharmony_ci except TypeError: pass 36817db96d56Sopenharmony_ci else: self.fail("'%(n)s' % None doesn't raise TypeError") 36827db96d56Sopenharmony_ci 36837db96d56Sopenharmony_ci try: '%(n' % {} 36847db96d56Sopenharmony_ci except ValueError: pass 36857db96d56Sopenharmony_ci else: self.fail("'%(n' % {} '' doesn't raise ValueError") 36867db96d56Sopenharmony_ci 36877db96d56Sopenharmony_ci try: '%*s' % ('abc') 36887db96d56Sopenharmony_ci except TypeError: pass 36897db96d56Sopenharmony_ci else: self.fail("'%*s' % ('abc') doesn't raise TypeError") 36907db96d56Sopenharmony_ci 36917db96d56Sopenharmony_ci try: '%*.*s' % ('abc', 5) 36927db96d56Sopenharmony_ci except TypeError: pass 36937db96d56Sopenharmony_ci else: self.fail("'%*.*s' % ('abc', 5) doesn't raise TypeError") 36947db96d56Sopenharmony_ci 36957db96d56Sopenharmony_ci try: '%s' % (1, 2) 36967db96d56Sopenharmony_ci except TypeError: pass 36977db96d56Sopenharmony_ci else: self.fail("'%s' % (1, 2) doesn't raise TypeError") 36987db96d56Sopenharmony_ci 36997db96d56Sopenharmony_ci try: '%' % None 37007db96d56Sopenharmony_ci except ValueError: pass 37017db96d56Sopenharmony_ci else: self.fail("'%' % None doesn't raise ValueError") 37027db96d56Sopenharmony_ci 37037db96d56Sopenharmony_ci self.assertEqual('534253'.isdigit(), 1) 37047db96d56Sopenharmony_ci self.assertEqual('534253x'.isdigit(), 0) 37057db96d56Sopenharmony_ci self.assertEqual('%c' % 5, '\x05') 37067db96d56Sopenharmony_ci self.assertEqual('%c' % '5', '5') 37077db96d56Sopenharmony_ci 37087db96d56Sopenharmony_ci def test_deepcopy_recursive(self): 37097db96d56Sopenharmony_ci # Testing deepcopy of recursive objects... 37107db96d56Sopenharmony_ci class Node: 37117db96d56Sopenharmony_ci pass 37127db96d56Sopenharmony_ci a = Node() 37137db96d56Sopenharmony_ci b = Node() 37147db96d56Sopenharmony_ci a.b = b 37157db96d56Sopenharmony_ci b.a = a 37167db96d56Sopenharmony_ci z = deepcopy(a) # This blew up before 37177db96d56Sopenharmony_ci 37187db96d56Sopenharmony_ci def test_uninitialized_modules(self): 37197db96d56Sopenharmony_ci # Testing uninitialized module objects... 37207db96d56Sopenharmony_ci from types import ModuleType as M 37217db96d56Sopenharmony_ci m = M.__new__(M) 37227db96d56Sopenharmony_ci str(m) 37237db96d56Sopenharmony_ci self.assertNotHasAttr(m, "__name__") 37247db96d56Sopenharmony_ci self.assertNotHasAttr(m, "__file__") 37257db96d56Sopenharmony_ci self.assertNotHasAttr(m, "foo") 37267db96d56Sopenharmony_ci self.assertFalse(m.__dict__) # None or {} are both reasonable answers 37277db96d56Sopenharmony_ci m.foo = 1 37287db96d56Sopenharmony_ci self.assertEqual(m.__dict__, {"foo": 1}) 37297db96d56Sopenharmony_ci 37307db96d56Sopenharmony_ci def test_funny_new(self): 37317db96d56Sopenharmony_ci # Testing __new__ returning something unexpected... 37327db96d56Sopenharmony_ci class C(object): 37337db96d56Sopenharmony_ci def __new__(cls, arg): 37347db96d56Sopenharmony_ci if isinstance(arg, str): return [1, 2, 3] 37357db96d56Sopenharmony_ci elif isinstance(arg, int): return object.__new__(D) 37367db96d56Sopenharmony_ci else: return object.__new__(cls) 37377db96d56Sopenharmony_ci class D(C): 37387db96d56Sopenharmony_ci def __init__(self, arg): 37397db96d56Sopenharmony_ci self.foo = arg 37407db96d56Sopenharmony_ci self.assertEqual(C("1"), [1, 2, 3]) 37417db96d56Sopenharmony_ci self.assertEqual(D("1"), [1, 2, 3]) 37427db96d56Sopenharmony_ci d = D(None) 37437db96d56Sopenharmony_ci self.assertEqual(d.foo, None) 37447db96d56Sopenharmony_ci d = C(1) 37457db96d56Sopenharmony_ci self.assertIsInstance(d, D) 37467db96d56Sopenharmony_ci self.assertEqual(d.foo, 1) 37477db96d56Sopenharmony_ci d = D(1) 37487db96d56Sopenharmony_ci self.assertIsInstance(d, D) 37497db96d56Sopenharmony_ci self.assertEqual(d.foo, 1) 37507db96d56Sopenharmony_ci 37517db96d56Sopenharmony_ci class C(object): 37527db96d56Sopenharmony_ci @staticmethod 37537db96d56Sopenharmony_ci def __new__(*args): 37547db96d56Sopenharmony_ci return args 37557db96d56Sopenharmony_ci self.assertEqual(C(1, 2), (C, 1, 2)) 37567db96d56Sopenharmony_ci class D(C): 37577db96d56Sopenharmony_ci pass 37587db96d56Sopenharmony_ci self.assertEqual(D(1, 2), (D, 1, 2)) 37597db96d56Sopenharmony_ci 37607db96d56Sopenharmony_ci class C(object): 37617db96d56Sopenharmony_ci @classmethod 37627db96d56Sopenharmony_ci def __new__(*args): 37637db96d56Sopenharmony_ci return args 37647db96d56Sopenharmony_ci self.assertEqual(C(1, 2), (C, C, 1, 2)) 37657db96d56Sopenharmony_ci class D(C): 37667db96d56Sopenharmony_ci pass 37677db96d56Sopenharmony_ci self.assertEqual(D(1, 2), (D, D, 1, 2)) 37687db96d56Sopenharmony_ci 37697db96d56Sopenharmony_ci def test_imul_bug(self): 37707db96d56Sopenharmony_ci # Testing for __imul__ problems... 37717db96d56Sopenharmony_ci # SF bug 544647 37727db96d56Sopenharmony_ci class C(object): 37737db96d56Sopenharmony_ci def __imul__(self, other): 37747db96d56Sopenharmony_ci return (self, other) 37757db96d56Sopenharmony_ci x = C() 37767db96d56Sopenharmony_ci y = x 37777db96d56Sopenharmony_ci y *= 1.0 37787db96d56Sopenharmony_ci self.assertEqual(y, (x, 1.0)) 37797db96d56Sopenharmony_ci y = x 37807db96d56Sopenharmony_ci y *= 2 37817db96d56Sopenharmony_ci self.assertEqual(y, (x, 2)) 37827db96d56Sopenharmony_ci y = x 37837db96d56Sopenharmony_ci y *= 3 37847db96d56Sopenharmony_ci self.assertEqual(y, (x, 3)) 37857db96d56Sopenharmony_ci y = x 37867db96d56Sopenharmony_ci y *= 1<<100 37877db96d56Sopenharmony_ci self.assertEqual(y, (x, 1<<100)) 37887db96d56Sopenharmony_ci y = x 37897db96d56Sopenharmony_ci y *= None 37907db96d56Sopenharmony_ci self.assertEqual(y, (x, None)) 37917db96d56Sopenharmony_ci y = x 37927db96d56Sopenharmony_ci y *= "foo" 37937db96d56Sopenharmony_ci self.assertEqual(y, (x, "foo")) 37947db96d56Sopenharmony_ci 37957db96d56Sopenharmony_ci def test_copy_setstate(self): 37967db96d56Sopenharmony_ci # Testing that copy.*copy() correctly uses __setstate__... 37977db96d56Sopenharmony_ci import copy 37987db96d56Sopenharmony_ci class C(object): 37997db96d56Sopenharmony_ci def __init__(self, foo=None): 38007db96d56Sopenharmony_ci self.foo = foo 38017db96d56Sopenharmony_ci self.__foo = foo 38027db96d56Sopenharmony_ci def setfoo(self, foo=None): 38037db96d56Sopenharmony_ci self.foo = foo 38047db96d56Sopenharmony_ci def getfoo(self): 38057db96d56Sopenharmony_ci return self.__foo 38067db96d56Sopenharmony_ci def __getstate__(self): 38077db96d56Sopenharmony_ci return [self.foo] 38087db96d56Sopenharmony_ci def __setstate__(self_, lst): 38097db96d56Sopenharmony_ci self.assertEqual(len(lst), 1) 38107db96d56Sopenharmony_ci self_.__foo = self_.foo = lst[0] 38117db96d56Sopenharmony_ci a = C(42) 38127db96d56Sopenharmony_ci a.setfoo(24) 38137db96d56Sopenharmony_ci self.assertEqual(a.foo, 24) 38147db96d56Sopenharmony_ci self.assertEqual(a.getfoo(), 42) 38157db96d56Sopenharmony_ci b = copy.copy(a) 38167db96d56Sopenharmony_ci self.assertEqual(b.foo, 24) 38177db96d56Sopenharmony_ci self.assertEqual(b.getfoo(), 24) 38187db96d56Sopenharmony_ci b = copy.deepcopy(a) 38197db96d56Sopenharmony_ci self.assertEqual(b.foo, 24) 38207db96d56Sopenharmony_ci self.assertEqual(b.getfoo(), 24) 38217db96d56Sopenharmony_ci 38227db96d56Sopenharmony_ci def test_slices(self): 38237db96d56Sopenharmony_ci # Testing cases with slices and overridden __getitem__ ... 38247db96d56Sopenharmony_ci 38257db96d56Sopenharmony_ci # Strings 38267db96d56Sopenharmony_ci self.assertEqual("hello"[:4], "hell") 38277db96d56Sopenharmony_ci self.assertEqual("hello"[slice(4)], "hell") 38287db96d56Sopenharmony_ci self.assertEqual(str.__getitem__("hello", slice(4)), "hell") 38297db96d56Sopenharmony_ci class S(str): 38307db96d56Sopenharmony_ci def __getitem__(self, x): 38317db96d56Sopenharmony_ci return str.__getitem__(self, x) 38327db96d56Sopenharmony_ci self.assertEqual(S("hello")[:4], "hell") 38337db96d56Sopenharmony_ci self.assertEqual(S("hello")[slice(4)], "hell") 38347db96d56Sopenharmony_ci self.assertEqual(S("hello").__getitem__(slice(4)), "hell") 38357db96d56Sopenharmony_ci # Tuples 38367db96d56Sopenharmony_ci self.assertEqual((1,2,3)[:2], (1,2)) 38377db96d56Sopenharmony_ci self.assertEqual((1,2,3)[slice(2)], (1,2)) 38387db96d56Sopenharmony_ci self.assertEqual(tuple.__getitem__((1,2,3), slice(2)), (1,2)) 38397db96d56Sopenharmony_ci class T(tuple): 38407db96d56Sopenharmony_ci def __getitem__(self, x): 38417db96d56Sopenharmony_ci return tuple.__getitem__(self, x) 38427db96d56Sopenharmony_ci self.assertEqual(T((1,2,3))[:2], (1,2)) 38437db96d56Sopenharmony_ci self.assertEqual(T((1,2,3))[slice(2)], (1,2)) 38447db96d56Sopenharmony_ci self.assertEqual(T((1,2,3)).__getitem__(slice(2)), (1,2)) 38457db96d56Sopenharmony_ci # Lists 38467db96d56Sopenharmony_ci self.assertEqual([1,2,3][:2], [1,2]) 38477db96d56Sopenharmony_ci self.assertEqual([1,2,3][slice(2)], [1,2]) 38487db96d56Sopenharmony_ci self.assertEqual(list.__getitem__([1,2,3], slice(2)), [1,2]) 38497db96d56Sopenharmony_ci class L(list): 38507db96d56Sopenharmony_ci def __getitem__(self, x): 38517db96d56Sopenharmony_ci return list.__getitem__(self, x) 38527db96d56Sopenharmony_ci self.assertEqual(L([1,2,3])[:2], [1,2]) 38537db96d56Sopenharmony_ci self.assertEqual(L([1,2,3])[slice(2)], [1,2]) 38547db96d56Sopenharmony_ci self.assertEqual(L([1,2,3]).__getitem__(slice(2)), [1,2]) 38557db96d56Sopenharmony_ci # Now do lists and __setitem__ 38567db96d56Sopenharmony_ci a = L([1,2,3]) 38577db96d56Sopenharmony_ci a[slice(1, 3)] = [3,2] 38587db96d56Sopenharmony_ci self.assertEqual(a, [1,3,2]) 38597db96d56Sopenharmony_ci a[slice(0, 2, 1)] = [3,1] 38607db96d56Sopenharmony_ci self.assertEqual(a, [3,1,2]) 38617db96d56Sopenharmony_ci a.__setitem__(slice(1, 3), [2,1]) 38627db96d56Sopenharmony_ci self.assertEqual(a, [3,2,1]) 38637db96d56Sopenharmony_ci a.__setitem__(slice(0, 2, 1), [2,3]) 38647db96d56Sopenharmony_ci self.assertEqual(a, [2,3,1]) 38657db96d56Sopenharmony_ci 38667db96d56Sopenharmony_ci def test_subtype_resurrection(self): 38677db96d56Sopenharmony_ci # Testing resurrection of new-style instance... 38687db96d56Sopenharmony_ci 38697db96d56Sopenharmony_ci class C(object): 38707db96d56Sopenharmony_ci container = [] 38717db96d56Sopenharmony_ci 38727db96d56Sopenharmony_ci def __del__(self): 38737db96d56Sopenharmony_ci # resurrect the instance 38747db96d56Sopenharmony_ci C.container.append(self) 38757db96d56Sopenharmony_ci 38767db96d56Sopenharmony_ci c = C() 38777db96d56Sopenharmony_ci c.attr = 42 38787db96d56Sopenharmony_ci 38797db96d56Sopenharmony_ci # The most interesting thing here is whether this blows up, due to 38807db96d56Sopenharmony_ci # flawed GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 38817db96d56Sopenharmony_ci # bug). 38827db96d56Sopenharmony_ci del c 38837db96d56Sopenharmony_ci 38847db96d56Sopenharmony_ci support.gc_collect() 38857db96d56Sopenharmony_ci self.assertEqual(len(C.container), 1) 38867db96d56Sopenharmony_ci 38877db96d56Sopenharmony_ci # Make c mortal again, so that the test framework with -l doesn't report 38887db96d56Sopenharmony_ci # it as a leak. 38897db96d56Sopenharmony_ci del C.__del__ 38907db96d56Sopenharmony_ci 38917db96d56Sopenharmony_ci def test_slots_trash(self): 38927db96d56Sopenharmony_ci # Testing slot trash... 38937db96d56Sopenharmony_ci # Deallocating deeply nested slotted trash caused stack overflows 38947db96d56Sopenharmony_ci class trash(object): 38957db96d56Sopenharmony_ci __slots__ = ['x'] 38967db96d56Sopenharmony_ci def __init__(self, x): 38977db96d56Sopenharmony_ci self.x = x 38987db96d56Sopenharmony_ci o = None 38997db96d56Sopenharmony_ci for i in range(50000): 39007db96d56Sopenharmony_ci o = trash(o) 39017db96d56Sopenharmony_ci del o 39027db96d56Sopenharmony_ci 39037db96d56Sopenharmony_ci def test_slots_multiple_inheritance(self): 39047db96d56Sopenharmony_ci # SF bug 575229, multiple inheritance w/ slots dumps core 39057db96d56Sopenharmony_ci class A(object): 39067db96d56Sopenharmony_ci __slots__=() 39077db96d56Sopenharmony_ci class B(object): 39087db96d56Sopenharmony_ci pass 39097db96d56Sopenharmony_ci class C(A,B) : 39107db96d56Sopenharmony_ci __slots__=() 39117db96d56Sopenharmony_ci if support.check_impl_detail(): 39127db96d56Sopenharmony_ci self.assertEqual(C.__basicsize__, B.__basicsize__) 39137db96d56Sopenharmony_ci self.assertHasAttr(C, '__dict__') 39147db96d56Sopenharmony_ci self.assertHasAttr(C, '__weakref__') 39157db96d56Sopenharmony_ci C().x = 2 39167db96d56Sopenharmony_ci 39177db96d56Sopenharmony_ci def test_rmul(self): 39187db96d56Sopenharmony_ci # Testing correct invocation of __rmul__... 39197db96d56Sopenharmony_ci # SF patch 592646 39207db96d56Sopenharmony_ci class C(object): 39217db96d56Sopenharmony_ci def __mul__(self, other): 39227db96d56Sopenharmony_ci return "mul" 39237db96d56Sopenharmony_ci def __rmul__(self, other): 39247db96d56Sopenharmony_ci return "rmul" 39257db96d56Sopenharmony_ci a = C() 39267db96d56Sopenharmony_ci self.assertEqual(a*2, "mul") 39277db96d56Sopenharmony_ci self.assertEqual(a*2.2, "mul") 39287db96d56Sopenharmony_ci self.assertEqual(2*a, "rmul") 39297db96d56Sopenharmony_ci self.assertEqual(2.2*a, "rmul") 39307db96d56Sopenharmony_ci 39317db96d56Sopenharmony_ci def test_ipow(self): 39327db96d56Sopenharmony_ci # Testing correct invocation of __ipow__... 39337db96d56Sopenharmony_ci # [SF bug 620179] 39347db96d56Sopenharmony_ci class C(object): 39357db96d56Sopenharmony_ci def __ipow__(self, other): 39367db96d56Sopenharmony_ci pass 39377db96d56Sopenharmony_ci a = C() 39387db96d56Sopenharmony_ci a **= 2 39397db96d56Sopenharmony_ci 39407db96d56Sopenharmony_ci def test_ipow_returns_not_implemented(self): 39417db96d56Sopenharmony_ci class A: 39427db96d56Sopenharmony_ci def __ipow__(self, other): 39437db96d56Sopenharmony_ci return NotImplemented 39447db96d56Sopenharmony_ci 39457db96d56Sopenharmony_ci class B(A): 39467db96d56Sopenharmony_ci def __rpow__(self, other): 39477db96d56Sopenharmony_ci return 1 39487db96d56Sopenharmony_ci 39497db96d56Sopenharmony_ci class C(A): 39507db96d56Sopenharmony_ci def __pow__(self, other): 39517db96d56Sopenharmony_ci return 2 39527db96d56Sopenharmony_ci a = A() 39537db96d56Sopenharmony_ci b = B() 39547db96d56Sopenharmony_ci c = C() 39557db96d56Sopenharmony_ci 39567db96d56Sopenharmony_ci a **= b 39577db96d56Sopenharmony_ci self.assertEqual(a, 1) 39587db96d56Sopenharmony_ci 39597db96d56Sopenharmony_ci c **= b 39607db96d56Sopenharmony_ci self.assertEqual(c, 2) 39617db96d56Sopenharmony_ci 39627db96d56Sopenharmony_ci def test_no_ipow(self): 39637db96d56Sopenharmony_ci class B: 39647db96d56Sopenharmony_ci def __rpow__(self, other): 39657db96d56Sopenharmony_ci return 1 39667db96d56Sopenharmony_ci 39677db96d56Sopenharmony_ci a = object() 39687db96d56Sopenharmony_ci b = B() 39697db96d56Sopenharmony_ci a **= b 39707db96d56Sopenharmony_ci self.assertEqual(a, 1) 39717db96d56Sopenharmony_ci 39727db96d56Sopenharmony_ci def test_ipow_exception_text(self): 39737db96d56Sopenharmony_ci x = None 39747db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 39757db96d56Sopenharmony_ci x **= 2 39767db96d56Sopenharmony_ci self.assertIn('unsupported operand type(s) for **=', str(cm.exception)) 39777db96d56Sopenharmony_ci 39787db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 39797db96d56Sopenharmony_ci y = x ** 2 39807db96d56Sopenharmony_ci self.assertIn('unsupported operand type(s) for **', str(cm.exception)) 39817db96d56Sopenharmony_ci 39827db96d56Sopenharmony_ci def test_mutable_bases(self): 39837db96d56Sopenharmony_ci # Testing mutable bases... 39847db96d56Sopenharmony_ci 39857db96d56Sopenharmony_ci # stuff that should work: 39867db96d56Sopenharmony_ci class C(object): 39877db96d56Sopenharmony_ci pass 39887db96d56Sopenharmony_ci class C2(object): 39897db96d56Sopenharmony_ci def __getattribute__(self, attr): 39907db96d56Sopenharmony_ci if attr == 'a': 39917db96d56Sopenharmony_ci return 2 39927db96d56Sopenharmony_ci else: 39937db96d56Sopenharmony_ci return super(C2, self).__getattribute__(attr) 39947db96d56Sopenharmony_ci def meth(self): 39957db96d56Sopenharmony_ci return 1 39967db96d56Sopenharmony_ci class D(C): 39977db96d56Sopenharmony_ci pass 39987db96d56Sopenharmony_ci class E(D): 39997db96d56Sopenharmony_ci pass 40007db96d56Sopenharmony_ci d = D() 40017db96d56Sopenharmony_ci e = E() 40027db96d56Sopenharmony_ci D.__bases__ = (C,) 40037db96d56Sopenharmony_ci D.__bases__ = (C2,) 40047db96d56Sopenharmony_ci self.assertEqual(d.meth(), 1) 40057db96d56Sopenharmony_ci self.assertEqual(e.meth(), 1) 40067db96d56Sopenharmony_ci self.assertEqual(d.a, 2) 40077db96d56Sopenharmony_ci self.assertEqual(e.a, 2) 40087db96d56Sopenharmony_ci self.assertEqual(C2.__subclasses__(), [D]) 40097db96d56Sopenharmony_ci 40107db96d56Sopenharmony_ci try: 40117db96d56Sopenharmony_ci del D.__bases__ 40127db96d56Sopenharmony_ci except (TypeError, AttributeError): 40137db96d56Sopenharmony_ci pass 40147db96d56Sopenharmony_ci else: 40157db96d56Sopenharmony_ci self.fail("shouldn't be able to delete .__bases__") 40167db96d56Sopenharmony_ci 40177db96d56Sopenharmony_ci try: 40187db96d56Sopenharmony_ci D.__bases__ = () 40197db96d56Sopenharmony_ci except TypeError as msg: 40207db96d56Sopenharmony_ci if str(msg) == "a new-style class can't have only classic bases": 40217db96d56Sopenharmony_ci self.fail("wrong error message for .__bases__ = ()") 40227db96d56Sopenharmony_ci else: 40237db96d56Sopenharmony_ci self.fail("shouldn't be able to set .__bases__ to ()") 40247db96d56Sopenharmony_ci 40257db96d56Sopenharmony_ci try: 40267db96d56Sopenharmony_ci D.__bases__ = (D,) 40277db96d56Sopenharmony_ci except TypeError: 40287db96d56Sopenharmony_ci pass 40297db96d56Sopenharmony_ci else: 40307db96d56Sopenharmony_ci # actually, we'll have crashed by here... 40317db96d56Sopenharmony_ci self.fail("shouldn't be able to create inheritance cycles") 40327db96d56Sopenharmony_ci 40337db96d56Sopenharmony_ci try: 40347db96d56Sopenharmony_ci D.__bases__ = (C, C) 40357db96d56Sopenharmony_ci except TypeError: 40367db96d56Sopenharmony_ci pass 40377db96d56Sopenharmony_ci else: 40387db96d56Sopenharmony_ci self.fail("didn't detect repeated base classes") 40397db96d56Sopenharmony_ci 40407db96d56Sopenharmony_ci try: 40417db96d56Sopenharmony_ci D.__bases__ = (E,) 40427db96d56Sopenharmony_ci except TypeError: 40437db96d56Sopenharmony_ci pass 40447db96d56Sopenharmony_ci else: 40457db96d56Sopenharmony_ci self.fail("shouldn't be able to create inheritance cycles") 40467db96d56Sopenharmony_ci 40477db96d56Sopenharmony_ci def test_builtin_bases(self): 40487db96d56Sopenharmony_ci # Make sure all the builtin types can have their base queried without 40497db96d56Sopenharmony_ci # segfaulting. See issue #5787. 40507db96d56Sopenharmony_ci builtin_types = [tp for tp in builtins.__dict__.values() 40517db96d56Sopenharmony_ci if isinstance(tp, type)] 40527db96d56Sopenharmony_ci for tp in builtin_types: 40537db96d56Sopenharmony_ci object.__getattribute__(tp, "__bases__") 40547db96d56Sopenharmony_ci if tp is not object: 40557db96d56Sopenharmony_ci if tp is ExceptionGroup: 40567db96d56Sopenharmony_ci num_bases = 2 40577db96d56Sopenharmony_ci else: 40587db96d56Sopenharmony_ci num_bases = 1 40597db96d56Sopenharmony_ci self.assertEqual(len(tp.__bases__), num_bases, tp) 40607db96d56Sopenharmony_ci 40617db96d56Sopenharmony_ci class L(list): 40627db96d56Sopenharmony_ci pass 40637db96d56Sopenharmony_ci 40647db96d56Sopenharmony_ci class C(object): 40657db96d56Sopenharmony_ci pass 40667db96d56Sopenharmony_ci 40677db96d56Sopenharmony_ci class D(C): 40687db96d56Sopenharmony_ci pass 40697db96d56Sopenharmony_ci 40707db96d56Sopenharmony_ci try: 40717db96d56Sopenharmony_ci L.__bases__ = (dict,) 40727db96d56Sopenharmony_ci except TypeError: 40737db96d56Sopenharmony_ci pass 40747db96d56Sopenharmony_ci else: 40757db96d56Sopenharmony_ci self.fail("shouldn't turn list subclass into dict subclass") 40767db96d56Sopenharmony_ci 40777db96d56Sopenharmony_ci try: 40787db96d56Sopenharmony_ci list.__bases__ = (dict,) 40797db96d56Sopenharmony_ci except TypeError: 40807db96d56Sopenharmony_ci pass 40817db96d56Sopenharmony_ci else: 40827db96d56Sopenharmony_ci self.fail("shouldn't be able to assign to list.__bases__") 40837db96d56Sopenharmony_ci 40847db96d56Sopenharmony_ci try: 40857db96d56Sopenharmony_ci D.__bases__ = (C, list) 40867db96d56Sopenharmony_ci except TypeError: 40877db96d56Sopenharmony_ci pass 40887db96d56Sopenharmony_ci else: 40897db96d56Sopenharmony_ci self.fail("best_base calculation found wanting") 40907db96d56Sopenharmony_ci 40917db96d56Sopenharmony_ci def test_unsubclassable_types(self): 40927db96d56Sopenharmony_ci with self.assertRaises(TypeError): 40937db96d56Sopenharmony_ci class X(type(None)): 40947db96d56Sopenharmony_ci pass 40957db96d56Sopenharmony_ci with self.assertRaises(TypeError): 40967db96d56Sopenharmony_ci class X(object, type(None)): 40977db96d56Sopenharmony_ci pass 40987db96d56Sopenharmony_ci with self.assertRaises(TypeError): 40997db96d56Sopenharmony_ci class X(type(None), object): 41007db96d56Sopenharmony_ci pass 41017db96d56Sopenharmony_ci class O(object): 41027db96d56Sopenharmony_ci pass 41037db96d56Sopenharmony_ci with self.assertRaises(TypeError): 41047db96d56Sopenharmony_ci class X(O, type(None)): 41057db96d56Sopenharmony_ci pass 41067db96d56Sopenharmony_ci with self.assertRaises(TypeError): 41077db96d56Sopenharmony_ci class X(type(None), O): 41087db96d56Sopenharmony_ci pass 41097db96d56Sopenharmony_ci 41107db96d56Sopenharmony_ci class X(object): 41117db96d56Sopenharmony_ci pass 41127db96d56Sopenharmony_ci with self.assertRaises(TypeError): 41137db96d56Sopenharmony_ci X.__bases__ = type(None), 41147db96d56Sopenharmony_ci with self.assertRaises(TypeError): 41157db96d56Sopenharmony_ci X.__bases__ = object, type(None) 41167db96d56Sopenharmony_ci with self.assertRaises(TypeError): 41177db96d56Sopenharmony_ci X.__bases__ = type(None), object 41187db96d56Sopenharmony_ci with self.assertRaises(TypeError): 41197db96d56Sopenharmony_ci X.__bases__ = O, type(None) 41207db96d56Sopenharmony_ci with self.assertRaises(TypeError): 41217db96d56Sopenharmony_ci X.__bases__ = type(None), O 41227db96d56Sopenharmony_ci 41237db96d56Sopenharmony_ci def test_mutable_bases_with_failing_mro(self): 41247db96d56Sopenharmony_ci # Testing mutable bases with failing mro... 41257db96d56Sopenharmony_ci class WorkOnce(type): 41267db96d56Sopenharmony_ci def __new__(self, name, bases, ns): 41277db96d56Sopenharmony_ci self.flag = 0 41287db96d56Sopenharmony_ci return super(WorkOnce, self).__new__(WorkOnce, name, bases, ns) 41297db96d56Sopenharmony_ci def mro(self): 41307db96d56Sopenharmony_ci if self.flag > 0: 41317db96d56Sopenharmony_ci raise RuntimeError("bozo") 41327db96d56Sopenharmony_ci else: 41337db96d56Sopenharmony_ci self.flag += 1 41347db96d56Sopenharmony_ci return type.mro(self) 41357db96d56Sopenharmony_ci 41367db96d56Sopenharmony_ci class WorkAlways(type): 41377db96d56Sopenharmony_ci def mro(self): 41387db96d56Sopenharmony_ci # this is here to make sure that .mro()s aren't called 41397db96d56Sopenharmony_ci # with an exception set (which was possible at one point). 41407db96d56Sopenharmony_ci # An error message will be printed in a debug build. 41417db96d56Sopenharmony_ci # What's a good way to test for this? 41427db96d56Sopenharmony_ci return type.mro(self) 41437db96d56Sopenharmony_ci 41447db96d56Sopenharmony_ci class C(object): 41457db96d56Sopenharmony_ci pass 41467db96d56Sopenharmony_ci 41477db96d56Sopenharmony_ci class C2(object): 41487db96d56Sopenharmony_ci pass 41497db96d56Sopenharmony_ci 41507db96d56Sopenharmony_ci class D(C): 41517db96d56Sopenharmony_ci pass 41527db96d56Sopenharmony_ci 41537db96d56Sopenharmony_ci class E(D): 41547db96d56Sopenharmony_ci pass 41557db96d56Sopenharmony_ci 41567db96d56Sopenharmony_ci class F(D, metaclass=WorkOnce): 41577db96d56Sopenharmony_ci pass 41587db96d56Sopenharmony_ci 41597db96d56Sopenharmony_ci class G(D, metaclass=WorkAlways): 41607db96d56Sopenharmony_ci pass 41617db96d56Sopenharmony_ci 41627db96d56Sopenharmony_ci # Immediate subclasses have their mro's adjusted in alphabetical 41637db96d56Sopenharmony_ci # order, so E's will get adjusted before adjusting F's fails. We 41647db96d56Sopenharmony_ci # check here that E's gets restored. 41657db96d56Sopenharmony_ci 41667db96d56Sopenharmony_ci E_mro_before = E.__mro__ 41677db96d56Sopenharmony_ci D_mro_before = D.__mro__ 41687db96d56Sopenharmony_ci 41697db96d56Sopenharmony_ci try: 41707db96d56Sopenharmony_ci D.__bases__ = (C2,) 41717db96d56Sopenharmony_ci except RuntimeError: 41727db96d56Sopenharmony_ci self.assertEqual(E.__mro__, E_mro_before) 41737db96d56Sopenharmony_ci self.assertEqual(D.__mro__, D_mro_before) 41747db96d56Sopenharmony_ci else: 41757db96d56Sopenharmony_ci self.fail("exception not propagated") 41767db96d56Sopenharmony_ci 41777db96d56Sopenharmony_ci def test_mutable_bases_catch_mro_conflict(self): 41787db96d56Sopenharmony_ci # Testing mutable bases catch mro conflict... 41797db96d56Sopenharmony_ci class A(object): 41807db96d56Sopenharmony_ci pass 41817db96d56Sopenharmony_ci 41827db96d56Sopenharmony_ci class B(object): 41837db96d56Sopenharmony_ci pass 41847db96d56Sopenharmony_ci 41857db96d56Sopenharmony_ci class C(A, B): 41867db96d56Sopenharmony_ci pass 41877db96d56Sopenharmony_ci 41887db96d56Sopenharmony_ci class D(A, B): 41897db96d56Sopenharmony_ci pass 41907db96d56Sopenharmony_ci 41917db96d56Sopenharmony_ci class E(C, D): 41927db96d56Sopenharmony_ci pass 41937db96d56Sopenharmony_ci 41947db96d56Sopenharmony_ci try: 41957db96d56Sopenharmony_ci C.__bases__ = (B, A) 41967db96d56Sopenharmony_ci except TypeError: 41977db96d56Sopenharmony_ci pass 41987db96d56Sopenharmony_ci else: 41997db96d56Sopenharmony_ci self.fail("didn't catch MRO conflict") 42007db96d56Sopenharmony_ci 42017db96d56Sopenharmony_ci def test_mutable_names(self): 42027db96d56Sopenharmony_ci # Testing mutable names... 42037db96d56Sopenharmony_ci class C(object): 42047db96d56Sopenharmony_ci pass 42057db96d56Sopenharmony_ci 42067db96d56Sopenharmony_ci # C.__module__ could be 'test_descr' or '__main__' 42077db96d56Sopenharmony_ci mod = C.__module__ 42087db96d56Sopenharmony_ci 42097db96d56Sopenharmony_ci C.__name__ = 'D' 42107db96d56Sopenharmony_ci self.assertEqual((C.__module__, C.__name__), (mod, 'D')) 42117db96d56Sopenharmony_ci 42127db96d56Sopenharmony_ci C.__name__ = 'D.E' 42137db96d56Sopenharmony_ci self.assertEqual((C.__module__, C.__name__), (mod, 'D.E')) 42147db96d56Sopenharmony_ci 42157db96d56Sopenharmony_ci def test_evil_type_name(self): 42167db96d56Sopenharmony_ci # A badly placed Py_DECREF in type_set_name led to arbitrary code 42177db96d56Sopenharmony_ci # execution while the type structure was not in a sane state, and a 42187db96d56Sopenharmony_ci # possible segmentation fault as a result. See bug #16447. 42197db96d56Sopenharmony_ci class Nasty(str): 42207db96d56Sopenharmony_ci def __del__(self): 42217db96d56Sopenharmony_ci C.__name__ = "other" 42227db96d56Sopenharmony_ci 42237db96d56Sopenharmony_ci class C: 42247db96d56Sopenharmony_ci pass 42257db96d56Sopenharmony_ci 42267db96d56Sopenharmony_ci C.__name__ = Nasty("abc") 42277db96d56Sopenharmony_ci C.__name__ = "normal" 42287db96d56Sopenharmony_ci 42297db96d56Sopenharmony_ci def test_subclass_right_op(self): 42307db96d56Sopenharmony_ci # Testing correct dispatch of subclass overloading __r<op>__... 42317db96d56Sopenharmony_ci 42327db96d56Sopenharmony_ci # This code tests various cases where right-dispatch of a subclass 42337db96d56Sopenharmony_ci # should be preferred over left-dispatch of a base class. 42347db96d56Sopenharmony_ci 42357db96d56Sopenharmony_ci # Case 1: subclass of int; this tests code in abstract.c::binary_op1() 42367db96d56Sopenharmony_ci 42377db96d56Sopenharmony_ci class B(int): 42387db96d56Sopenharmony_ci def __floordiv__(self, other): 42397db96d56Sopenharmony_ci return "B.__floordiv__" 42407db96d56Sopenharmony_ci def __rfloordiv__(self, other): 42417db96d56Sopenharmony_ci return "B.__rfloordiv__" 42427db96d56Sopenharmony_ci 42437db96d56Sopenharmony_ci self.assertEqual(B(1) // 1, "B.__floordiv__") 42447db96d56Sopenharmony_ci self.assertEqual(1 // B(1), "B.__rfloordiv__") 42457db96d56Sopenharmony_ci 42467db96d56Sopenharmony_ci # Case 2: subclass of object; this is just the baseline for case 3 42477db96d56Sopenharmony_ci 42487db96d56Sopenharmony_ci class C(object): 42497db96d56Sopenharmony_ci def __floordiv__(self, other): 42507db96d56Sopenharmony_ci return "C.__floordiv__" 42517db96d56Sopenharmony_ci def __rfloordiv__(self, other): 42527db96d56Sopenharmony_ci return "C.__rfloordiv__" 42537db96d56Sopenharmony_ci 42547db96d56Sopenharmony_ci self.assertEqual(C() // 1, "C.__floordiv__") 42557db96d56Sopenharmony_ci self.assertEqual(1 // C(), "C.__rfloordiv__") 42567db96d56Sopenharmony_ci 42577db96d56Sopenharmony_ci # Case 3: subclass of new-style class; here it gets interesting 42587db96d56Sopenharmony_ci 42597db96d56Sopenharmony_ci class D(C): 42607db96d56Sopenharmony_ci def __floordiv__(self, other): 42617db96d56Sopenharmony_ci return "D.__floordiv__" 42627db96d56Sopenharmony_ci def __rfloordiv__(self, other): 42637db96d56Sopenharmony_ci return "D.__rfloordiv__" 42647db96d56Sopenharmony_ci 42657db96d56Sopenharmony_ci self.assertEqual(D() // C(), "D.__floordiv__") 42667db96d56Sopenharmony_ci self.assertEqual(C() // D(), "D.__rfloordiv__") 42677db96d56Sopenharmony_ci 42687db96d56Sopenharmony_ci # Case 4: this didn't work right in 2.2.2 and 2.3a1 42697db96d56Sopenharmony_ci 42707db96d56Sopenharmony_ci class E(C): 42717db96d56Sopenharmony_ci pass 42727db96d56Sopenharmony_ci 42737db96d56Sopenharmony_ci self.assertEqual(E.__rfloordiv__, C.__rfloordiv__) 42747db96d56Sopenharmony_ci 42757db96d56Sopenharmony_ci self.assertEqual(E() // 1, "C.__floordiv__") 42767db96d56Sopenharmony_ci self.assertEqual(1 // E(), "C.__rfloordiv__") 42777db96d56Sopenharmony_ci self.assertEqual(E() // C(), "C.__floordiv__") 42787db96d56Sopenharmony_ci self.assertEqual(C() // E(), "C.__floordiv__") # This one would fail 42797db96d56Sopenharmony_ci 42807db96d56Sopenharmony_ci @support.impl_detail("testing an internal kind of method object") 42817db96d56Sopenharmony_ci def test_meth_class_get(self): 42827db96d56Sopenharmony_ci # Testing __get__ method of METH_CLASS C methods... 42837db96d56Sopenharmony_ci # Full coverage of descrobject.c::classmethod_get() 42847db96d56Sopenharmony_ci 42857db96d56Sopenharmony_ci # Baseline 42867db96d56Sopenharmony_ci arg = [1, 2, 3] 42877db96d56Sopenharmony_ci res = {1: None, 2: None, 3: None} 42887db96d56Sopenharmony_ci self.assertEqual(dict.fromkeys(arg), res) 42897db96d56Sopenharmony_ci self.assertEqual({}.fromkeys(arg), res) 42907db96d56Sopenharmony_ci 42917db96d56Sopenharmony_ci # Now get the descriptor 42927db96d56Sopenharmony_ci descr = dict.__dict__["fromkeys"] 42937db96d56Sopenharmony_ci 42947db96d56Sopenharmony_ci # More baseline using the descriptor directly 42957db96d56Sopenharmony_ci self.assertEqual(descr.__get__(None, dict)(arg), res) 42967db96d56Sopenharmony_ci self.assertEqual(descr.__get__({})(arg), res) 42977db96d56Sopenharmony_ci 42987db96d56Sopenharmony_ci # Now check various error cases 42997db96d56Sopenharmony_ci try: 43007db96d56Sopenharmony_ci descr.__get__(None, None) 43017db96d56Sopenharmony_ci except TypeError: 43027db96d56Sopenharmony_ci pass 43037db96d56Sopenharmony_ci else: 43047db96d56Sopenharmony_ci self.fail("shouldn't have allowed descr.__get__(None, None)") 43057db96d56Sopenharmony_ci try: 43067db96d56Sopenharmony_ci descr.__get__(42) 43077db96d56Sopenharmony_ci except TypeError: 43087db96d56Sopenharmony_ci pass 43097db96d56Sopenharmony_ci else: 43107db96d56Sopenharmony_ci self.fail("shouldn't have allowed descr.__get__(42)") 43117db96d56Sopenharmony_ci try: 43127db96d56Sopenharmony_ci descr.__get__(None, 42) 43137db96d56Sopenharmony_ci except TypeError: 43147db96d56Sopenharmony_ci pass 43157db96d56Sopenharmony_ci else: 43167db96d56Sopenharmony_ci self.fail("shouldn't have allowed descr.__get__(None, 42)") 43177db96d56Sopenharmony_ci try: 43187db96d56Sopenharmony_ci descr.__get__(None, int) 43197db96d56Sopenharmony_ci except TypeError: 43207db96d56Sopenharmony_ci pass 43217db96d56Sopenharmony_ci else: 43227db96d56Sopenharmony_ci self.fail("shouldn't have allowed descr.__get__(None, int)") 43237db96d56Sopenharmony_ci 43247db96d56Sopenharmony_ci def test_isinst_isclass(self): 43257db96d56Sopenharmony_ci # Testing proxy isinstance() and isclass()... 43267db96d56Sopenharmony_ci class Proxy(object): 43277db96d56Sopenharmony_ci def __init__(self, obj): 43287db96d56Sopenharmony_ci self.__obj = obj 43297db96d56Sopenharmony_ci def __getattribute__(self, name): 43307db96d56Sopenharmony_ci if name.startswith("_Proxy__"): 43317db96d56Sopenharmony_ci return object.__getattribute__(self, name) 43327db96d56Sopenharmony_ci else: 43337db96d56Sopenharmony_ci return getattr(self.__obj, name) 43347db96d56Sopenharmony_ci # Test with a classic class 43357db96d56Sopenharmony_ci class C: 43367db96d56Sopenharmony_ci pass 43377db96d56Sopenharmony_ci a = C() 43387db96d56Sopenharmony_ci pa = Proxy(a) 43397db96d56Sopenharmony_ci self.assertIsInstance(a, C) # Baseline 43407db96d56Sopenharmony_ci self.assertIsInstance(pa, C) # Test 43417db96d56Sopenharmony_ci # Test with a classic subclass 43427db96d56Sopenharmony_ci class D(C): 43437db96d56Sopenharmony_ci pass 43447db96d56Sopenharmony_ci a = D() 43457db96d56Sopenharmony_ci pa = Proxy(a) 43467db96d56Sopenharmony_ci self.assertIsInstance(a, C) # Baseline 43477db96d56Sopenharmony_ci self.assertIsInstance(pa, C) # Test 43487db96d56Sopenharmony_ci # Test with a new-style class 43497db96d56Sopenharmony_ci class C(object): 43507db96d56Sopenharmony_ci pass 43517db96d56Sopenharmony_ci a = C() 43527db96d56Sopenharmony_ci pa = Proxy(a) 43537db96d56Sopenharmony_ci self.assertIsInstance(a, C) # Baseline 43547db96d56Sopenharmony_ci self.assertIsInstance(pa, C) # Test 43557db96d56Sopenharmony_ci # Test with a new-style subclass 43567db96d56Sopenharmony_ci class D(C): 43577db96d56Sopenharmony_ci pass 43587db96d56Sopenharmony_ci a = D() 43597db96d56Sopenharmony_ci pa = Proxy(a) 43607db96d56Sopenharmony_ci self.assertIsInstance(a, C) # Baseline 43617db96d56Sopenharmony_ci self.assertIsInstance(pa, C) # Test 43627db96d56Sopenharmony_ci 43637db96d56Sopenharmony_ci def test_proxy_super(self): 43647db96d56Sopenharmony_ci # Testing super() for a proxy object... 43657db96d56Sopenharmony_ci class Proxy(object): 43667db96d56Sopenharmony_ci def __init__(self, obj): 43677db96d56Sopenharmony_ci self.__obj = obj 43687db96d56Sopenharmony_ci def __getattribute__(self, name): 43697db96d56Sopenharmony_ci if name.startswith("_Proxy__"): 43707db96d56Sopenharmony_ci return object.__getattribute__(self, name) 43717db96d56Sopenharmony_ci else: 43727db96d56Sopenharmony_ci return getattr(self.__obj, name) 43737db96d56Sopenharmony_ci 43747db96d56Sopenharmony_ci class B(object): 43757db96d56Sopenharmony_ci def f(self): 43767db96d56Sopenharmony_ci return "B.f" 43777db96d56Sopenharmony_ci 43787db96d56Sopenharmony_ci class C(B): 43797db96d56Sopenharmony_ci def f(self): 43807db96d56Sopenharmony_ci return super(C, self).f() + "->C.f" 43817db96d56Sopenharmony_ci 43827db96d56Sopenharmony_ci obj = C() 43837db96d56Sopenharmony_ci p = Proxy(obj) 43847db96d56Sopenharmony_ci self.assertEqual(C.__dict__["f"](p), "B.f->C.f") 43857db96d56Sopenharmony_ci 43867db96d56Sopenharmony_ci def test_carloverre(self): 43877db96d56Sopenharmony_ci # Testing prohibition of Carlo Verre's hack... 43887db96d56Sopenharmony_ci try: 43897db96d56Sopenharmony_ci object.__setattr__(str, "foo", 42) 43907db96d56Sopenharmony_ci except TypeError: 43917db96d56Sopenharmony_ci pass 43927db96d56Sopenharmony_ci else: 43937db96d56Sopenharmony_ci self.fail("Carlo Verre __setattr__ succeeded!") 43947db96d56Sopenharmony_ci try: 43957db96d56Sopenharmony_ci object.__delattr__(str, "lower") 43967db96d56Sopenharmony_ci except TypeError: 43977db96d56Sopenharmony_ci pass 43987db96d56Sopenharmony_ci else: 43997db96d56Sopenharmony_ci self.fail("Carlo Verre __delattr__ succeeded!") 44007db96d56Sopenharmony_ci 44017db96d56Sopenharmony_ci def test_carloverre_multi_inherit_valid(self): 44027db96d56Sopenharmony_ci class A(type): 44037db96d56Sopenharmony_ci def __setattr__(cls, key, value): 44047db96d56Sopenharmony_ci type.__setattr__(cls, key, value) 44057db96d56Sopenharmony_ci 44067db96d56Sopenharmony_ci class B: 44077db96d56Sopenharmony_ci pass 44087db96d56Sopenharmony_ci 44097db96d56Sopenharmony_ci class C(B, A): 44107db96d56Sopenharmony_ci pass 44117db96d56Sopenharmony_ci 44127db96d56Sopenharmony_ci obj = C('D', (object,), {}) 44137db96d56Sopenharmony_ci try: 44147db96d56Sopenharmony_ci obj.test = True 44157db96d56Sopenharmony_ci except TypeError: 44167db96d56Sopenharmony_ci self.fail("setattr through direct base types should be legal") 44177db96d56Sopenharmony_ci 44187db96d56Sopenharmony_ci def test_carloverre_multi_inherit_invalid(self): 44197db96d56Sopenharmony_ci class A(type): 44207db96d56Sopenharmony_ci def __setattr__(cls, key, value): 44217db96d56Sopenharmony_ci object.__setattr__(cls, key, value) # this should fail! 44227db96d56Sopenharmony_ci 44237db96d56Sopenharmony_ci class B: 44247db96d56Sopenharmony_ci pass 44257db96d56Sopenharmony_ci 44267db96d56Sopenharmony_ci class C(B, A): 44277db96d56Sopenharmony_ci pass 44287db96d56Sopenharmony_ci 44297db96d56Sopenharmony_ci obj = C('D', (object,), {}) 44307db96d56Sopenharmony_ci try: 44317db96d56Sopenharmony_ci obj.test = True 44327db96d56Sopenharmony_ci except TypeError: 44337db96d56Sopenharmony_ci pass 44347db96d56Sopenharmony_ci else: 44357db96d56Sopenharmony_ci self.fail("setattr through indirect base types should be rejected") 44367db96d56Sopenharmony_ci 44377db96d56Sopenharmony_ci def test_weakref_segfault(self): 44387db96d56Sopenharmony_ci # Testing weakref segfault... 44397db96d56Sopenharmony_ci # SF 742911 44407db96d56Sopenharmony_ci import weakref 44417db96d56Sopenharmony_ci 44427db96d56Sopenharmony_ci class Provoker: 44437db96d56Sopenharmony_ci def __init__(self, referrent): 44447db96d56Sopenharmony_ci self.ref = weakref.ref(referrent) 44457db96d56Sopenharmony_ci 44467db96d56Sopenharmony_ci def __del__(self): 44477db96d56Sopenharmony_ci x = self.ref() 44487db96d56Sopenharmony_ci 44497db96d56Sopenharmony_ci class Oops(object): 44507db96d56Sopenharmony_ci pass 44517db96d56Sopenharmony_ci 44527db96d56Sopenharmony_ci o = Oops() 44537db96d56Sopenharmony_ci o.whatever = Provoker(o) 44547db96d56Sopenharmony_ci del o 44557db96d56Sopenharmony_ci 44567db96d56Sopenharmony_ci def test_wrapper_segfault(self): 44577db96d56Sopenharmony_ci # SF 927248: deeply nested wrappers could cause stack overflow 44587db96d56Sopenharmony_ci f = lambda:None 44597db96d56Sopenharmony_ci for i in range(1000000): 44607db96d56Sopenharmony_ci f = f.__call__ 44617db96d56Sopenharmony_ci f = None 44627db96d56Sopenharmony_ci 44637db96d56Sopenharmony_ci def test_file_fault(self): 44647db96d56Sopenharmony_ci # Testing sys.stdout is changed in getattr... 44657db96d56Sopenharmony_ci class StdoutGuard: 44667db96d56Sopenharmony_ci def __getattr__(self, attr): 44677db96d56Sopenharmony_ci sys.stdout = sys.__stdout__ 44687db96d56Sopenharmony_ci raise RuntimeError(f"Premature access to sys.stdout.{attr}") 44697db96d56Sopenharmony_ci 44707db96d56Sopenharmony_ci with redirect_stdout(StdoutGuard()): 44717db96d56Sopenharmony_ci with self.assertRaises(RuntimeError): 44727db96d56Sopenharmony_ci print("Oops!") 44737db96d56Sopenharmony_ci 44747db96d56Sopenharmony_ci def test_vicious_descriptor_nonsense(self): 44757db96d56Sopenharmony_ci # Testing vicious_descriptor_nonsense... 44767db96d56Sopenharmony_ci 44777db96d56Sopenharmony_ci # A potential segfault spotted by Thomas Wouters in mail to 44787db96d56Sopenharmony_ci # python-dev 2003-04-17, turned into an example & fixed by Michael 44797db96d56Sopenharmony_ci # Hudson just less than four months later... 44807db96d56Sopenharmony_ci 44817db96d56Sopenharmony_ci class Evil(object): 44827db96d56Sopenharmony_ci def __hash__(self): 44837db96d56Sopenharmony_ci return hash('attr') 44847db96d56Sopenharmony_ci def __eq__(self, other): 44857db96d56Sopenharmony_ci try: 44867db96d56Sopenharmony_ci del C.attr 44877db96d56Sopenharmony_ci except AttributeError: 44887db96d56Sopenharmony_ci # possible race condition 44897db96d56Sopenharmony_ci pass 44907db96d56Sopenharmony_ci return 0 44917db96d56Sopenharmony_ci 44927db96d56Sopenharmony_ci class Descr(object): 44937db96d56Sopenharmony_ci def __get__(self, ob, type=None): 44947db96d56Sopenharmony_ci return 1 44957db96d56Sopenharmony_ci 44967db96d56Sopenharmony_ci class C(object): 44977db96d56Sopenharmony_ci attr = Descr() 44987db96d56Sopenharmony_ci 44997db96d56Sopenharmony_ci c = C() 45007db96d56Sopenharmony_ci c.__dict__[Evil()] = 0 45017db96d56Sopenharmony_ci 45027db96d56Sopenharmony_ci self.assertEqual(c.attr, 1) 45037db96d56Sopenharmony_ci # this makes a crash more likely: 45047db96d56Sopenharmony_ci support.gc_collect() 45057db96d56Sopenharmony_ci self.assertNotHasAttr(c, 'attr') 45067db96d56Sopenharmony_ci 45077db96d56Sopenharmony_ci def test_init(self): 45087db96d56Sopenharmony_ci # SF 1155938 45097db96d56Sopenharmony_ci class Foo(object): 45107db96d56Sopenharmony_ci def __init__(self): 45117db96d56Sopenharmony_ci return 10 45127db96d56Sopenharmony_ci try: 45137db96d56Sopenharmony_ci Foo() 45147db96d56Sopenharmony_ci except TypeError: 45157db96d56Sopenharmony_ci pass 45167db96d56Sopenharmony_ci else: 45177db96d56Sopenharmony_ci self.fail("did not test __init__() for None return") 45187db96d56Sopenharmony_ci 45197db96d56Sopenharmony_ci def assertNotOrderable(self, a, b): 45207db96d56Sopenharmony_ci with self.assertRaises(TypeError): 45217db96d56Sopenharmony_ci a < b 45227db96d56Sopenharmony_ci with self.assertRaises(TypeError): 45237db96d56Sopenharmony_ci a > b 45247db96d56Sopenharmony_ci with self.assertRaises(TypeError): 45257db96d56Sopenharmony_ci a <= b 45267db96d56Sopenharmony_ci with self.assertRaises(TypeError): 45277db96d56Sopenharmony_ci a >= b 45287db96d56Sopenharmony_ci 45297db96d56Sopenharmony_ci def test_method_wrapper(self): 45307db96d56Sopenharmony_ci # Testing method-wrapper objects... 45317db96d56Sopenharmony_ci # <type 'method-wrapper'> did not support any reflection before 2.5 45327db96d56Sopenharmony_ci l = [] 45337db96d56Sopenharmony_ci self.assertTrue(l.__add__ == l.__add__) 45347db96d56Sopenharmony_ci self.assertFalse(l.__add__ != l.__add__) 45357db96d56Sopenharmony_ci self.assertFalse(l.__add__ == [].__add__) 45367db96d56Sopenharmony_ci self.assertTrue(l.__add__ != [].__add__) 45377db96d56Sopenharmony_ci self.assertFalse(l.__add__ == l.__mul__) 45387db96d56Sopenharmony_ci self.assertTrue(l.__add__ != l.__mul__) 45397db96d56Sopenharmony_ci self.assertNotOrderable(l.__add__, l.__add__) 45407db96d56Sopenharmony_ci self.assertEqual(l.__add__.__name__, '__add__') 45417db96d56Sopenharmony_ci self.assertIs(l.__add__.__self__, l) 45427db96d56Sopenharmony_ci self.assertIs(l.__add__.__objclass__, list) 45437db96d56Sopenharmony_ci self.assertEqual(l.__add__.__doc__, list.__add__.__doc__) 45447db96d56Sopenharmony_ci # hash([].__add__) should not be based on hash([]) 45457db96d56Sopenharmony_ci hash(l.__add__) 45467db96d56Sopenharmony_ci 45477db96d56Sopenharmony_ci def test_builtin_function_or_method(self): 45487db96d56Sopenharmony_ci # Not really belonging to test_descr, but introspection and 45497db96d56Sopenharmony_ci # comparison on <type 'builtin_function_or_method'> seems not 45507db96d56Sopenharmony_ci # to be tested elsewhere 45517db96d56Sopenharmony_ci l = [] 45527db96d56Sopenharmony_ci self.assertTrue(l.append == l.append) 45537db96d56Sopenharmony_ci self.assertFalse(l.append != l.append) 45547db96d56Sopenharmony_ci self.assertFalse(l.append == [].append) 45557db96d56Sopenharmony_ci self.assertTrue(l.append != [].append) 45567db96d56Sopenharmony_ci self.assertFalse(l.append == l.pop) 45577db96d56Sopenharmony_ci self.assertTrue(l.append != l.pop) 45587db96d56Sopenharmony_ci self.assertNotOrderable(l.append, l.append) 45597db96d56Sopenharmony_ci self.assertEqual(l.append.__name__, 'append') 45607db96d56Sopenharmony_ci self.assertIs(l.append.__self__, l) 45617db96d56Sopenharmony_ci # self.assertIs(l.append.__objclass__, list) --- could be added? 45627db96d56Sopenharmony_ci self.assertEqual(l.append.__doc__, list.append.__doc__) 45637db96d56Sopenharmony_ci # hash([].append) should not be based on hash([]) 45647db96d56Sopenharmony_ci hash(l.append) 45657db96d56Sopenharmony_ci 45667db96d56Sopenharmony_ci def test_special_unbound_method_types(self): 45677db96d56Sopenharmony_ci # Testing objects of <type 'wrapper_descriptor'>... 45687db96d56Sopenharmony_ci self.assertTrue(list.__add__ == list.__add__) 45697db96d56Sopenharmony_ci self.assertFalse(list.__add__ != list.__add__) 45707db96d56Sopenharmony_ci self.assertFalse(list.__add__ == list.__mul__) 45717db96d56Sopenharmony_ci self.assertTrue(list.__add__ != list.__mul__) 45727db96d56Sopenharmony_ci self.assertNotOrderable(list.__add__, list.__add__) 45737db96d56Sopenharmony_ci self.assertEqual(list.__add__.__name__, '__add__') 45747db96d56Sopenharmony_ci self.assertIs(list.__add__.__objclass__, list) 45757db96d56Sopenharmony_ci 45767db96d56Sopenharmony_ci # Testing objects of <type 'method_descriptor'>... 45777db96d56Sopenharmony_ci self.assertTrue(list.append == list.append) 45787db96d56Sopenharmony_ci self.assertFalse(list.append != list.append) 45797db96d56Sopenharmony_ci self.assertFalse(list.append == list.pop) 45807db96d56Sopenharmony_ci self.assertTrue(list.append != list.pop) 45817db96d56Sopenharmony_ci self.assertNotOrderable(list.append, list.append) 45827db96d56Sopenharmony_ci self.assertEqual(list.append.__name__, 'append') 45837db96d56Sopenharmony_ci self.assertIs(list.append.__objclass__, list) 45847db96d56Sopenharmony_ci 45857db96d56Sopenharmony_ci def test_not_implemented(self): 45867db96d56Sopenharmony_ci # Testing NotImplemented... 45877db96d56Sopenharmony_ci # all binary methods should be able to return a NotImplemented 45887db96d56Sopenharmony_ci import operator 45897db96d56Sopenharmony_ci 45907db96d56Sopenharmony_ci def specialmethod(self, other): 45917db96d56Sopenharmony_ci return NotImplemented 45927db96d56Sopenharmony_ci 45937db96d56Sopenharmony_ci def check(expr, x, y): 45947db96d56Sopenharmony_ci try: 45957db96d56Sopenharmony_ci exec(expr, {'x': x, 'y': y, 'operator': operator}) 45967db96d56Sopenharmony_ci except TypeError: 45977db96d56Sopenharmony_ci pass 45987db96d56Sopenharmony_ci else: 45997db96d56Sopenharmony_ci self.fail("no TypeError from %r" % (expr,)) 46007db96d56Sopenharmony_ci 46017db96d56Sopenharmony_ci N1 = sys.maxsize + 1 # might trigger OverflowErrors instead of 46027db96d56Sopenharmony_ci # TypeErrors 46037db96d56Sopenharmony_ci N2 = sys.maxsize # if sizeof(int) < sizeof(long), might trigger 46047db96d56Sopenharmony_ci # ValueErrors instead of TypeErrors 46057db96d56Sopenharmony_ci for name, expr, iexpr in [ 46067db96d56Sopenharmony_ci ('__add__', 'x + y', 'x += y'), 46077db96d56Sopenharmony_ci ('__sub__', 'x - y', 'x -= y'), 46087db96d56Sopenharmony_ci ('__mul__', 'x * y', 'x *= y'), 46097db96d56Sopenharmony_ci ('__matmul__', 'x @ y', 'x @= y'), 46107db96d56Sopenharmony_ci ('__truediv__', 'x / y', 'x /= y'), 46117db96d56Sopenharmony_ci ('__floordiv__', 'x // y', 'x //= y'), 46127db96d56Sopenharmony_ci ('__mod__', 'x % y', 'x %= y'), 46137db96d56Sopenharmony_ci ('__divmod__', 'divmod(x, y)', None), 46147db96d56Sopenharmony_ci ('__pow__', 'x ** y', 'x **= y'), 46157db96d56Sopenharmony_ci ('__lshift__', 'x << y', 'x <<= y'), 46167db96d56Sopenharmony_ci ('__rshift__', 'x >> y', 'x >>= y'), 46177db96d56Sopenharmony_ci ('__and__', 'x & y', 'x &= y'), 46187db96d56Sopenharmony_ci ('__or__', 'x | y', 'x |= y'), 46197db96d56Sopenharmony_ci ('__xor__', 'x ^ y', 'x ^= y')]: 46207db96d56Sopenharmony_ci rname = '__r' + name[2:] 46217db96d56Sopenharmony_ci A = type('A', (), {name: specialmethod}) 46227db96d56Sopenharmony_ci a = A() 46237db96d56Sopenharmony_ci check(expr, a, a) 46247db96d56Sopenharmony_ci check(expr, a, N1) 46257db96d56Sopenharmony_ci check(expr, a, N2) 46267db96d56Sopenharmony_ci if iexpr: 46277db96d56Sopenharmony_ci check(iexpr, a, a) 46287db96d56Sopenharmony_ci check(iexpr, a, N1) 46297db96d56Sopenharmony_ci check(iexpr, a, N2) 46307db96d56Sopenharmony_ci iname = '__i' + name[2:] 46317db96d56Sopenharmony_ci C = type('C', (), {iname: specialmethod}) 46327db96d56Sopenharmony_ci c = C() 46337db96d56Sopenharmony_ci check(iexpr, c, a) 46347db96d56Sopenharmony_ci check(iexpr, c, N1) 46357db96d56Sopenharmony_ci check(iexpr, c, N2) 46367db96d56Sopenharmony_ci 46377db96d56Sopenharmony_ci def test_assign_slice(self): 46387db96d56Sopenharmony_ci # ceval.c's assign_slice used to check for 46397db96d56Sopenharmony_ci # tp->tp_as_sequence->sq_slice instead of 46407db96d56Sopenharmony_ci # tp->tp_as_sequence->sq_ass_slice 46417db96d56Sopenharmony_ci 46427db96d56Sopenharmony_ci class C(object): 46437db96d56Sopenharmony_ci def __setitem__(self, idx, value): 46447db96d56Sopenharmony_ci self.value = value 46457db96d56Sopenharmony_ci 46467db96d56Sopenharmony_ci c = C() 46477db96d56Sopenharmony_ci c[1:2] = 3 46487db96d56Sopenharmony_ci self.assertEqual(c.value, 3) 46497db96d56Sopenharmony_ci 46507db96d56Sopenharmony_ci def test_set_and_no_get(self): 46517db96d56Sopenharmony_ci # See 46527db96d56Sopenharmony_ci # http://mail.python.org/pipermail/python-dev/2010-January/095637.html 46537db96d56Sopenharmony_ci class Descr(object): 46547db96d56Sopenharmony_ci 46557db96d56Sopenharmony_ci def __init__(self, name): 46567db96d56Sopenharmony_ci self.name = name 46577db96d56Sopenharmony_ci 46587db96d56Sopenharmony_ci def __set__(self, obj, value): 46597db96d56Sopenharmony_ci obj.__dict__[self.name] = value 46607db96d56Sopenharmony_ci descr = Descr("a") 46617db96d56Sopenharmony_ci 46627db96d56Sopenharmony_ci class X(object): 46637db96d56Sopenharmony_ci a = descr 46647db96d56Sopenharmony_ci 46657db96d56Sopenharmony_ci x = X() 46667db96d56Sopenharmony_ci self.assertIs(x.a, descr) 46677db96d56Sopenharmony_ci x.a = 42 46687db96d56Sopenharmony_ci self.assertEqual(x.a, 42) 46697db96d56Sopenharmony_ci 46707db96d56Sopenharmony_ci # Also check type_getattro for correctness. 46717db96d56Sopenharmony_ci class Meta(type): 46727db96d56Sopenharmony_ci pass 46737db96d56Sopenharmony_ci class X(metaclass=Meta): 46747db96d56Sopenharmony_ci pass 46757db96d56Sopenharmony_ci X.a = 42 46767db96d56Sopenharmony_ci Meta.a = Descr("a") 46777db96d56Sopenharmony_ci self.assertEqual(X.a, 42) 46787db96d56Sopenharmony_ci 46797db96d56Sopenharmony_ci def test_getattr_hooks(self): 46807db96d56Sopenharmony_ci # issue 4230 46817db96d56Sopenharmony_ci 46827db96d56Sopenharmony_ci class Descriptor(object): 46837db96d56Sopenharmony_ci counter = 0 46847db96d56Sopenharmony_ci def __get__(self, obj, objtype=None): 46857db96d56Sopenharmony_ci def getter(name): 46867db96d56Sopenharmony_ci self.counter += 1 46877db96d56Sopenharmony_ci raise AttributeError(name) 46887db96d56Sopenharmony_ci return getter 46897db96d56Sopenharmony_ci 46907db96d56Sopenharmony_ci descr = Descriptor() 46917db96d56Sopenharmony_ci class A(object): 46927db96d56Sopenharmony_ci __getattribute__ = descr 46937db96d56Sopenharmony_ci class B(object): 46947db96d56Sopenharmony_ci __getattr__ = descr 46957db96d56Sopenharmony_ci class C(object): 46967db96d56Sopenharmony_ci __getattribute__ = descr 46977db96d56Sopenharmony_ci __getattr__ = descr 46987db96d56Sopenharmony_ci 46997db96d56Sopenharmony_ci self.assertRaises(AttributeError, getattr, A(), "attr") 47007db96d56Sopenharmony_ci self.assertEqual(descr.counter, 1) 47017db96d56Sopenharmony_ci self.assertRaises(AttributeError, getattr, B(), "attr") 47027db96d56Sopenharmony_ci self.assertEqual(descr.counter, 2) 47037db96d56Sopenharmony_ci self.assertRaises(AttributeError, getattr, C(), "attr") 47047db96d56Sopenharmony_ci self.assertEqual(descr.counter, 4) 47057db96d56Sopenharmony_ci 47067db96d56Sopenharmony_ci class EvilGetattribute(object): 47077db96d56Sopenharmony_ci # This used to segfault 47087db96d56Sopenharmony_ci def __getattr__(self, name): 47097db96d56Sopenharmony_ci raise AttributeError(name) 47107db96d56Sopenharmony_ci def __getattribute__(self, name): 47117db96d56Sopenharmony_ci del EvilGetattribute.__getattr__ 47127db96d56Sopenharmony_ci for i in range(5): 47137db96d56Sopenharmony_ci gc.collect() 47147db96d56Sopenharmony_ci raise AttributeError(name) 47157db96d56Sopenharmony_ci 47167db96d56Sopenharmony_ci self.assertRaises(AttributeError, getattr, EvilGetattribute(), "attr") 47177db96d56Sopenharmony_ci 47187db96d56Sopenharmony_ci def test_type___getattribute__(self): 47197db96d56Sopenharmony_ci self.assertRaises(TypeError, type.__getattribute__, list, type) 47207db96d56Sopenharmony_ci 47217db96d56Sopenharmony_ci def test_abstractmethods(self): 47227db96d56Sopenharmony_ci # type pretends not to have __abstractmethods__. 47237db96d56Sopenharmony_ci self.assertRaises(AttributeError, getattr, type, "__abstractmethods__") 47247db96d56Sopenharmony_ci class meta(type): 47257db96d56Sopenharmony_ci pass 47267db96d56Sopenharmony_ci self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__") 47277db96d56Sopenharmony_ci class X(object): 47287db96d56Sopenharmony_ci pass 47297db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 47307db96d56Sopenharmony_ci del X.__abstractmethods__ 47317db96d56Sopenharmony_ci 47327db96d56Sopenharmony_ci def test_proxy_call(self): 47337db96d56Sopenharmony_ci class FakeStr: 47347db96d56Sopenharmony_ci __class__ = str 47357db96d56Sopenharmony_ci 47367db96d56Sopenharmony_ci fake_str = FakeStr() 47377db96d56Sopenharmony_ci # isinstance() reads __class__ 47387db96d56Sopenharmony_ci self.assertIsInstance(fake_str, str) 47397db96d56Sopenharmony_ci 47407db96d56Sopenharmony_ci # call a method descriptor 47417db96d56Sopenharmony_ci with self.assertRaises(TypeError): 47427db96d56Sopenharmony_ci str.split(fake_str) 47437db96d56Sopenharmony_ci 47447db96d56Sopenharmony_ci # call a slot wrapper descriptor 47457db96d56Sopenharmony_ci with self.assertRaises(TypeError): 47467db96d56Sopenharmony_ci str.__add__(fake_str, "abc") 47477db96d56Sopenharmony_ci 47487db96d56Sopenharmony_ci def test_specialized_method_calls_check_types(self): 47497db96d56Sopenharmony_ci # https://github.com/python/cpython/issues/92063 47507db96d56Sopenharmony_ci class Thing: 47517db96d56Sopenharmony_ci pass 47527db96d56Sopenharmony_ci thing = Thing() 47537db96d56Sopenharmony_ci for i in range(20): 47547db96d56Sopenharmony_ci with self.assertRaises(TypeError): 47557db96d56Sopenharmony_ci # PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 47567db96d56Sopenharmony_ci list.sort(thing) 47577db96d56Sopenharmony_ci for i in range(20): 47587db96d56Sopenharmony_ci with self.assertRaises(TypeError): 47597db96d56Sopenharmony_ci # PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 47607db96d56Sopenharmony_ci str.split(thing) 47617db96d56Sopenharmony_ci for i in range(20): 47627db96d56Sopenharmony_ci with self.assertRaises(TypeError): 47637db96d56Sopenharmony_ci # PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 47647db96d56Sopenharmony_ci str.upper(thing) 47657db96d56Sopenharmony_ci for i in range(20): 47667db96d56Sopenharmony_ci with self.assertRaises(TypeError): 47677db96d56Sopenharmony_ci # PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 47687db96d56Sopenharmony_ci str.strip(thing) 47697db96d56Sopenharmony_ci from collections import deque 47707db96d56Sopenharmony_ci for i in range(20): 47717db96d56Sopenharmony_ci with self.assertRaises(TypeError): 47727db96d56Sopenharmony_ci # PRECALL_NO_KW_METHOD_DESCRIPTOR_O 47737db96d56Sopenharmony_ci deque.append(thing, thing) 47747db96d56Sopenharmony_ci 47757db96d56Sopenharmony_ci def test_repr_as_str(self): 47767db96d56Sopenharmony_ci # Issue #11603: crash or infinite loop when rebinding __str__ as 47777db96d56Sopenharmony_ci # __repr__. 47787db96d56Sopenharmony_ci class Foo: 47797db96d56Sopenharmony_ci pass 47807db96d56Sopenharmony_ci Foo.__repr__ = Foo.__str__ 47817db96d56Sopenharmony_ci foo = Foo() 47827db96d56Sopenharmony_ci self.assertRaises(RecursionError, str, foo) 47837db96d56Sopenharmony_ci self.assertRaises(RecursionError, repr, foo) 47847db96d56Sopenharmony_ci 47857db96d56Sopenharmony_ci def test_mixing_slot_wrappers(self): 47867db96d56Sopenharmony_ci class X(dict): 47877db96d56Sopenharmony_ci __setattr__ = dict.__setitem__ 47887db96d56Sopenharmony_ci __neg__ = dict.copy 47897db96d56Sopenharmony_ci x = X() 47907db96d56Sopenharmony_ci x.y = 42 47917db96d56Sopenharmony_ci self.assertEqual(x["y"], 42) 47927db96d56Sopenharmony_ci self.assertEqual(x, -x) 47937db96d56Sopenharmony_ci 47947db96d56Sopenharmony_ci def test_wrong_class_slot_wrapper(self): 47957db96d56Sopenharmony_ci # Check bpo-37619: a wrapper descriptor taken from the wrong class 47967db96d56Sopenharmony_ci # should raise an exception instead of silently being ignored 47977db96d56Sopenharmony_ci class A(int): 47987db96d56Sopenharmony_ci __eq__ = str.__eq__ 47997db96d56Sopenharmony_ci __add__ = str.__add__ 48007db96d56Sopenharmony_ci a = A() 48017db96d56Sopenharmony_ci with self.assertRaises(TypeError): 48027db96d56Sopenharmony_ci a == a 48037db96d56Sopenharmony_ci with self.assertRaises(TypeError): 48047db96d56Sopenharmony_ci a + a 48057db96d56Sopenharmony_ci 48067db96d56Sopenharmony_ci def test_slot_shadows_class_variable(self): 48077db96d56Sopenharmony_ci with self.assertRaises(ValueError) as cm: 48087db96d56Sopenharmony_ci class X: 48097db96d56Sopenharmony_ci __slots__ = ["foo"] 48107db96d56Sopenharmony_ci foo = None 48117db96d56Sopenharmony_ci m = str(cm.exception) 48127db96d56Sopenharmony_ci self.assertEqual("'foo' in __slots__ conflicts with class variable", m) 48137db96d56Sopenharmony_ci 48147db96d56Sopenharmony_ci def test_set_doc(self): 48157db96d56Sopenharmony_ci class X: 48167db96d56Sopenharmony_ci "elephant" 48177db96d56Sopenharmony_ci X.__doc__ = "banana" 48187db96d56Sopenharmony_ci self.assertEqual(X.__doc__, "banana") 48197db96d56Sopenharmony_ci 48207db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 48217db96d56Sopenharmony_ci type(list).__dict__["__doc__"].__set__(list, "blah") 48227db96d56Sopenharmony_ci self.assertIn("cannot set '__doc__' attribute of immutable type 'list'", str(cm.exception)) 48237db96d56Sopenharmony_ci 48247db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 48257db96d56Sopenharmony_ci type(X).__dict__["__doc__"].__delete__(X) 48267db96d56Sopenharmony_ci self.assertIn("cannot delete '__doc__' attribute of immutable type 'X'", str(cm.exception)) 48277db96d56Sopenharmony_ci self.assertEqual(X.__doc__, "banana") 48287db96d56Sopenharmony_ci 48297db96d56Sopenharmony_ci def test_qualname(self): 48307db96d56Sopenharmony_ci descriptors = [str.lower, complex.real, float.real, int.__add__] 48317db96d56Sopenharmony_ci types = ['method', 'member', 'getset', 'wrapper'] 48327db96d56Sopenharmony_ci 48337db96d56Sopenharmony_ci # make sure we have an example of each type of descriptor 48347db96d56Sopenharmony_ci for d, n in zip(descriptors, types): 48357db96d56Sopenharmony_ci self.assertEqual(type(d).__name__, n + '_descriptor') 48367db96d56Sopenharmony_ci 48377db96d56Sopenharmony_ci for d in descriptors: 48387db96d56Sopenharmony_ci qualname = d.__objclass__.__qualname__ + '.' + d.__name__ 48397db96d56Sopenharmony_ci self.assertEqual(d.__qualname__, qualname) 48407db96d56Sopenharmony_ci 48417db96d56Sopenharmony_ci self.assertEqual(str.lower.__qualname__, 'str.lower') 48427db96d56Sopenharmony_ci self.assertEqual(complex.real.__qualname__, 'complex.real') 48437db96d56Sopenharmony_ci self.assertEqual(float.real.__qualname__, 'float.real') 48447db96d56Sopenharmony_ci self.assertEqual(int.__add__.__qualname__, 'int.__add__') 48457db96d56Sopenharmony_ci 48467db96d56Sopenharmony_ci class X: 48477db96d56Sopenharmony_ci pass 48487db96d56Sopenharmony_ci with self.assertRaises(TypeError): 48497db96d56Sopenharmony_ci del X.__qualname__ 48507db96d56Sopenharmony_ci 48517db96d56Sopenharmony_ci self.assertRaises(TypeError, type.__dict__['__qualname__'].__set__, 48527db96d56Sopenharmony_ci str, 'Oink') 48537db96d56Sopenharmony_ci 48547db96d56Sopenharmony_ci global Y 48557db96d56Sopenharmony_ci class Y: 48567db96d56Sopenharmony_ci class Inside: 48577db96d56Sopenharmony_ci pass 48587db96d56Sopenharmony_ci self.assertEqual(Y.__qualname__, 'Y') 48597db96d56Sopenharmony_ci self.assertEqual(Y.Inside.__qualname__, 'Y.Inside') 48607db96d56Sopenharmony_ci 48617db96d56Sopenharmony_ci def test_qualname_dict(self): 48627db96d56Sopenharmony_ci ns = {'__qualname__': 'some.name'} 48637db96d56Sopenharmony_ci tp = type('Foo', (), ns) 48647db96d56Sopenharmony_ci self.assertEqual(tp.__qualname__, 'some.name') 48657db96d56Sopenharmony_ci self.assertNotIn('__qualname__', tp.__dict__) 48667db96d56Sopenharmony_ci self.assertEqual(ns, {'__qualname__': 'some.name'}) 48677db96d56Sopenharmony_ci 48687db96d56Sopenharmony_ci ns = {'__qualname__': 1} 48697db96d56Sopenharmony_ci self.assertRaises(TypeError, type, 'Foo', (), ns) 48707db96d56Sopenharmony_ci 48717db96d56Sopenharmony_ci def test_cycle_through_dict(self): 48727db96d56Sopenharmony_ci # See bug #1469629 48737db96d56Sopenharmony_ci class X(dict): 48747db96d56Sopenharmony_ci def __init__(self): 48757db96d56Sopenharmony_ci dict.__init__(self) 48767db96d56Sopenharmony_ci self.__dict__ = self 48777db96d56Sopenharmony_ci x = X() 48787db96d56Sopenharmony_ci x.attr = 42 48797db96d56Sopenharmony_ci wr = weakref.ref(x) 48807db96d56Sopenharmony_ci del x 48817db96d56Sopenharmony_ci support.gc_collect() 48827db96d56Sopenharmony_ci self.assertIsNone(wr()) 48837db96d56Sopenharmony_ci for o in gc.get_objects(): 48847db96d56Sopenharmony_ci self.assertIsNot(type(o), X) 48857db96d56Sopenharmony_ci 48867db96d56Sopenharmony_ci def test_object_new_and_init_with_parameters(self): 48877db96d56Sopenharmony_ci # See issue #1683368 48887db96d56Sopenharmony_ci class OverrideNeither: 48897db96d56Sopenharmony_ci pass 48907db96d56Sopenharmony_ci self.assertRaises(TypeError, OverrideNeither, 1) 48917db96d56Sopenharmony_ci self.assertRaises(TypeError, OverrideNeither, kw=1) 48927db96d56Sopenharmony_ci class OverrideNew: 48937db96d56Sopenharmony_ci def __new__(cls, foo, kw=0, *args, **kwds): 48947db96d56Sopenharmony_ci return object.__new__(cls, *args, **kwds) 48957db96d56Sopenharmony_ci class OverrideInit: 48967db96d56Sopenharmony_ci def __init__(self, foo, kw=0, *args, **kwargs): 48977db96d56Sopenharmony_ci return object.__init__(self, *args, **kwargs) 48987db96d56Sopenharmony_ci class OverrideBoth(OverrideNew, OverrideInit): 48997db96d56Sopenharmony_ci pass 49007db96d56Sopenharmony_ci for case in OverrideNew, OverrideInit, OverrideBoth: 49017db96d56Sopenharmony_ci case(1) 49027db96d56Sopenharmony_ci case(1, kw=2) 49037db96d56Sopenharmony_ci self.assertRaises(TypeError, case, 1, 2, 3) 49047db96d56Sopenharmony_ci self.assertRaises(TypeError, case, 1, 2, foo=3) 49057db96d56Sopenharmony_ci 49067db96d56Sopenharmony_ci def test_subclassing_does_not_duplicate_dict_descriptors(self): 49077db96d56Sopenharmony_ci class Base: 49087db96d56Sopenharmony_ci pass 49097db96d56Sopenharmony_ci class Sub(Base): 49107db96d56Sopenharmony_ci pass 49117db96d56Sopenharmony_ci self.assertIn("__dict__", Base.__dict__) 49127db96d56Sopenharmony_ci self.assertNotIn("__dict__", Sub.__dict__) 49137db96d56Sopenharmony_ci 49147db96d56Sopenharmony_ci def test_bound_method_repr(self): 49157db96d56Sopenharmony_ci class Foo: 49167db96d56Sopenharmony_ci def method(self): 49177db96d56Sopenharmony_ci pass 49187db96d56Sopenharmony_ci self.assertRegex(repr(Foo().method), 49197db96d56Sopenharmony_ci r"<bound method .*Foo\.method of <.*Foo object at .*>>") 49207db96d56Sopenharmony_ci 49217db96d56Sopenharmony_ci 49227db96d56Sopenharmony_ci class Base: 49237db96d56Sopenharmony_ci def method(self): 49247db96d56Sopenharmony_ci pass 49257db96d56Sopenharmony_ci class Derived1(Base): 49267db96d56Sopenharmony_ci pass 49277db96d56Sopenharmony_ci class Derived2(Base): 49287db96d56Sopenharmony_ci def method(self): 49297db96d56Sopenharmony_ci pass 49307db96d56Sopenharmony_ci base = Base() 49317db96d56Sopenharmony_ci derived1 = Derived1() 49327db96d56Sopenharmony_ci derived2 = Derived2() 49337db96d56Sopenharmony_ci super_d2 = super(Derived2, derived2) 49347db96d56Sopenharmony_ci self.assertRegex(repr(base.method), 49357db96d56Sopenharmony_ci r"<bound method .*Base\.method of <.*Base object at .*>>") 49367db96d56Sopenharmony_ci self.assertRegex(repr(derived1.method), 49377db96d56Sopenharmony_ci r"<bound method .*Base\.method of <.*Derived1 object at .*>>") 49387db96d56Sopenharmony_ci self.assertRegex(repr(derived2.method), 49397db96d56Sopenharmony_ci r"<bound method .*Derived2\.method of <.*Derived2 object at .*>>") 49407db96d56Sopenharmony_ci self.assertRegex(repr(super_d2.method), 49417db96d56Sopenharmony_ci r"<bound method .*Base\.method of <.*Derived2 object at .*>>") 49427db96d56Sopenharmony_ci 49437db96d56Sopenharmony_ci class Foo: 49447db96d56Sopenharmony_ci @classmethod 49457db96d56Sopenharmony_ci def method(cls): 49467db96d56Sopenharmony_ci pass 49477db96d56Sopenharmony_ci foo = Foo() 49487db96d56Sopenharmony_ci self.assertRegex(repr(foo.method), # access via instance 49497db96d56Sopenharmony_ci r"<bound method .*Foo\.method of <class '.*Foo'>>") 49507db96d56Sopenharmony_ci self.assertRegex(repr(Foo.method), # access via the class 49517db96d56Sopenharmony_ci r"<bound method .*Foo\.method of <class '.*Foo'>>") 49527db96d56Sopenharmony_ci 49537db96d56Sopenharmony_ci 49547db96d56Sopenharmony_ci class MyCallable: 49557db96d56Sopenharmony_ci def __call__(self, arg): 49567db96d56Sopenharmony_ci pass 49577db96d56Sopenharmony_ci func = MyCallable() # func has no __name__ or __qualname__ attributes 49587db96d56Sopenharmony_ci instance = object() 49597db96d56Sopenharmony_ci method = types.MethodType(func, instance) 49607db96d56Sopenharmony_ci self.assertRegex(repr(method), 49617db96d56Sopenharmony_ci r"<bound method \? of <object object at .*>>") 49627db96d56Sopenharmony_ci func.__name__ = "name" 49637db96d56Sopenharmony_ci self.assertRegex(repr(method), 49647db96d56Sopenharmony_ci r"<bound method name of <object object at .*>>") 49657db96d56Sopenharmony_ci func.__qualname__ = "qualname" 49667db96d56Sopenharmony_ci self.assertRegex(repr(method), 49677db96d56Sopenharmony_ci r"<bound method qualname of <object object at .*>>") 49687db96d56Sopenharmony_ci 49697db96d56Sopenharmony_ci @unittest.skipIf(_testcapi is None, 'need the _testcapi module') 49707db96d56Sopenharmony_ci def test_bpo25750(self): 49717db96d56Sopenharmony_ci # bpo-25750: calling a descriptor (implemented as built-in 49727db96d56Sopenharmony_ci # function with METH_FASTCALL) should not crash CPython if the 49737db96d56Sopenharmony_ci # descriptor deletes itself from the class. 49747db96d56Sopenharmony_ci class Descr: 49757db96d56Sopenharmony_ci __get__ = _testcapi.bad_get 49767db96d56Sopenharmony_ci 49777db96d56Sopenharmony_ci class X: 49787db96d56Sopenharmony_ci descr = Descr() 49797db96d56Sopenharmony_ci def __new__(cls): 49807db96d56Sopenharmony_ci cls.descr = None 49817db96d56Sopenharmony_ci # Create this large list to corrupt some unused memory 49827db96d56Sopenharmony_ci cls.lst = [2**i for i in range(10000)] 49837db96d56Sopenharmony_ci X.descr 49847db96d56Sopenharmony_ci 49857db96d56Sopenharmony_ci def test_remove_subclass(self): 49867db96d56Sopenharmony_ci # bpo-46417: when the last subclass of a type is deleted, 49877db96d56Sopenharmony_ci # remove_subclass() clears the internal dictionary of subclasses: 49887db96d56Sopenharmony_ci # set PyTypeObject.tp_subclasses to NULL. remove_subclass() is called 49897db96d56Sopenharmony_ci # when a type is deallocated. 49907db96d56Sopenharmony_ci class Parent: 49917db96d56Sopenharmony_ci pass 49927db96d56Sopenharmony_ci self.assertEqual(Parent.__subclasses__(), []) 49937db96d56Sopenharmony_ci 49947db96d56Sopenharmony_ci class Child(Parent): 49957db96d56Sopenharmony_ci pass 49967db96d56Sopenharmony_ci self.assertEqual(Parent.__subclasses__(), [Child]) 49977db96d56Sopenharmony_ci 49987db96d56Sopenharmony_ci del Child 49997db96d56Sopenharmony_ci gc.collect() 50007db96d56Sopenharmony_ci self.assertEqual(Parent.__subclasses__(), []) 50017db96d56Sopenharmony_ci 50027db96d56Sopenharmony_ci def test_attr_raise_through_property(self): 50037db96d56Sopenharmony_ci # add test case for gh-103272 50047db96d56Sopenharmony_ci class A: 50057db96d56Sopenharmony_ci def __getattr__(self, name): 50067db96d56Sopenharmony_ci raise ValueError("FOO") 50077db96d56Sopenharmony_ci 50087db96d56Sopenharmony_ci @property 50097db96d56Sopenharmony_ci def foo(self): 50107db96d56Sopenharmony_ci return self.__getattr__("asdf") 50117db96d56Sopenharmony_ci 50127db96d56Sopenharmony_ci with self.assertRaisesRegex(ValueError, "FOO"): 50137db96d56Sopenharmony_ci A().foo 50147db96d56Sopenharmony_ci 50157db96d56Sopenharmony_ci 50167db96d56Sopenharmony_ciclass DictProxyTests(unittest.TestCase): 50177db96d56Sopenharmony_ci def setUp(self): 50187db96d56Sopenharmony_ci class C(object): 50197db96d56Sopenharmony_ci def meth(self): 50207db96d56Sopenharmony_ci pass 50217db96d56Sopenharmony_ci self.C = C 50227db96d56Sopenharmony_ci 50237db96d56Sopenharmony_ci @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 50247db96d56Sopenharmony_ci 'trace function introduces __local__') 50257db96d56Sopenharmony_ci def test_iter_keys(self): 50267db96d56Sopenharmony_ci # Testing dict-proxy keys... 50277db96d56Sopenharmony_ci it = self.C.__dict__.keys() 50287db96d56Sopenharmony_ci self.assertNotIsInstance(it, list) 50297db96d56Sopenharmony_ci keys = list(it) 50307db96d56Sopenharmony_ci keys.sort() 50317db96d56Sopenharmony_ci self.assertEqual(keys, ['__dict__', '__doc__', '__module__', 50327db96d56Sopenharmony_ci '__weakref__', 'meth']) 50337db96d56Sopenharmony_ci 50347db96d56Sopenharmony_ci @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 50357db96d56Sopenharmony_ci 'trace function introduces __local__') 50367db96d56Sopenharmony_ci def test_iter_values(self): 50377db96d56Sopenharmony_ci # Testing dict-proxy values... 50387db96d56Sopenharmony_ci it = self.C.__dict__.values() 50397db96d56Sopenharmony_ci self.assertNotIsInstance(it, list) 50407db96d56Sopenharmony_ci values = list(it) 50417db96d56Sopenharmony_ci self.assertEqual(len(values), 5) 50427db96d56Sopenharmony_ci 50437db96d56Sopenharmony_ci @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 50447db96d56Sopenharmony_ci 'trace function introduces __local__') 50457db96d56Sopenharmony_ci def test_iter_items(self): 50467db96d56Sopenharmony_ci # Testing dict-proxy iteritems... 50477db96d56Sopenharmony_ci it = self.C.__dict__.items() 50487db96d56Sopenharmony_ci self.assertNotIsInstance(it, list) 50497db96d56Sopenharmony_ci keys = [item[0] for item in it] 50507db96d56Sopenharmony_ci keys.sort() 50517db96d56Sopenharmony_ci self.assertEqual(keys, ['__dict__', '__doc__', '__module__', 50527db96d56Sopenharmony_ci '__weakref__', 'meth']) 50537db96d56Sopenharmony_ci 50547db96d56Sopenharmony_ci def test_dict_type_with_metaclass(self): 50557db96d56Sopenharmony_ci # Testing type of __dict__ when metaclass set... 50567db96d56Sopenharmony_ci class B(object): 50577db96d56Sopenharmony_ci pass 50587db96d56Sopenharmony_ci class M(type): 50597db96d56Sopenharmony_ci pass 50607db96d56Sopenharmony_ci class C(metaclass=M): 50617db96d56Sopenharmony_ci # In 2.3a1, C.__dict__ was a real dict rather than a dict proxy 50627db96d56Sopenharmony_ci pass 50637db96d56Sopenharmony_ci self.assertEqual(type(C.__dict__), type(B.__dict__)) 50647db96d56Sopenharmony_ci 50657db96d56Sopenharmony_ci def test_repr(self): 50667db96d56Sopenharmony_ci # Testing mappingproxy.__repr__. 50677db96d56Sopenharmony_ci # We can't blindly compare with the repr of another dict as ordering 50687db96d56Sopenharmony_ci # of keys and values is arbitrary and may differ. 50697db96d56Sopenharmony_ci r = repr(self.C.__dict__) 50707db96d56Sopenharmony_ci self.assertTrue(r.startswith('mappingproxy('), r) 50717db96d56Sopenharmony_ci self.assertTrue(r.endswith(')'), r) 50727db96d56Sopenharmony_ci for k, v in self.C.__dict__.items(): 50737db96d56Sopenharmony_ci self.assertIn('{!r}: {!r}'.format(k, v), r) 50747db96d56Sopenharmony_ci 50757db96d56Sopenharmony_ci 50767db96d56Sopenharmony_ciclass AAAPTypesLongInitTest(unittest.TestCase): 50777db96d56Sopenharmony_ci # This is in its own TestCase so that it can be run before any other tests. 50787db96d56Sopenharmony_ci # (Hence the 'AAA' in the test class name: to make it the first 50797db96d56Sopenharmony_ci # item in a list sorted by name, like 50807db96d56Sopenharmony_ci # unittest.TestLoader.getTestCaseNames() does.) 50817db96d56Sopenharmony_ci def test_pytype_long_ready(self): 50827db96d56Sopenharmony_ci # Testing SF bug 551412 ... 50837db96d56Sopenharmony_ci 50847db96d56Sopenharmony_ci # This dumps core when SF bug 551412 isn't fixed -- 50857db96d56Sopenharmony_ci # but only when test_descr.py is run separately. 50867db96d56Sopenharmony_ci # (That can't be helped -- as soon as PyType_Ready() 50877db96d56Sopenharmony_ci # is called for PyLong_Type, the bug is gone.) 50887db96d56Sopenharmony_ci class UserLong(object): 50897db96d56Sopenharmony_ci def __pow__(self, *args): 50907db96d56Sopenharmony_ci pass 50917db96d56Sopenharmony_ci try: 50927db96d56Sopenharmony_ci pow(0, UserLong(), 0) 50937db96d56Sopenharmony_ci except: 50947db96d56Sopenharmony_ci pass 50957db96d56Sopenharmony_ci 50967db96d56Sopenharmony_ci # Another segfault only when run early 50977db96d56Sopenharmony_ci # (before PyType_Ready(tuple) is called) 50987db96d56Sopenharmony_ci type.mro(tuple) 50997db96d56Sopenharmony_ci 51007db96d56Sopenharmony_ci 51017db96d56Sopenharmony_ciclass MiscTests(unittest.TestCase): 51027db96d56Sopenharmony_ci def test_type_lookup_mro_reference(self): 51037db96d56Sopenharmony_ci # Issue #14199: _PyType_Lookup() has to keep a strong reference to 51047db96d56Sopenharmony_ci # the type MRO because it may be modified during the lookup, if 51057db96d56Sopenharmony_ci # __bases__ is set during the lookup for example. 51067db96d56Sopenharmony_ci class MyKey(object): 51077db96d56Sopenharmony_ci def __hash__(self): 51087db96d56Sopenharmony_ci return hash('mykey') 51097db96d56Sopenharmony_ci 51107db96d56Sopenharmony_ci def __eq__(self, other): 51117db96d56Sopenharmony_ci X.__bases__ = (Base2,) 51127db96d56Sopenharmony_ci 51137db96d56Sopenharmony_ci class Base(object): 51147db96d56Sopenharmony_ci mykey = 'from Base' 51157db96d56Sopenharmony_ci mykey2 = 'from Base' 51167db96d56Sopenharmony_ci 51177db96d56Sopenharmony_ci class Base2(object): 51187db96d56Sopenharmony_ci mykey = 'from Base2' 51197db96d56Sopenharmony_ci mykey2 = 'from Base2' 51207db96d56Sopenharmony_ci 51217db96d56Sopenharmony_ci X = type('X', (Base,), {MyKey(): 5}) 51227db96d56Sopenharmony_ci # mykey is read from Base 51237db96d56Sopenharmony_ci self.assertEqual(X.mykey, 'from Base') 51247db96d56Sopenharmony_ci # mykey2 is read from Base2 because MyKey.__eq__ has set __bases__ 51257db96d56Sopenharmony_ci self.assertEqual(X.mykey2, 'from Base2') 51267db96d56Sopenharmony_ci 51277db96d56Sopenharmony_ci 51287db96d56Sopenharmony_ciclass PicklingTests(unittest.TestCase): 51297db96d56Sopenharmony_ci 51307db96d56Sopenharmony_ci def _check_reduce(self, proto, obj, args=(), kwargs={}, state=None, 51317db96d56Sopenharmony_ci listitems=None, dictitems=None): 51327db96d56Sopenharmony_ci if proto >= 2: 51337db96d56Sopenharmony_ci reduce_value = obj.__reduce_ex__(proto) 51347db96d56Sopenharmony_ci if kwargs: 51357db96d56Sopenharmony_ci self.assertEqual(reduce_value[0], copyreg.__newobj_ex__) 51367db96d56Sopenharmony_ci self.assertEqual(reduce_value[1], (type(obj), args, kwargs)) 51377db96d56Sopenharmony_ci else: 51387db96d56Sopenharmony_ci self.assertEqual(reduce_value[0], copyreg.__newobj__) 51397db96d56Sopenharmony_ci self.assertEqual(reduce_value[1], (type(obj),) + args) 51407db96d56Sopenharmony_ci self.assertEqual(reduce_value[2], state) 51417db96d56Sopenharmony_ci if listitems is not None: 51427db96d56Sopenharmony_ci self.assertListEqual(list(reduce_value[3]), listitems) 51437db96d56Sopenharmony_ci else: 51447db96d56Sopenharmony_ci self.assertIsNone(reduce_value[3]) 51457db96d56Sopenharmony_ci if dictitems is not None: 51467db96d56Sopenharmony_ci self.assertDictEqual(dict(reduce_value[4]), dictitems) 51477db96d56Sopenharmony_ci else: 51487db96d56Sopenharmony_ci self.assertIsNone(reduce_value[4]) 51497db96d56Sopenharmony_ci else: 51507db96d56Sopenharmony_ci base_type = type(obj).__base__ 51517db96d56Sopenharmony_ci reduce_value = (copyreg._reconstructor, 51527db96d56Sopenharmony_ci (type(obj), 51537db96d56Sopenharmony_ci base_type, 51547db96d56Sopenharmony_ci None if base_type is object else base_type(obj))) 51557db96d56Sopenharmony_ci if state is not None: 51567db96d56Sopenharmony_ci reduce_value += (state,) 51577db96d56Sopenharmony_ci self.assertEqual(obj.__reduce_ex__(proto), reduce_value) 51587db96d56Sopenharmony_ci self.assertEqual(obj.__reduce__(), reduce_value) 51597db96d56Sopenharmony_ci 51607db96d56Sopenharmony_ci def test_reduce(self): 51617db96d56Sopenharmony_ci protocols = range(pickle.HIGHEST_PROTOCOL + 1) 51627db96d56Sopenharmony_ci args = (-101, "spam") 51637db96d56Sopenharmony_ci kwargs = {'bacon': -201, 'fish': -301} 51647db96d56Sopenharmony_ci state = {'cheese': -401} 51657db96d56Sopenharmony_ci 51667db96d56Sopenharmony_ci class C1: 51677db96d56Sopenharmony_ci def __getnewargs__(self): 51687db96d56Sopenharmony_ci return args 51697db96d56Sopenharmony_ci obj = C1() 51707db96d56Sopenharmony_ci for proto in protocols: 51717db96d56Sopenharmony_ci self._check_reduce(proto, obj, args) 51727db96d56Sopenharmony_ci 51737db96d56Sopenharmony_ci for name, value in state.items(): 51747db96d56Sopenharmony_ci setattr(obj, name, value) 51757db96d56Sopenharmony_ci for proto in protocols: 51767db96d56Sopenharmony_ci self._check_reduce(proto, obj, args, state=state) 51777db96d56Sopenharmony_ci 51787db96d56Sopenharmony_ci class C2: 51797db96d56Sopenharmony_ci def __getnewargs__(self): 51807db96d56Sopenharmony_ci return "bad args" 51817db96d56Sopenharmony_ci obj = C2() 51827db96d56Sopenharmony_ci for proto in protocols: 51837db96d56Sopenharmony_ci if proto >= 2: 51847db96d56Sopenharmony_ci with self.assertRaises(TypeError): 51857db96d56Sopenharmony_ci obj.__reduce_ex__(proto) 51867db96d56Sopenharmony_ci 51877db96d56Sopenharmony_ci class C3: 51887db96d56Sopenharmony_ci def __getnewargs_ex__(self): 51897db96d56Sopenharmony_ci return (args, kwargs) 51907db96d56Sopenharmony_ci obj = C3() 51917db96d56Sopenharmony_ci for proto in protocols: 51927db96d56Sopenharmony_ci if proto >= 2: 51937db96d56Sopenharmony_ci self._check_reduce(proto, obj, args, kwargs) 51947db96d56Sopenharmony_ci 51957db96d56Sopenharmony_ci class C4: 51967db96d56Sopenharmony_ci def __getnewargs_ex__(self): 51977db96d56Sopenharmony_ci return (args, "bad dict") 51987db96d56Sopenharmony_ci class C5: 51997db96d56Sopenharmony_ci def __getnewargs_ex__(self): 52007db96d56Sopenharmony_ci return ("bad tuple", kwargs) 52017db96d56Sopenharmony_ci class C6: 52027db96d56Sopenharmony_ci def __getnewargs_ex__(self): 52037db96d56Sopenharmony_ci return () 52047db96d56Sopenharmony_ci class C7: 52057db96d56Sopenharmony_ci def __getnewargs_ex__(self): 52067db96d56Sopenharmony_ci return "bad args" 52077db96d56Sopenharmony_ci for proto in protocols: 52087db96d56Sopenharmony_ci for cls in C4, C5, C6, C7: 52097db96d56Sopenharmony_ci obj = cls() 52107db96d56Sopenharmony_ci if proto >= 2: 52117db96d56Sopenharmony_ci with self.assertRaises((TypeError, ValueError)): 52127db96d56Sopenharmony_ci obj.__reduce_ex__(proto) 52137db96d56Sopenharmony_ci 52147db96d56Sopenharmony_ci class C9: 52157db96d56Sopenharmony_ci def __getnewargs_ex__(self): 52167db96d56Sopenharmony_ci return (args, {}) 52177db96d56Sopenharmony_ci obj = C9() 52187db96d56Sopenharmony_ci for proto in protocols: 52197db96d56Sopenharmony_ci self._check_reduce(proto, obj, args) 52207db96d56Sopenharmony_ci 52217db96d56Sopenharmony_ci class C10: 52227db96d56Sopenharmony_ci def __getnewargs_ex__(self): 52237db96d56Sopenharmony_ci raise IndexError 52247db96d56Sopenharmony_ci obj = C10() 52257db96d56Sopenharmony_ci for proto in protocols: 52267db96d56Sopenharmony_ci if proto >= 2: 52277db96d56Sopenharmony_ci with self.assertRaises(IndexError): 52287db96d56Sopenharmony_ci obj.__reduce_ex__(proto) 52297db96d56Sopenharmony_ci 52307db96d56Sopenharmony_ci class C11: 52317db96d56Sopenharmony_ci def __getstate__(self): 52327db96d56Sopenharmony_ci return state 52337db96d56Sopenharmony_ci obj = C11() 52347db96d56Sopenharmony_ci for proto in protocols: 52357db96d56Sopenharmony_ci self._check_reduce(proto, obj, state=state) 52367db96d56Sopenharmony_ci 52377db96d56Sopenharmony_ci class C12: 52387db96d56Sopenharmony_ci def __getstate__(self): 52397db96d56Sopenharmony_ci return "not dict" 52407db96d56Sopenharmony_ci obj = C12() 52417db96d56Sopenharmony_ci for proto in protocols: 52427db96d56Sopenharmony_ci self._check_reduce(proto, obj, state="not dict") 52437db96d56Sopenharmony_ci 52447db96d56Sopenharmony_ci class C13: 52457db96d56Sopenharmony_ci def __getstate__(self): 52467db96d56Sopenharmony_ci raise IndexError 52477db96d56Sopenharmony_ci obj = C13() 52487db96d56Sopenharmony_ci for proto in protocols: 52497db96d56Sopenharmony_ci with self.assertRaises(IndexError): 52507db96d56Sopenharmony_ci obj.__reduce_ex__(proto) 52517db96d56Sopenharmony_ci if proto < 2: 52527db96d56Sopenharmony_ci with self.assertRaises(IndexError): 52537db96d56Sopenharmony_ci obj.__reduce__() 52547db96d56Sopenharmony_ci 52557db96d56Sopenharmony_ci class C14: 52567db96d56Sopenharmony_ci __slots__ = tuple(state) 52577db96d56Sopenharmony_ci def __init__(self): 52587db96d56Sopenharmony_ci for name, value in state.items(): 52597db96d56Sopenharmony_ci setattr(self, name, value) 52607db96d56Sopenharmony_ci 52617db96d56Sopenharmony_ci obj = C14() 52627db96d56Sopenharmony_ci for proto in protocols: 52637db96d56Sopenharmony_ci if proto >= 2: 52647db96d56Sopenharmony_ci self._check_reduce(proto, obj, state=(None, state)) 52657db96d56Sopenharmony_ci else: 52667db96d56Sopenharmony_ci with self.assertRaises(TypeError): 52677db96d56Sopenharmony_ci obj.__reduce_ex__(proto) 52687db96d56Sopenharmony_ci with self.assertRaises(TypeError): 52697db96d56Sopenharmony_ci obj.__reduce__() 52707db96d56Sopenharmony_ci 52717db96d56Sopenharmony_ci class C15(dict): 52727db96d56Sopenharmony_ci pass 52737db96d56Sopenharmony_ci obj = C15({"quebec": -601}) 52747db96d56Sopenharmony_ci for proto in protocols: 52757db96d56Sopenharmony_ci self._check_reduce(proto, obj, dictitems=dict(obj)) 52767db96d56Sopenharmony_ci 52777db96d56Sopenharmony_ci class C16(list): 52787db96d56Sopenharmony_ci pass 52797db96d56Sopenharmony_ci obj = C16(["yukon"]) 52807db96d56Sopenharmony_ci for proto in protocols: 52817db96d56Sopenharmony_ci self._check_reduce(proto, obj, listitems=list(obj)) 52827db96d56Sopenharmony_ci 52837db96d56Sopenharmony_ci def test_special_method_lookup(self): 52847db96d56Sopenharmony_ci protocols = range(pickle.HIGHEST_PROTOCOL + 1) 52857db96d56Sopenharmony_ci class Picky: 52867db96d56Sopenharmony_ci def __getstate__(self): 52877db96d56Sopenharmony_ci return {} 52887db96d56Sopenharmony_ci 52897db96d56Sopenharmony_ci def __getattr__(self, attr): 52907db96d56Sopenharmony_ci if attr in ("__getnewargs__", "__getnewargs_ex__"): 52917db96d56Sopenharmony_ci raise AssertionError(attr) 52927db96d56Sopenharmony_ci return None 52937db96d56Sopenharmony_ci for protocol in protocols: 52947db96d56Sopenharmony_ci state = {} if protocol >= 2 else None 52957db96d56Sopenharmony_ci self._check_reduce(protocol, Picky(), state=state) 52967db96d56Sopenharmony_ci 52977db96d56Sopenharmony_ci def _assert_is_copy(self, obj, objcopy, msg=None): 52987db96d56Sopenharmony_ci """Utility method to verify if two objects are copies of each others. 52997db96d56Sopenharmony_ci """ 53007db96d56Sopenharmony_ci if msg is None: 53017db96d56Sopenharmony_ci msg = "{!r} is not a copy of {!r}".format(obj, objcopy) 53027db96d56Sopenharmony_ci if type(obj).__repr__ is object.__repr__: 53037db96d56Sopenharmony_ci # We have this limitation for now because we use the object's repr 53047db96d56Sopenharmony_ci # to help us verify that the two objects are copies. This allows 53057db96d56Sopenharmony_ci # us to delegate the non-generic verification logic to the objects 53067db96d56Sopenharmony_ci # themselves. 53077db96d56Sopenharmony_ci raise ValueError("object passed to _assert_is_copy must " + 53087db96d56Sopenharmony_ci "override the __repr__ method.") 53097db96d56Sopenharmony_ci self.assertIsNot(obj, objcopy, msg=msg) 53107db96d56Sopenharmony_ci self.assertIs(type(obj), type(objcopy), msg=msg) 53117db96d56Sopenharmony_ci if hasattr(obj, '__dict__'): 53127db96d56Sopenharmony_ci self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg) 53137db96d56Sopenharmony_ci self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg) 53147db96d56Sopenharmony_ci if hasattr(obj, '__slots__'): 53157db96d56Sopenharmony_ci self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg) 53167db96d56Sopenharmony_ci for slot in obj.__slots__: 53177db96d56Sopenharmony_ci self.assertEqual( 53187db96d56Sopenharmony_ci hasattr(obj, slot), hasattr(objcopy, slot), msg=msg) 53197db96d56Sopenharmony_ci self.assertEqual(getattr(obj, slot, None), 53207db96d56Sopenharmony_ci getattr(objcopy, slot, None), msg=msg) 53217db96d56Sopenharmony_ci self.assertEqual(repr(obj), repr(objcopy), msg=msg) 53227db96d56Sopenharmony_ci 53237db96d56Sopenharmony_ci @staticmethod 53247db96d56Sopenharmony_ci def _generate_pickle_copiers(): 53257db96d56Sopenharmony_ci """Utility method to generate the many possible pickle configurations. 53267db96d56Sopenharmony_ci """ 53277db96d56Sopenharmony_ci class PickleCopier: 53287db96d56Sopenharmony_ci "This class copies object using pickle." 53297db96d56Sopenharmony_ci def __init__(self, proto, dumps, loads): 53307db96d56Sopenharmony_ci self.proto = proto 53317db96d56Sopenharmony_ci self.dumps = dumps 53327db96d56Sopenharmony_ci self.loads = loads 53337db96d56Sopenharmony_ci def copy(self, obj): 53347db96d56Sopenharmony_ci return self.loads(self.dumps(obj, self.proto)) 53357db96d56Sopenharmony_ci def __repr__(self): 53367db96d56Sopenharmony_ci # We try to be as descriptive as possible here since this is 53377db96d56Sopenharmony_ci # the string which we will allow us to tell the pickle 53387db96d56Sopenharmony_ci # configuration we are using during debugging. 53397db96d56Sopenharmony_ci return ("PickleCopier(proto={}, dumps={}.{}, loads={}.{})" 53407db96d56Sopenharmony_ci .format(self.proto, 53417db96d56Sopenharmony_ci self.dumps.__module__, self.dumps.__qualname__, 53427db96d56Sopenharmony_ci self.loads.__module__, self.loads.__qualname__)) 53437db96d56Sopenharmony_ci return (PickleCopier(*args) for args in 53447db96d56Sopenharmony_ci itertools.product(range(pickle.HIGHEST_PROTOCOL + 1), 53457db96d56Sopenharmony_ci {pickle.dumps, pickle._dumps}, 53467db96d56Sopenharmony_ci {pickle.loads, pickle._loads})) 53477db96d56Sopenharmony_ci 53487db96d56Sopenharmony_ci def test_pickle_slots(self): 53497db96d56Sopenharmony_ci # Tests pickling of classes with __slots__. 53507db96d56Sopenharmony_ci 53517db96d56Sopenharmony_ci # Pickling of classes with __slots__ but without __getstate__ should 53527db96d56Sopenharmony_ci # fail (if using protocol 0 or 1) 53537db96d56Sopenharmony_ci global C 53547db96d56Sopenharmony_ci class C: 53557db96d56Sopenharmony_ci __slots__ = ['a'] 53567db96d56Sopenharmony_ci with self.assertRaises(TypeError): 53577db96d56Sopenharmony_ci pickle.dumps(C(), 0) 53587db96d56Sopenharmony_ci 53597db96d56Sopenharmony_ci global D 53607db96d56Sopenharmony_ci class D(C): 53617db96d56Sopenharmony_ci pass 53627db96d56Sopenharmony_ci with self.assertRaises(TypeError): 53637db96d56Sopenharmony_ci pickle.dumps(D(), 0) 53647db96d56Sopenharmony_ci 53657db96d56Sopenharmony_ci class C: 53667db96d56Sopenharmony_ci "A class with __getstate__ and __setstate__ implemented." 53677db96d56Sopenharmony_ci __slots__ = ['a'] 53687db96d56Sopenharmony_ci def __getstate__(self): 53697db96d56Sopenharmony_ci state = getattr(self, '__dict__', {}).copy() 53707db96d56Sopenharmony_ci for cls in type(self).__mro__: 53717db96d56Sopenharmony_ci for slot in cls.__dict__.get('__slots__', ()): 53727db96d56Sopenharmony_ci try: 53737db96d56Sopenharmony_ci state[slot] = getattr(self, slot) 53747db96d56Sopenharmony_ci except AttributeError: 53757db96d56Sopenharmony_ci pass 53767db96d56Sopenharmony_ci return state 53777db96d56Sopenharmony_ci def __setstate__(self, state): 53787db96d56Sopenharmony_ci for k, v in state.items(): 53797db96d56Sopenharmony_ci setattr(self, k, v) 53807db96d56Sopenharmony_ci def __repr__(self): 53817db96d56Sopenharmony_ci return "%s()<%r>" % (type(self).__name__, self.__getstate__()) 53827db96d56Sopenharmony_ci 53837db96d56Sopenharmony_ci class D(C): 53847db96d56Sopenharmony_ci "A subclass of a class with slots." 53857db96d56Sopenharmony_ci pass 53867db96d56Sopenharmony_ci 53877db96d56Sopenharmony_ci global E 53887db96d56Sopenharmony_ci class E(C): 53897db96d56Sopenharmony_ci "A subclass with an extra slot." 53907db96d56Sopenharmony_ci __slots__ = ['b'] 53917db96d56Sopenharmony_ci 53927db96d56Sopenharmony_ci # Now it should work 53937db96d56Sopenharmony_ci for pickle_copier in self._generate_pickle_copiers(): 53947db96d56Sopenharmony_ci with self.subTest(pickle_copier=pickle_copier): 53957db96d56Sopenharmony_ci x = C() 53967db96d56Sopenharmony_ci y = pickle_copier.copy(x) 53977db96d56Sopenharmony_ci self._assert_is_copy(x, y) 53987db96d56Sopenharmony_ci 53997db96d56Sopenharmony_ci x.a = 42 54007db96d56Sopenharmony_ci y = pickle_copier.copy(x) 54017db96d56Sopenharmony_ci self._assert_is_copy(x, y) 54027db96d56Sopenharmony_ci 54037db96d56Sopenharmony_ci x = D() 54047db96d56Sopenharmony_ci x.a = 42 54057db96d56Sopenharmony_ci x.b = 100 54067db96d56Sopenharmony_ci y = pickle_copier.copy(x) 54077db96d56Sopenharmony_ci self._assert_is_copy(x, y) 54087db96d56Sopenharmony_ci 54097db96d56Sopenharmony_ci x = E() 54107db96d56Sopenharmony_ci x.a = 42 54117db96d56Sopenharmony_ci x.b = "foo" 54127db96d56Sopenharmony_ci y = pickle_copier.copy(x) 54137db96d56Sopenharmony_ci self._assert_is_copy(x, y) 54147db96d56Sopenharmony_ci 54157db96d56Sopenharmony_ci def test_reduce_copying(self): 54167db96d56Sopenharmony_ci # Tests pickling and copying new-style classes and objects. 54177db96d56Sopenharmony_ci global C1 54187db96d56Sopenharmony_ci class C1: 54197db96d56Sopenharmony_ci "The state of this class is copyable via its instance dict." 54207db96d56Sopenharmony_ci ARGS = (1, 2) 54217db96d56Sopenharmony_ci NEED_DICT_COPYING = True 54227db96d56Sopenharmony_ci def __init__(self, a, b): 54237db96d56Sopenharmony_ci super().__init__() 54247db96d56Sopenharmony_ci self.a = a 54257db96d56Sopenharmony_ci self.b = b 54267db96d56Sopenharmony_ci def __repr__(self): 54277db96d56Sopenharmony_ci return "C1(%r, %r)" % (self.a, self.b) 54287db96d56Sopenharmony_ci 54297db96d56Sopenharmony_ci global C2 54307db96d56Sopenharmony_ci class C2(list): 54317db96d56Sopenharmony_ci "A list subclass copyable via __getnewargs__." 54327db96d56Sopenharmony_ci ARGS = (1, 2) 54337db96d56Sopenharmony_ci NEED_DICT_COPYING = False 54347db96d56Sopenharmony_ci def __new__(cls, a, b): 54357db96d56Sopenharmony_ci self = super().__new__(cls) 54367db96d56Sopenharmony_ci self.a = a 54377db96d56Sopenharmony_ci self.b = b 54387db96d56Sopenharmony_ci return self 54397db96d56Sopenharmony_ci def __init__(self, *args): 54407db96d56Sopenharmony_ci super().__init__() 54417db96d56Sopenharmony_ci # This helps testing that __init__ is not called during the 54427db96d56Sopenharmony_ci # unpickling process, which would cause extra appends. 54437db96d56Sopenharmony_ci self.append("cheese") 54447db96d56Sopenharmony_ci @classmethod 54457db96d56Sopenharmony_ci def __getnewargs__(cls): 54467db96d56Sopenharmony_ci return cls.ARGS 54477db96d56Sopenharmony_ci def __repr__(self): 54487db96d56Sopenharmony_ci return "C2(%r, %r)<%r>" % (self.a, self.b, list(self)) 54497db96d56Sopenharmony_ci 54507db96d56Sopenharmony_ci global C3 54517db96d56Sopenharmony_ci class C3(list): 54527db96d56Sopenharmony_ci "A list subclass copyable via __getstate__." 54537db96d56Sopenharmony_ci ARGS = (1, 2) 54547db96d56Sopenharmony_ci NEED_DICT_COPYING = False 54557db96d56Sopenharmony_ci def __init__(self, a, b): 54567db96d56Sopenharmony_ci self.a = a 54577db96d56Sopenharmony_ci self.b = b 54587db96d56Sopenharmony_ci # This helps testing that __init__ is not called during the 54597db96d56Sopenharmony_ci # unpickling process, which would cause extra appends. 54607db96d56Sopenharmony_ci self.append("cheese") 54617db96d56Sopenharmony_ci @classmethod 54627db96d56Sopenharmony_ci def __getstate__(cls): 54637db96d56Sopenharmony_ci return cls.ARGS 54647db96d56Sopenharmony_ci def __setstate__(self, state): 54657db96d56Sopenharmony_ci a, b = state 54667db96d56Sopenharmony_ci self.a = a 54677db96d56Sopenharmony_ci self.b = b 54687db96d56Sopenharmony_ci def __repr__(self): 54697db96d56Sopenharmony_ci return "C3(%r, %r)<%r>" % (self.a, self.b, list(self)) 54707db96d56Sopenharmony_ci 54717db96d56Sopenharmony_ci global C4 54727db96d56Sopenharmony_ci class C4(int): 54737db96d56Sopenharmony_ci "An int subclass copyable via __getnewargs__." 54747db96d56Sopenharmony_ci ARGS = ("hello", "world", 1) 54757db96d56Sopenharmony_ci NEED_DICT_COPYING = False 54767db96d56Sopenharmony_ci def __new__(cls, a, b, value): 54777db96d56Sopenharmony_ci self = super().__new__(cls, value) 54787db96d56Sopenharmony_ci self.a = a 54797db96d56Sopenharmony_ci self.b = b 54807db96d56Sopenharmony_ci return self 54817db96d56Sopenharmony_ci @classmethod 54827db96d56Sopenharmony_ci def __getnewargs__(cls): 54837db96d56Sopenharmony_ci return cls.ARGS 54847db96d56Sopenharmony_ci def __repr__(self): 54857db96d56Sopenharmony_ci return "C4(%r, %r)<%r>" % (self.a, self.b, int(self)) 54867db96d56Sopenharmony_ci 54877db96d56Sopenharmony_ci global C5 54887db96d56Sopenharmony_ci class C5(int): 54897db96d56Sopenharmony_ci "An int subclass copyable via __getnewargs_ex__." 54907db96d56Sopenharmony_ci ARGS = (1, 2) 54917db96d56Sopenharmony_ci KWARGS = {'value': 3} 54927db96d56Sopenharmony_ci NEED_DICT_COPYING = False 54937db96d56Sopenharmony_ci def __new__(cls, a, b, *, value=0): 54947db96d56Sopenharmony_ci self = super().__new__(cls, value) 54957db96d56Sopenharmony_ci self.a = a 54967db96d56Sopenharmony_ci self.b = b 54977db96d56Sopenharmony_ci return self 54987db96d56Sopenharmony_ci @classmethod 54997db96d56Sopenharmony_ci def __getnewargs_ex__(cls): 55007db96d56Sopenharmony_ci return (cls.ARGS, cls.KWARGS) 55017db96d56Sopenharmony_ci def __repr__(self): 55027db96d56Sopenharmony_ci return "C5(%r, %r)<%r>" % (self.a, self.b, int(self)) 55037db96d56Sopenharmony_ci 55047db96d56Sopenharmony_ci test_classes = (C1, C2, C3, C4, C5) 55057db96d56Sopenharmony_ci # Testing copying through pickle 55067db96d56Sopenharmony_ci pickle_copiers = self._generate_pickle_copiers() 55077db96d56Sopenharmony_ci for cls, pickle_copier in itertools.product(test_classes, pickle_copiers): 55087db96d56Sopenharmony_ci with self.subTest(cls=cls, pickle_copier=pickle_copier): 55097db96d56Sopenharmony_ci kwargs = getattr(cls, 'KWARGS', {}) 55107db96d56Sopenharmony_ci obj = cls(*cls.ARGS, **kwargs) 55117db96d56Sopenharmony_ci proto = pickle_copier.proto 55127db96d56Sopenharmony_ci objcopy = pickle_copier.copy(obj) 55137db96d56Sopenharmony_ci self._assert_is_copy(obj, objcopy) 55147db96d56Sopenharmony_ci # For test classes that supports this, make sure we didn't go 55157db96d56Sopenharmony_ci # around the reduce protocol by simply copying the attribute 55167db96d56Sopenharmony_ci # dictionary. We clear attributes using the previous copy to 55177db96d56Sopenharmony_ci # not mutate the original argument. 55187db96d56Sopenharmony_ci if proto >= 2 and not cls.NEED_DICT_COPYING: 55197db96d56Sopenharmony_ci objcopy.__dict__.clear() 55207db96d56Sopenharmony_ci objcopy2 = pickle_copier.copy(objcopy) 55217db96d56Sopenharmony_ci self._assert_is_copy(obj, objcopy2) 55227db96d56Sopenharmony_ci 55237db96d56Sopenharmony_ci # Testing copying through copy.deepcopy() 55247db96d56Sopenharmony_ci for cls in test_classes: 55257db96d56Sopenharmony_ci with self.subTest(cls=cls): 55267db96d56Sopenharmony_ci kwargs = getattr(cls, 'KWARGS', {}) 55277db96d56Sopenharmony_ci obj = cls(*cls.ARGS, **kwargs) 55287db96d56Sopenharmony_ci objcopy = deepcopy(obj) 55297db96d56Sopenharmony_ci self._assert_is_copy(obj, objcopy) 55307db96d56Sopenharmony_ci # For test classes that supports this, make sure we didn't go 55317db96d56Sopenharmony_ci # around the reduce protocol by simply copying the attribute 55327db96d56Sopenharmony_ci # dictionary. We clear attributes using the previous copy to 55337db96d56Sopenharmony_ci # not mutate the original argument. 55347db96d56Sopenharmony_ci if not cls.NEED_DICT_COPYING: 55357db96d56Sopenharmony_ci objcopy.__dict__.clear() 55367db96d56Sopenharmony_ci objcopy2 = deepcopy(objcopy) 55377db96d56Sopenharmony_ci self._assert_is_copy(obj, objcopy2) 55387db96d56Sopenharmony_ci 55397db96d56Sopenharmony_ci def test_issue24097(self): 55407db96d56Sopenharmony_ci # Slot name is freed inside __getattr__ and is later used. 55417db96d56Sopenharmony_ci class S(str): # Not interned 55427db96d56Sopenharmony_ci pass 55437db96d56Sopenharmony_ci class A: 55447db96d56Sopenharmony_ci __slotnames__ = [S('spam')] 55457db96d56Sopenharmony_ci def __getattr__(self, attr): 55467db96d56Sopenharmony_ci if attr == 'spam': 55477db96d56Sopenharmony_ci A.__slotnames__[:] = [S('spam')] 55487db96d56Sopenharmony_ci return 42 55497db96d56Sopenharmony_ci else: 55507db96d56Sopenharmony_ci raise AttributeError 55517db96d56Sopenharmony_ci 55527db96d56Sopenharmony_ci import copyreg 55537db96d56Sopenharmony_ci expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None) 55547db96d56Sopenharmony_ci self.assertEqual(A().__reduce_ex__(2), expected) # Shouldn't crash 55557db96d56Sopenharmony_ci 55567db96d56Sopenharmony_ci def test_object_reduce(self): 55577db96d56Sopenharmony_ci # Issue #29914 55587db96d56Sopenharmony_ci # __reduce__() takes no arguments 55597db96d56Sopenharmony_ci object().__reduce__() 55607db96d56Sopenharmony_ci with self.assertRaises(TypeError): 55617db96d56Sopenharmony_ci object().__reduce__(0) 55627db96d56Sopenharmony_ci # __reduce_ex__() takes one integer argument 55637db96d56Sopenharmony_ci object().__reduce_ex__(0) 55647db96d56Sopenharmony_ci with self.assertRaises(TypeError): 55657db96d56Sopenharmony_ci object().__reduce_ex__() 55667db96d56Sopenharmony_ci with self.assertRaises(TypeError): 55677db96d56Sopenharmony_ci object().__reduce_ex__(None) 55687db96d56Sopenharmony_ci 55697db96d56Sopenharmony_ci 55707db96d56Sopenharmony_ciclass SharedKeyTests(unittest.TestCase): 55717db96d56Sopenharmony_ci 55727db96d56Sopenharmony_ci @support.cpython_only 55737db96d56Sopenharmony_ci def test_subclasses(self): 55747db96d56Sopenharmony_ci # Verify that subclasses can share keys (per PEP 412) 55757db96d56Sopenharmony_ci class A: 55767db96d56Sopenharmony_ci pass 55777db96d56Sopenharmony_ci class B(A): 55787db96d56Sopenharmony_ci pass 55797db96d56Sopenharmony_ci 55807db96d56Sopenharmony_ci #Shrink keys by repeatedly creating instances 55817db96d56Sopenharmony_ci [(A(), B()) for _ in range(30)] 55827db96d56Sopenharmony_ci 55837db96d56Sopenharmony_ci a, b = A(), B() 55847db96d56Sopenharmony_ci self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) 55857db96d56Sopenharmony_ci self.assertLess(sys.getsizeof(vars(a)), sys.getsizeof({"a":1})) 55867db96d56Sopenharmony_ci # Initial hash table can contain only one or two elements. 55877db96d56Sopenharmony_ci # Set 6 attributes to cause internal resizing. 55887db96d56Sopenharmony_ci a.x, a.y, a.z, a.w, a.v, a.u = range(6) 55897db96d56Sopenharmony_ci self.assertNotEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) 55907db96d56Sopenharmony_ci a2 = A() 55917db96d56Sopenharmony_ci self.assertGreater(sys.getsizeof(vars(a)), sys.getsizeof(vars(a2))) 55927db96d56Sopenharmony_ci self.assertLess(sys.getsizeof(vars(a2)), sys.getsizeof({"a":1})) 55937db96d56Sopenharmony_ci self.assertLess(sys.getsizeof(vars(b)), sys.getsizeof({"a":1})) 55947db96d56Sopenharmony_ci 55957db96d56Sopenharmony_ci 55967db96d56Sopenharmony_ciclass DebugHelperMeta(type): 55977db96d56Sopenharmony_ci """ 55987db96d56Sopenharmony_ci Sets default __doc__ and simplifies repr() output. 55997db96d56Sopenharmony_ci """ 56007db96d56Sopenharmony_ci def __new__(mcls, name, bases, attrs): 56017db96d56Sopenharmony_ci if attrs.get('__doc__') is None: 56027db96d56Sopenharmony_ci attrs['__doc__'] = name # helps when debugging with gdb 56037db96d56Sopenharmony_ci return type.__new__(mcls, name, bases, attrs) 56047db96d56Sopenharmony_ci def __repr__(cls): 56057db96d56Sopenharmony_ci return repr(cls.__name__) 56067db96d56Sopenharmony_ci 56077db96d56Sopenharmony_ci 56087db96d56Sopenharmony_ciclass MroTest(unittest.TestCase): 56097db96d56Sopenharmony_ci """ 56107db96d56Sopenharmony_ci Regressions for some bugs revealed through 56117db96d56Sopenharmony_ci mcsl.mro() customization (typeobject.c: mro_internal()) and 56127db96d56Sopenharmony_ci cls.__bases__ assignment (typeobject.c: type_set_bases()). 56137db96d56Sopenharmony_ci """ 56147db96d56Sopenharmony_ci 56157db96d56Sopenharmony_ci def setUp(self): 56167db96d56Sopenharmony_ci self.step = 0 56177db96d56Sopenharmony_ci self.ready = False 56187db96d56Sopenharmony_ci 56197db96d56Sopenharmony_ci def step_until(self, limit): 56207db96d56Sopenharmony_ci ret = (self.step < limit) 56217db96d56Sopenharmony_ci if ret: 56227db96d56Sopenharmony_ci self.step += 1 56237db96d56Sopenharmony_ci return ret 56247db96d56Sopenharmony_ci 56257db96d56Sopenharmony_ci def test_incomplete_set_bases_on_self(self): 56267db96d56Sopenharmony_ci """ 56277db96d56Sopenharmony_ci type_set_bases must be aware that type->tp_mro can be NULL. 56287db96d56Sopenharmony_ci """ 56297db96d56Sopenharmony_ci class M(DebugHelperMeta): 56307db96d56Sopenharmony_ci def mro(cls): 56317db96d56Sopenharmony_ci if self.step_until(1): 56327db96d56Sopenharmony_ci assert cls.__mro__ is None 56337db96d56Sopenharmony_ci cls.__bases__ += () 56347db96d56Sopenharmony_ci 56357db96d56Sopenharmony_ci return type.mro(cls) 56367db96d56Sopenharmony_ci 56377db96d56Sopenharmony_ci class A(metaclass=M): 56387db96d56Sopenharmony_ci pass 56397db96d56Sopenharmony_ci 56407db96d56Sopenharmony_ci def test_reent_set_bases_on_base(self): 56417db96d56Sopenharmony_ci """ 56427db96d56Sopenharmony_ci Deep reentrancy must not over-decref old_mro. 56437db96d56Sopenharmony_ci """ 56447db96d56Sopenharmony_ci class M(DebugHelperMeta): 56457db96d56Sopenharmony_ci def mro(cls): 56467db96d56Sopenharmony_ci if cls.__mro__ is not None and cls.__name__ == 'B': 56477db96d56Sopenharmony_ci # 4-5 steps are usually enough to make it crash somewhere 56487db96d56Sopenharmony_ci if self.step_until(10): 56497db96d56Sopenharmony_ci A.__bases__ += () 56507db96d56Sopenharmony_ci 56517db96d56Sopenharmony_ci return type.mro(cls) 56527db96d56Sopenharmony_ci 56537db96d56Sopenharmony_ci class A(metaclass=M): 56547db96d56Sopenharmony_ci pass 56557db96d56Sopenharmony_ci class B(A): 56567db96d56Sopenharmony_ci pass 56577db96d56Sopenharmony_ci B.__bases__ += () 56587db96d56Sopenharmony_ci 56597db96d56Sopenharmony_ci def test_reent_set_bases_on_direct_base(self): 56607db96d56Sopenharmony_ci """ 56617db96d56Sopenharmony_ci Similar to test_reent_set_bases_on_base, but may crash differently. 56627db96d56Sopenharmony_ci """ 56637db96d56Sopenharmony_ci class M(DebugHelperMeta): 56647db96d56Sopenharmony_ci def mro(cls): 56657db96d56Sopenharmony_ci base = cls.__bases__[0] 56667db96d56Sopenharmony_ci if base is not object: 56677db96d56Sopenharmony_ci if self.step_until(5): 56687db96d56Sopenharmony_ci base.__bases__ += () 56697db96d56Sopenharmony_ci 56707db96d56Sopenharmony_ci return type.mro(cls) 56717db96d56Sopenharmony_ci 56727db96d56Sopenharmony_ci class A(metaclass=M): 56737db96d56Sopenharmony_ci pass 56747db96d56Sopenharmony_ci class B(A): 56757db96d56Sopenharmony_ci pass 56767db96d56Sopenharmony_ci class C(B): 56777db96d56Sopenharmony_ci pass 56787db96d56Sopenharmony_ci 56797db96d56Sopenharmony_ci def test_reent_set_bases_tp_base_cycle(self): 56807db96d56Sopenharmony_ci """ 56817db96d56Sopenharmony_ci type_set_bases must check for an inheritance cycle not only through 56827db96d56Sopenharmony_ci MRO of the type, which may be not yet updated in case of reentrance, 56837db96d56Sopenharmony_ci but also through tp_base chain, which is assigned before diving into 56847db96d56Sopenharmony_ci inner calls to mro(). 56857db96d56Sopenharmony_ci 56867db96d56Sopenharmony_ci Otherwise, the following snippet can loop forever: 56877db96d56Sopenharmony_ci do { 56887db96d56Sopenharmony_ci // ... 56897db96d56Sopenharmony_ci type = type->tp_base; 56907db96d56Sopenharmony_ci } while (type != NULL); 56917db96d56Sopenharmony_ci 56927db96d56Sopenharmony_ci Functions that rely on tp_base (like solid_base and PyType_IsSubtype) 56937db96d56Sopenharmony_ci would not be happy in that case, causing a stack overflow. 56947db96d56Sopenharmony_ci """ 56957db96d56Sopenharmony_ci class M(DebugHelperMeta): 56967db96d56Sopenharmony_ci def mro(cls): 56977db96d56Sopenharmony_ci if self.ready: 56987db96d56Sopenharmony_ci if cls.__name__ == 'B1': 56997db96d56Sopenharmony_ci B2.__bases__ = (B1,) 57007db96d56Sopenharmony_ci if cls.__name__ == 'B2': 57017db96d56Sopenharmony_ci B1.__bases__ = (B2,) 57027db96d56Sopenharmony_ci return type.mro(cls) 57037db96d56Sopenharmony_ci 57047db96d56Sopenharmony_ci class A(metaclass=M): 57057db96d56Sopenharmony_ci pass 57067db96d56Sopenharmony_ci class B1(A): 57077db96d56Sopenharmony_ci pass 57087db96d56Sopenharmony_ci class B2(A): 57097db96d56Sopenharmony_ci pass 57107db96d56Sopenharmony_ci 57117db96d56Sopenharmony_ci self.ready = True 57127db96d56Sopenharmony_ci with self.assertRaises(TypeError): 57137db96d56Sopenharmony_ci B1.__bases__ += () 57147db96d56Sopenharmony_ci 57157db96d56Sopenharmony_ci def test_tp_subclasses_cycle_in_update_slots(self): 57167db96d56Sopenharmony_ci """ 57177db96d56Sopenharmony_ci type_set_bases must check for reentrancy upon finishing its job 57187db96d56Sopenharmony_ci by updating tp_subclasses of old/new bases of the type. 57197db96d56Sopenharmony_ci Otherwise, an implicit inheritance cycle through tp_subclasses 57207db96d56Sopenharmony_ci can break functions that recurse on elements of that field 57217db96d56Sopenharmony_ci (like recurse_down_subclasses and mro_hierarchy) eventually 57227db96d56Sopenharmony_ci leading to a stack overflow. 57237db96d56Sopenharmony_ci """ 57247db96d56Sopenharmony_ci class M(DebugHelperMeta): 57257db96d56Sopenharmony_ci def mro(cls): 57267db96d56Sopenharmony_ci if self.ready and cls.__name__ == 'C': 57277db96d56Sopenharmony_ci self.ready = False 57287db96d56Sopenharmony_ci C.__bases__ = (B2,) 57297db96d56Sopenharmony_ci return type.mro(cls) 57307db96d56Sopenharmony_ci 57317db96d56Sopenharmony_ci class A(metaclass=M): 57327db96d56Sopenharmony_ci pass 57337db96d56Sopenharmony_ci class B1(A): 57347db96d56Sopenharmony_ci pass 57357db96d56Sopenharmony_ci class B2(A): 57367db96d56Sopenharmony_ci pass 57377db96d56Sopenharmony_ci class C(A): 57387db96d56Sopenharmony_ci pass 57397db96d56Sopenharmony_ci 57407db96d56Sopenharmony_ci self.ready = True 57417db96d56Sopenharmony_ci C.__bases__ = (B1,) 57427db96d56Sopenharmony_ci B1.__bases__ = (C,) 57437db96d56Sopenharmony_ci 57447db96d56Sopenharmony_ci self.assertEqual(C.__bases__, (B2,)) 57457db96d56Sopenharmony_ci self.assertEqual(B2.__subclasses__(), [C]) 57467db96d56Sopenharmony_ci self.assertEqual(B1.__subclasses__(), []) 57477db96d56Sopenharmony_ci 57487db96d56Sopenharmony_ci self.assertEqual(B1.__bases__, (C,)) 57497db96d56Sopenharmony_ci self.assertEqual(C.__subclasses__(), [B1]) 57507db96d56Sopenharmony_ci 57517db96d56Sopenharmony_ci def test_tp_subclasses_cycle_error_return_path(self): 57527db96d56Sopenharmony_ci """ 57537db96d56Sopenharmony_ci The same as test_tp_subclasses_cycle_in_update_slots, but tests 57547db96d56Sopenharmony_ci a code path executed on error (goto bail). 57557db96d56Sopenharmony_ci """ 57567db96d56Sopenharmony_ci class E(Exception): 57577db96d56Sopenharmony_ci pass 57587db96d56Sopenharmony_ci class M(DebugHelperMeta): 57597db96d56Sopenharmony_ci def mro(cls): 57607db96d56Sopenharmony_ci if self.ready and cls.__name__ == 'C': 57617db96d56Sopenharmony_ci if C.__bases__ == (B2,): 57627db96d56Sopenharmony_ci self.ready = False 57637db96d56Sopenharmony_ci else: 57647db96d56Sopenharmony_ci C.__bases__ = (B2,) 57657db96d56Sopenharmony_ci raise E 57667db96d56Sopenharmony_ci return type.mro(cls) 57677db96d56Sopenharmony_ci 57687db96d56Sopenharmony_ci class A(metaclass=M): 57697db96d56Sopenharmony_ci pass 57707db96d56Sopenharmony_ci class B1(A): 57717db96d56Sopenharmony_ci pass 57727db96d56Sopenharmony_ci class B2(A): 57737db96d56Sopenharmony_ci pass 57747db96d56Sopenharmony_ci class C(A): 57757db96d56Sopenharmony_ci pass 57767db96d56Sopenharmony_ci 57777db96d56Sopenharmony_ci self.ready = True 57787db96d56Sopenharmony_ci with self.assertRaises(E): 57797db96d56Sopenharmony_ci C.__bases__ = (B1,) 57807db96d56Sopenharmony_ci B1.__bases__ = (C,) 57817db96d56Sopenharmony_ci 57827db96d56Sopenharmony_ci self.assertEqual(C.__bases__, (B2,)) 57837db96d56Sopenharmony_ci self.assertEqual(C.__mro__, tuple(type.mro(C))) 57847db96d56Sopenharmony_ci 57857db96d56Sopenharmony_ci def test_incomplete_extend(self): 57867db96d56Sopenharmony_ci """ 57877db96d56Sopenharmony_ci Extending an uninitialized type with type->tp_mro == NULL must 57887db96d56Sopenharmony_ci throw a reasonable TypeError exception, instead of failing 57897db96d56Sopenharmony_ci with PyErr_BadInternalCall. 57907db96d56Sopenharmony_ci """ 57917db96d56Sopenharmony_ci class M(DebugHelperMeta): 57927db96d56Sopenharmony_ci def mro(cls): 57937db96d56Sopenharmony_ci if cls.__mro__ is None and cls.__name__ != 'X': 57947db96d56Sopenharmony_ci with self.assertRaises(TypeError): 57957db96d56Sopenharmony_ci class X(cls): 57967db96d56Sopenharmony_ci pass 57977db96d56Sopenharmony_ci 57987db96d56Sopenharmony_ci return type.mro(cls) 57997db96d56Sopenharmony_ci 58007db96d56Sopenharmony_ci class A(metaclass=M): 58017db96d56Sopenharmony_ci pass 58027db96d56Sopenharmony_ci 58037db96d56Sopenharmony_ci def test_incomplete_super(self): 58047db96d56Sopenharmony_ci """ 58057db96d56Sopenharmony_ci Attribute lookup on a super object must be aware that 58067db96d56Sopenharmony_ci its target type can be uninitialized (type->tp_mro == NULL). 58077db96d56Sopenharmony_ci """ 58087db96d56Sopenharmony_ci class M(DebugHelperMeta): 58097db96d56Sopenharmony_ci def mro(cls): 58107db96d56Sopenharmony_ci if cls.__mro__ is None: 58117db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 58127db96d56Sopenharmony_ci super(cls, cls).xxx 58137db96d56Sopenharmony_ci 58147db96d56Sopenharmony_ci return type.mro(cls) 58157db96d56Sopenharmony_ci 58167db96d56Sopenharmony_ci class A(metaclass=M): 58177db96d56Sopenharmony_ci pass 58187db96d56Sopenharmony_ci 58197db96d56Sopenharmony_ci def test_disappearing_custom_mro(self): 58207db96d56Sopenharmony_ci """ 58217db96d56Sopenharmony_ci gh-92112: A custom mro() returning a result conflicting with 58227db96d56Sopenharmony_ci __bases__ and deleting itself caused a double free. 58237db96d56Sopenharmony_ci """ 58247db96d56Sopenharmony_ci class B: 58257db96d56Sopenharmony_ci pass 58267db96d56Sopenharmony_ci 58277db96d56Sopenharmony_ci class M(DebugHelperMeta): 58287db96d56Sopenharmony_ci def mro(cls): 58297db96d56Sopenharmony_ci del M.mro 58307db96d56Sopenharmony_ci return (B,) 58317db96d56Sopenharmony_ci 58327db96d56Sopenharmony_ci with self.assertRaises(TypeError): 58337db96d56Sopenharmony_ci class A(metaclass=M): 58347db96d56Sopenharmony_ci pass 58357db96d56Sopenharmony_ci 58367db96d56Sopenharmony_ci 58377db96d56Sopenharmony_ciif __name__ == "__main__": 58387db96d56Sopenharmony_ci unittest.main() 5839