17db96d56Sopenharmony_ciimport unittest 27db96d56Sopenharmony_cifrom test import support 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ciclass TestMROEntry(unittest.TestCase): 67db96d56Sopenharmony_ci def test_mro_entry_signature(self): 77db96d56Sopenharmony_ci tested = [] 87db96d56Sopenharmony_ci class B: ... 97db96d56Sopenharmony_ci class C: 107db96d56Sopenharmony_ci def __mro_entries__(self, *args, **kwargs): 117db96d56Sopenharmony_ci tested.extend([args, kwargs]) 127db96d56Sopenharmony_ci return (C,) 137db96d56Sopenharmony_ci c = C() 147db96d56Sopenharmony_ci self.assertEqual(tested, []) 157db96d56Sopenharmony_ci class D(B, c): ... 167db96d56Sopenharmony_ci self.assertEqual(tested[0], ((B, c),)) 177db96d56Sopenharmony_ci self.assertEqual(tested[1], {}) 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci def test_mro_entry(self): 207db96d56Sopenharmony_ci tested = [] 217db96d56Sopenharmony_ci class A: ... 227db96d56Sopenharmony_ci class B: ... 237db96d56Sopenharmony_ci class C: 247db96d56Sopenharmony_ci def __mro_entries__(self, bases): 257db96d56Sopenharmony_ci tested.append(bases) 267db96d56Sopenharmony_ci return (self.__class__,) 277db96d56Sopenharmony_ci c = C() 287db96d56Sopenharmony_ci self.assertEqual(tested, []) 297db96d56Sopenharmony_ci class D(A, c, B): ... 307db96d56Sopenharmony_ci self.assertEqual(tested[-1], (A, c, B)) 317db96d56Sopenharmony_ci self.assertEqual(D.__bases__, (A, C, B)) 327db96d56Sopenharmony_ci self.assertEqual(D.__orig_bases__, (A, c, B)) 337db96d56Sopenharmony_ci self.assertEqual(D.__mro__, (D, A, C, B, object)) 347db96d56Sopenharmony_ci d = D() 357db96d56Sopenharmony_ci class E(d): ... 367db96d56Sopenharmony_ci self.assertEqual(tested[-1], (d,)) 377db96d56Sopenharmony_ci self.assertEqual(E.__bases__, (D,)) 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci def test_mro_entry_none(self): 407db96d56Sopenharmony_ci tested = [] 417db96d56Sopenharmony_ci class A: ... 427db96d56Sopenharmony_ci class B: ... 437db96d56Sopenharmony_ci class C: 447db96d56Sopenharmony_ci def __mro_entries__(self, bases): 457db96d56Sopenharmony_ci tested.append(bases) 467db96d56Sopenharmony_ci return () 477db96d56Sopenharmony_ci c = C() 487db96d56Sopenharmony_ci self.assertEqual(tested, []) 497db96d56Sopenharmony_ci class D(A, c, B): ... 507db96d56Sopenharmony_ci self.assertEqual(tested[-1], (A, c, B)) 517db96d56Sopenharmony_ci self.assertEqual(D.__bases__, (A, B)) 527db96d56Sopenharmony_ci self.assertEqual(D.__orig_bases__, (A, c, B)) 537db96d56Sopenharmony_ci self.assertEqual(D.__mro__, (D, A, B, object)) 547db96d56Sopenharmony_ci class E(c): ... 557db96d56Sopenharmony_ci self.assertEqual(tested[-1], (c,)) 567db96d56Sopenharmony_ci self.assertEqual(E.__bases__, (object,)) 577db96d56Sopenharmony_ci self.assertEqual(E.__orig_bases__, (c,)) 587db96d56Sopenharmony_ci self.assertEqual(E.__mro__, (E, object)) 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci def test_mro_entry_with_builtins(self): 617db96d56Sopenharmony_ci tested = [] 627db96d56Sopenharmony_ci class A: ... 637db96d56Sopenharmony_ci class C: 647db96d56Sopenharmony_ci def __mro_entries__(self, bases): 657db96d56Sopenharmony_ci tested.append(bases) 667db96d56Sopenharmony_ci return (dict,) 677db96d56Sopenharmony_ci c = C() 687db96d56Sopenharmony_ci self.assertEqual(tested, []) 697db96d56Sopenharmony_ci class D(A, c): ... 707db96d56Sopenharmony_ci self.assertEqual(tested[-1], (A, c)) 717db96d56Sopenharmony_ci self.assertEqual(D.__bases__, (A, dict)) 727db96d56Sopenharmony_ci self.assertEqual(D.__orig_bases__, (A, c)) 737db96d56Sopenharmony_ci self.assertEqual(D.__mro__, (D, A, dict, object)) 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci def test_mro_entry_with_builtins_2(self): 767db96d56Sopenharmony_ci tested = [] 777db96d56Sopenharmony_ci class C: 787db96d56Sopenharmony_ci def __mro_entries__(self, bases): 797db96d56Sopenharmony_ci tested.append(bases) 807db96d56Sopenharmony_ci return (C,) 817db96d56Sopenharmony_ci c = C() 827db96d56Sopenharmony_ci self.assertEqual(tested, []) 837db96d56Sopenharmony_ci class D(c, dict): ... 847db96d56Sopenharmony_ci self.assertEqual(tested[-1], (c, dict)) 857db96d56Sopenharmony_ci self.assertEqual(D.__bases__, (C, dict)) 867db96d56Sopenharmony_ci self.assertEqual(D.__orig_bases__, (c, dict)) 877db96d56Sopenharmony_ci self.assertEqual(D.__mro__, (D, C, dict, object)) 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci def test_mro_entry_errors(self): 907db96d56Sopenharmony_ci class C_too_many: 917db96d56Sopenharmony_ci def __mro_entries__(self, bases, something, other): 927db96d56Sopenharmony_ci return () 937db96d56Sopenharmony_ci c = C_too_many() 947db96d56Sopenharmony_ci with self.assertRaises(TypeError): 957db96d56Sopenharmony_ci class D(c): ... 967db96d56Sopenharmony_ci class C_too_few: 977db96d56Sopenharmony_ci def __mro_entries__(self): 987db96d56Sopenharmony_ci return () 997db96d56Sopenharmony_ci d = C_too_few() 1007db96d56Sopenharmony_ci with self.assertRaises(TypeError): 1017db96d56Sopenharmony_ci class D(d): ... 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci def test_mro_entry_errors_2(self): 1047db96d56Sopenharmony_ci class C_not_callable: 1057db96d56Sopenharmony_ci __mro_entries__ = "Surprise!" 1067db96d56Sopenharmony_ci c = C_not_callable() 1077db96d56Sopenharmony_ci with self.assertRaises(TypeError): 1087db96d56Sopenharmony_ci class D(c): ... 1097db96d56Sopenharmony_ci class C_not_tuple: 1107db96d56Sopenharmony_ci def __mro_entries__(self): 1117db96d56Sopenharmony_ci return object 1127db96d56Sopenharmony_ci c = C_not_tuple() 1137db96d56Sopenharmony_ci with self.assertRaises(TypeError): 1147db96d56Sopenharmony_ci class D(c): ... 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ci def test_mro_entry_metaclass(self): 1177db96d56Sopenharmony_ci meta_args = [] 1187db96d56Sopenharmony_ci class Meta(type): 1197db96d56Sopenharmony_ci def __new__(mcls, name, bases, ns): 1207db96d56Sopenharmony_ci meta_args.extend([mcls, name, bases, ns]) 1217db96d56Sopenharmony_ci return super().__new__(mcls, name, bases, ns) 1227db96d56Sopenharmony_ci class A: ... 1237db96d56Sopenharmony_ci class C: 1247db96d56Sopenharmony_ci def __mro_entries__(self, bases): 1257db96d56Sopenharmony_ci return (A,) 1267db96d56Sopenharmony_ci c = C() 1277db96d56Sopenharmony_ci class D(c, metaclass=Meta): 1287db96d56Sopenharmony_ci x = 1 1297db96d56Sopenharmony_ci self.assertEqual(meta_args[0], Meta) 1307db96d56Sopenharmony_ci self.assertEqual(meta_args[1], 'D') 1317db96d56Sopenharmony_ci self.assertEqual(meta_args[2], (A,)) 1327db96d56Sopenharmony_ci self.assertEqual(meta_args[3]['x'], 1) 1337db96d56Sopenharmony_ci self.assertEqual(D.__bases__, (A,)) 1347db96d56Sopenharmony_ci self.assertEqual(D.__orig_bases__, (c,)) 1357db96d56Sopenharmony_ci self.assertEqual(D.__mro__, (D, A, object)) 1367db96d56Sopenharmony_ci self.assertEqual(D.__class__, Meta) 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_ci def test_mro_entry_type_call(self): 1397db96d56Sopenharmony_ci # Substitution should _not_ happen in direct type call 1407db96d56Sopenharmony_ci class C: 1417db96d56Sopenharmony_ci def __mro_entries__(self, bases): 1427db96d56Sopenharmony_ci return () 1437db96d56Sopenharmony_ci c = C() 1447db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, 1457db96d56Sopenharmony_ci "MRO entry resolution; " 1467db96d56Sopenharmony_ci "use types.new_class()"): 1477db96d56Sopenharmony_ci type('Bad', (c,), {}) 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_ciclass TestClassGetitem(unittest.TestCase): 1517db96d56Sopenharmony_ci def test_class_getitem(self): 1527db96d56Sopenharmony_ci getitem_args = [] 1537db96d56Sopenharmony_ci class C: 1547db96d56Sopenharmony_ci def __class_getitem__(*args, **kwargs): 1557db96d56Sopenharmony_ci getitem_args.extend([args, kwargs]) 1567db96d56Sopenharmony_ci return None 1577db96d56Sopenharmony_ci C[int, str] 1587db96d56Sopenharmony_ci self.assertEqual(getitem_args[0], (C, (int, str))) 1597db96d56Sopenharmony_ci self.assertEqual(getitem_args[1], {}) 1607db96d56Sopenharmony_ci 1617db96d56Sopenharmony_ci def test_class_getitem_format(self): 1627db96d56Sopenharmony_ci class C: 1637db96d56Sopenharmony_ci def __class_getitem__(cls, item): 1647db96d56Sopenharmony_ci return f'C[{item.__name__}]' 1657db96d56Sopenharmony_ci self.assertEqual(C[int], 'C[int]') 1667db96d56Sopenharmony_ci self.assertEqual(C[C], 'C[C]') 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ci def test_class_getitem_inheritance(self): 1697db96d56Sopenharmony_ci class C: 1707db96d56Sopenharmony_ci def __class_getitem__(cls, item): 1717db96d56Sopenharmony_ci return f'{cls.__name__}[{item.__name__}]' 1727db96d56Sopenharmony_ci class D(C): ... 1737db96d56Sopenharmony_ci self.assertEqual(D[int], 'D[int]') 1747db96d56Sopenharmony_ci self.assertEqual(D[D], 'D[D]') 1757db96d56Sopenharmony_ci 1767db96d56Sopenharmony_ci def test_class_getitem_inheritance_2(self): 1777db96d56Sopenharmony_ci class C: 1787db96d56Sopenharmony_ci def __class_getitem__(cls, item): 1797db96d56Sopenharmony_ci return 'Should not see this' 1807db96d56Sopenharmony_ci class D(C): 1817db96d56Sopenharmony_ci def __class_getitem__(cls, item): 1827db96d56Sopenharmony_ci return f'{cls.__name__}[{item.__name__}]' 1837db96d56Sopenharmony_ci self.assertEqual(D[int], 'D[int]') 1847db96d56Sopenharmony_ci self.assertEqual(D[D], 'D[D]') 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci def test_class_getitem_classmethod(self): 1877db96d56Sopenharmony_ci class C: 1887db96d56Sopenharmony_ci @classmethod 1897db96d56Sopenharmony_ci def __class_getitem__(cls, item): 1907db96d56Sopenharmony_ci return f'{cls.__name__}[{item.__name__}]' 1917db96d56Sopenharmony_ci class D(C): ... 1927db96d56Sopenharmony_ci self.assertEqual(D[int], 'D[int]') 1937db96d56Sopenharmony_ci self.assertEqual(D[D], 'D[D]') 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_ci def test_class_getitem_patched(self): 1967db96d56Sopenharmony_ci class C: 1977db96d56Sopenharmony_ci def __init_subclass__(cls): 1987db96d56Sopenharmony_ci def __class_getitem__(cls, item): 1997db96d56Sopenharmony_ci return f'{cls.__name__}[{item.__name__}]' 2007db96d56Sopenharmony_ci cls.__class_getitem__ = classmethod(__class_getitem__) 2017db96d56Sopenharmony_ci class D(C): ... 2027db96d56Sopenharmony_ci self.assertEqual(D[int], 'D[int]') 2037db96d56Sopenharmony_ci self.assertEqual(D[D], 'D[D]') 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_ci def test_class_getitem_with_builtins(self): 2067db96d56Sopenharmony_ci class A(dict): 2077db96d56Sopenharmony_ci called_with = None 2087db96d56Sopenharmony_ci 2097db96d56Sopenharmony_ci def __class_getitem__(cls, item): 2107db96d56Sopenharmony_ci cls.called_with = item 2117db96d56Sopenharmony_ci class B(A): 2127db96d56Sopenharmony_ci pass 2137db96d56Sopenharmony_ci self.assertIs(B.called_with, None) 2147db96d56Sopenharmony_ci B[int] 2157db96d56Sopenharmony_ci self.assertIs(B.called_with, int) 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci def test_class_getitem_errors(self): 2187db96d56Sopenharmony_ci class C_too_few: 2197db96d56Sopenharmony_ci def __class_getitem__(cls): 2207db96d56Sopenharmony_ci return None 2217db96d56Sopenharmony_ci with self.assertRaises(TypeError): 2227db96d56Sopenharmony_ci C_too_few[int] 2237db96d56Sopenharmony_ci 2247db96d56Sopenharmony_ci class C_too_many: 2257db96d56Sopenharmony_ci def __class_getitem__(cls, one, two): 2267db96d56Sopenharmony_ci return None 2277db96d56Sopenharmony_ci with self.assertRaises(TypeError): 2287db96d56Sopenharmony_ci C_too_many[int] 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ci def test_class_getitem_errors_2(self): 2317db96d56Sopenharmony_ci class C: 2327db96d56Sopenharmony_ci def __class_getitem__(cls, item): 2337db96d56Sopenharmony_ci return None 2347db96d56Sopenharmony_ci with self.assertRaises(TypeError): 2357db96d56Sopenharmony_ci C()[int] 2367db96d56Sopenharmony_ci 2377db96d56Sopenharmony_ci class E: ... 2387db96d56Sopenharmony_ci e = E() 2397db96d56Sopenharmony_ci e.__class_getitem__ = lambda cls, item: 'This will not work' 2407db96d56Sopenharmony_ci with self.assertRaises(TypeError): 2417db96d56Sopenharmony_ci e[int] 2427db96d56Sopenharmony_ci 2437db96d56Sopenharmony_ci class C_not_callable: 2447db96d56Sopenharmony_ci __class_getitem__ = "Surprise!" 2457db96d56Sopenharmony_ci with self.assertRaises(TypeError): 2467db96d56Sopenharmony_ci C_not_callable[int] 2477db96d56Sopenharmony_ci 2487db96d56Sopenharmony_ci class C_is_none(tuple): 2497db96d56Sopenharmony_ci __class_getitem__ = None 2507db96d56Sopenharmony_ci with self.assertRaisesRegex(TypeError, "C_is_none"): 2517db96d56Sopenharmony_ci C_is_none[int] 2527db96d56Sopenharmony_ci 2537db96d56Sopenharmony_ci def test_class_getitem_metaclass(self): 2547db96d56Sopenharmony_ci class Meta(type): 2557db96d56Sopenharmony_ci def __class_getitem__(cls, item): 2567db96d56Sopenharmony_ci return f'{cls.__name__}[{item.__name__}]' 2577db96d56Sopenharmony_ci self.assertEqual(Meta[int], 'Meta[int]') 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci def test_class_getitem_with_metaclass(self): 2607db96d56Sopenharmony_ci class Meta(type): pass 2617db96d56Sopenharmony_ci class C(metaclass=Meta): 2627db96d56Sopenharmony_ci def __class_getitem__(cls, item): 2637db96d56Sopenharmony_ci return f'{cls.__name__}[{item.__name__}]' 2647db96d56Sopenharmony_ci self.assertEqual(C[int], 'C[int]') 2657db96d56Sopenharmony_ci 2667db96d56Sopenharmony_ci def test_class_getitem_metaclass_first(self): 2677db96d56Sopenharmony_ci class Meta(type): 2687db96d56Sopenharmony_ci def __getitem__(cls, item): 2697db96d56Sopenharmony_ci return 'from metaclass' 2707db96d56Sopenharmony_ci class C(metaclass=Meta): 2717db96d56Sopenharmony_ci def __class_getitem__(cls, item): 2727db96d56Sopenharmony_ci return 'from __class_getitem__' 2737db96d56Sopenharmony_ci self.assertEqual(C[int], 'from metaclass') 2747db96d56Sopenharmony_ci 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci@support.cpython_only 2777db96d56Sopenharmony_ciclass CAPITest(unittest.TestCase): 2787db96d56Sopenharmony_ci 2797db96d56Sopenharmony_ci def test_c_class(self): 2807db96d56Sopenharmony_ci from _testcapi import Generic, GenericAlias 2817db96d56Sopenharmony_ci self.assertIsInstance(Generic.__class_getitem__(int), GenericAlias) 2827db96d56Sopenharmony_ci 2837db96d56Sopenharmony_ci IntGeneric = Generic[int] 2847db96d56Sopenharmony_ci self.assertIs(type(IntGeneric), GenericAlias) 2857db96d56Sopenharmony_ci self.assertEqual(IntGeneric.__mro_entries__(()), (int,)) 2867db96d56Sopenharmony_ci class C(IntGeneric): 2877db96d56Sopenharmony_ci pass 2887db96d56Sopenharmony_ci self.assertEqual(C.__bases__, (int,)) 2897db96d56Sopenharmony_ci self.assertEqual(C.__orig_bases__, (IntGeneric,)) 2907db96d56Sopenharmony_ci self.assertEqual(C.__mro__, (C, int, object)) 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci 2937db96d56Sopenharmony_ciif __name__ == "__main__": 2947db96d56Sopenharmony_ci unittest.main() 295