17db96d56Sopenharmony_ci# Copyright 2007 Google, Inc. All Rights Reserved.
27db96d56Sopenharmony_ci# Licensed to PSF under a Contributor Agreement.
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci# Note: each test is run with Python and C versions of ABCMeta. Except for
57db96d56Sopenharmony_ci# test_ABC_helper(), which assures that abc.ABC is an instance of abc.ABCMeta.
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci"""Unit tests for abc.py."""
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ciimport unittest
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ciimport abc
127db96d56Sopenharmony_ciimport _py_abc
137db96d56Sopenharmony_cifrom inspect import isabstract
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_cidef test_factory(abc_ABCMeta, abc_get_cache_token):
167db96d56Sopenharmony_ci    class TestLegacyAPI(unittest.TestCase):
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci        def test_abstractproperty_basics(self):
197db96d56Sopenharmony_ci            @abc.abstractproperty
207db96d56Sopenharmony_ci            def foo(self): pass
217db96d56Sopenharmony_ci            self.assertTrue(foo.__isabstractmethod__)
227db96d56Sopenharmony_ci            def bar(self): pass
237db96d56Sopenharmony_ci            self.assertFalse(hasattr(bar, "__isabstractmethod__"))
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
267db96d56Sopenharmony_ci                @abc.abstractproperty
277db96d56Sopenharmony_ci                def foo(self): return 3
287db96d56Sopenharmony_ci            self.assertRaises(TypeError, C)
297db96d56Sopenharmony_ci            class D(C):
307db96d56Sopenharmony_ci                @property
317db96d56Sopenharmony_ci                def foo(self): return super().foo
327db96d56Sopenharmony_ci            self.assertEqual(D().foo, 3)
337db96d56Sopenharmony_ci            self.assertFalse(getattr(D.foo, "__isabstractmethod__", False))
347db96d56Sopenharmony_ci
357db96d56Sopenharmony_ci        def test_abstractclassmethod_basics(self):
367db96d56Sopenharmony_ci            @abc.abstractclassmethod
377db96d56Sopenharmony_ci            def foo(cls): pass
387db96d56Sopenharmony_ci            self.assertTrue(foo.__isabstractmethod__)
397db96d56Sopenharmony_ci            @classmethod
407db96d56Sopenharmony_ci            def bar(cls): pass
417db96d56Sopenharmony_ci            self.assertFalse(getattr(bar, "__isabstractmethod__", False))
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
447db96d56Sopenharmony_ci                @abc.abstractclassmethod
457db96d56Sopenharmony_ci                def foo(cls): return cls.__name__
467db96d56Sopenharmony_ci            self.assertRaises(TypeError, C)
477db96d56Sopenharmony_ci            class D(C):
487db96d56Sopenharmony_ci                @classmethod
497db96d56Sopenharmony_ci                def foo(cls): return super().foo()
507db96d56Sopenharmony_ci            self.assertEqual(D.foo(), 'D')
517db96d56Sopenharmony_ci            self.assertEqual(D().foo(), 'D')
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci        def test_abstractstaticmethod_basics(self):
547db96d56Sopenharmony_ci            @abc.abstractstaticmethod
557db96d56Sopenharmony_ci            def foo(): pass
567db96d56Sopenharmony_ci            self.assertTrue(foo.__isabstractmethod__)
577db96d56Sopenharmony_ci            @staticmethod
587db96d56Sopenharmony_ci            def bar(): pass
597db96d56Sopenharmony_ci            self.assertFalse(getattr(bar, "__isabstractmethod__", False))
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
627db96d56Sopenharmony_ci                @abc.abstractstaticmethod
637db96d56Sopenharmony_ci                def foo(): return 3
647db96d56Sopenharmony_ci            self.assertRaises(TypeError, C)
657db96d56Sopenharmony_ci            class D(C):
667db96d56Sopenharmony_ci                @staticmethod
677db96d56Sopenharmony_ci                def foo(): return 4
687db96d56Sopenharmony_ci            self.assertEqual(D.foo(), 4)
697db96d56Sopenharmony_ci            self.assertEqual(D().foo(), 4)
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci    class TestABC(unittest.TestCase):
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_ci        def test_ABC_helper(self):
757db96d56Sopenharmony_ci            # create an ABC using the helper class and perform basic checks
767db96d56Sopenharmony_ci            class C(abc.ABC):
777db96d56Sopenharmony_ci                @classmethod
787db96d56Sopenharmony_ci                @abc.abstractmethod
797db96d56Sopenharmony_ci                def foo(cls): return cls.__name__
807db96d56Sopenharmony_ci            self.assertEqual(type(C), abc.ABCMeta)
817db96d56Sopenharmony_ci            self.assertRaises(TypeError, C)
827db96d56Sopenharmony_ci            class D(C):
837db96d56Sopenharmony_ci                @classmethod
847db96d56Sopenharmony_ci                def foo(cls): return super().foo()
857db96d56Sopenharmony_ci            self.assertEqual(D.foo(), 'D')
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci        def test_abstractmethod_basics(self):
887db96d56Sopenharmony_ci            @abc.abstractmethod
897db96d56Sopenharmony_ci            def foo(self): pass
907db96d56Sopenharmony_ci            self.assertTrue(foo.__isabstractmethod__)
917db96d56Sopenharmony_ci            def bar(self): pass
927db96d56Sopenharmony_ci            self.assertFalse(hasattr(bar, "__isabstractmethod__"))
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ci        def test_abstractproperty_basics(self):
957db96d56Sopenharmony_ci            @property
967db96d56Sopenharmony_ci            @abc.abstractmethod
977db96d56Sopenharmony_ci            def foo(self): pass
987db96d56Sopenharmony_ci            self.assertTrue(foo.__isabstractmethod__)
997db96d56Sopenharmony_ci            def bar(self): pass
1007db96d56Sopenharmony_ci            self.assertFalse(getattr(bar, "__isabstractmethod__", False))
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
1037db96d56Sopenharmony_ci                @property
1047db96d56Sopenharmony_ci                @abc.abstractmethod
1057db96d56Sopenharmony_ci                def foo(self): return 3
1067db96d56Sopenharmony_ci            self.assertRaises(TypeError, C)
1077db96d56Sopenharmony_ci            class D(C):
1087db96d56Sopenharmony_ci                @C.foo.getter
1097db96d56Sopenharmony_ci                def foo(self): return super().foo
1107db96d56Sopenharmony_ci            self.assertEqual(D().foo, 3)
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ci        def test_abstractclassmethod_basics(self):
1137db96d56Sopenharmony_ci            @classmethod
1147db96d56Sopenharmony_ci            @abc.abstractmethod
1157db96d56Sopenharmony_ci            def foo(cls): pass
1167db96d56Sopenharmony_ci            self.assertTrue(foo.__isabstractmethod__)
1177db96d56Sopenharmony_ci            @classmethod
1187db96d56Sopenharmony_ci            def bar(cls): pass
1197db96d56Sopenharmony_ci            self.assertFalse(getattr(bar, "__isabstractmethod__", False))
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
1227db96d56Sopenharmony_ci                @classmethod
1237db96d56Sopenharmony_ci                @abc.abstractmethod
1247db96d56Sopenharmony_ci                def foo(cls): return cls.__name__
1257db96d56Sopenharmony_ci            self.assertRaises(TypeError, C)
1267db96d56Sopenharmony_ci            class D(C):
1277db96d56Sopenharmony_ci                @classmethod
1287db96d56Sopenharmony_ci                def foo(cls): return super().foo()
1297db96d56Sopenharmony_ci            self.assertEqual(D.foo(), 'D')
1307db96d56Sopenharmony_ci            self.assertEqual(D().foo(), 'D')
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ci        def test_abstractstaticmethod_basics(self):
1337db96d56Sopenharmony_ci            @staticmethod
1347db96d56Sopenharmony_ci            @abc.abstractmethod
1357db96d56Sopenharmony_ci            def foo(): pass
1367db96d56Sopenharmony_ci            self.assertTrue(foo.__isabstractmethod__)
1377db96d56Sopenharmony_ci            @staticmethod
1387db96d56Sopenharmony_ci            def bar(): pass
1397db96d56Sopenharmony_ci            self.assertFalse(getattr(bar, "__isabstractmethod__", False))
1407db96d56Sopenharmony_ci
1417db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
1427db96d56Sopenharmony_ci                @staticmethod
1437db96d56Sopenharmony_ci                @abc.abstractmethod
1447db96d56Sopenharmony_ci                def foo(): return 3
1457db96d56Sopenharmony_ci            self.assertRaises(TypeError, C)
1467db96d56Sopenharmony_ci            class D(C):
1477db96d56Sopenharmony_ci                @staticmethod
1487db96d56Sopenharmony_ci                def foo(): return 4
1497db96d56Sopenharmony_ci            self.assertEqual(D.foo(), 4)
1507db96d56Sopenharmony_ci            self.assertEqual(D().foo(), 4)
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_ci        def test_object_new_with_one_abstractmethod(self):
1537db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
1547db96d56Sopenharmony_ci                @abc.abstractmethod
1557db96d56Sopenharmony_ci                def method_one(self):
1567db96d56Sopenharmony_ci                    pass
1577db96d56Sopenharmony_ci            msg = r"class C with abstract method method_one"
1587db96d56Sopenharmony_ci            self.assertRaisesRegex(TypeError, msg, C)
1597db96d56Sopenharmony_ci
1607db96d56Sopenharmony_ci        def test_object_new_with_many_abstractmethods(self):
1617db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
1627db96d56Sopenharmony_ci                @abc.abstractmethod
1637db96d56Sopenharmony_ci                def method_one(self):
1647db96d56Sopenharmony_ci                    pass
1657db96d56Sopenharmony_ci                @abc.abstractmethod
1667db96d56Sopenharmony_ci                def method_two(self):
1677db96d56Sopenharmony_ci                    pass
1687db96d56Sopenharmony_ci            msg = r"class C with abstract methods method_one, method_two"
1697db96d56Sopenharmony_ci            self.assertRaisesRegex(TypeError, msg, C)
1707db96d56Sopenharmony_ci
1717db96d56Sopenharmony_ci        def test_abstractmethod_integration(self):
1727db96d56Sopenharmony_ci            for abstractthing in [abc.abstractmethod, abc.abstractproperty,
1737db96d56Sopenharmony_ci                                  abc.abstractclassmethod,
1747db96d56Sopenharmony_ci                                  abc.abstractstaticmethod]:
1757db96d56Sopenharmony_ci                class C(metaclass=abc_ABCMeta):
1767db96d56Sopenharmony_ci                    @abstractthing
1777db96d56Sopenharmony_ci                    def foo(self): pass  # abstract
1787db96d56Sopenharmony_ci                    def bar(self): pass  # concrete
1797db96d56Sopenharmony_ci                self.assertEqual(C.__abstractmethods__, {"foo"})
1807db96d56Sopenharmony_ci                self.assertRaises(TypeError, C)  # because foo is abstract
1817db96d56Sopenharmony_ci                self.assertTrue(isabstract(C))
1827db96d56Sopenharmony_ci                class D(C):
1837db96d56Sopenharmony_ci                    def bar(self): pass  # concrete override of concrete
1847db96d56Sopenharmony_ci                self.assertEqual(D.__abstractmethods__, {"foo"})
1857db96d56Sopenharmony_ci                self.assertRaises(TypeError, D)  # because foo is still abstract
1867db96d56Sopenharmony_ci                self.assertTrue(isabstract(D))
1877db96d56Sopenharmony_ci                class E(D):
1887db96d56Sopenharmony_ci                    def foo(self): pass
1897db96d56Sopenharmony_ci                self.assertEqual(E.__abstractmethods__, set())
1907db96d56Sopenharmony_ci                E()  # now foo is concrete, too
1917db96d56Sopenharmony_ci                self.assertFalse(isabstract(E))
1927db96d56Sopenharmony_ci                class F(E):
1937db96d56Sopenharmony_ci                    @abstractthing
1947db96d56Sopenharmony_ci                    def bar(self): pass  # abstract override of concrete
1957db96d56Sopenharmony_ci                self.assertEqual(F.__abstractmethods__, {"bar"})
1967db96d56Sopenharmony_ci                self.assertRaises(TypeError, F)  # because bar is abstract now
1977db96d56Sopenharmony_ci                self.assertTrue(isabstract(F))
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ci        def test_descriptors_with_abstractmethod(self):
2007db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
2017db96d56Sopenharmony_ci                @property
2027db96d56Sopenharmony_ci                @abc.abstractmethod
2037db96d56Sopenharmony_ci                def foo(self): return 3
2047db96d56Sopenharmony_ci                @foo.setter
2057db96d56Sopenharmony_ci                @abc.abstractmethod
2067db96d56Sopenharmony_ci                def foo(self, val): pass
2077db96d56Sopenharmony_ci            self.assertRaises(TypeError, C)
2087db96d56Sopenharmony_ci            class D(C):
2097db96d56Sopenharmony_ci                @C.foo.getter
2107db96d56Sopenharmony_ci                def foo(self): return super().foo
2117db96d56Sopenharmony_ci            self.assertRaises(TypeError, D)
2127db96d56Sopenharmony_ci            class E(D):
2137db96d56Sopenharmony_ci                @D.foo.setter
2147db96d56Sopenharmony_ci                def foo(self, val): pass
2157db96d56Sopenharmony_ci            self.assertEqual(E().foo, 3)
2167db96d56Sopenharmony_ci            # check that the property's __isabstractmethod__ descriptor does the
2177db96d56Sopenharmony_ci            # right thing when presented with a value that fails truth testing:
2187db96d56Sopenharmony_ci            class NotBool(object):
2197db96d56Sopenharmony_ci                def __bool__(self):
2207db96d56Sopenharmony_ci                    raise ValueError()
2217db96d56Sopenharmony_ci                __len__ = __bool__
2227db96d56Sopenharmony_ci            with self.assertRaises(ValueError):
2237db96d56Sopenharmony_ci                class F(C):
2247db96d56Sopenharmony_ci                    def bar(self):
2257db96d56Sopenharmony_ci                        pass
2267db96d56Sopenharmony_ci                    bar.__isabstractmethod__ = NotBool()
2277db96d56Sopenharmony_ci                    foo = property(bar)
2287db96d56Sopenharmony_ci
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci        def test_customdescriptors_with_abstractmethod(self):
2317db96d56Sopenharmony_ci            class Descriptor:
2327db96d56Sopenharmony_ci                def __init__(self, fget, fset=None):
2337db96d56Sopenharmony_ci                    self._fget = fget
2347db96d56Sopenharmony_ci                    self._fset = fset
2357db96d56Sopenharmony_ci                def getter(self, callable):
2367db96d56Sopenharmony_ci                    return Descriptor(callable, self._fget)
2377db96d56Sopenharmony_ci                def setter(self, callable):
2387db96d56Sopenharmony_ci                    return Descriptor(self._fget, callable)
2397db96d56Sopenharmony_ci                @property
2407db96d56Sopenharmony_ci                def __isabstractmethod__(self):
2417db96d56Sopenharmony_ci                    return (getattr(self._fget, '__isabstractmethod__', False)
2427db96d56Sopenharmony_ci                            or getattr(self._fset, '__isabstractmethod__', False))
2437db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
2447db96d56Sopenharmony_ci                @Descriptor
2457db96d56Sopenharmony_ci                @abc.abstractmethod
2467db96d56Sopenharmony_ci                def foo(self): return 3
2477db96d56Sopenharmony_ci                @foo.setter
2487db96d56Sopenharmony_ci                @abc.abstractmethod
2497db96d56Sopenharmony_ci                def foo(self, val): pass
2507db96d56Sopenharmony_ci            self.assertRaises(TypeError, C)
2517db96d56Sopenharmony_ci            class D(C):
2527db96d56Sopenharmony_ci                @C.foo.getter
2537db96d56Sopenharmony_ci                def foo(self): return super().foo
2547db96d56Sopenharmony_ci            self.assertRaises(TypeError, D)
2557db96d56Sopenharmony_ci            class E(D):
2567db96d56Sopenharmony_ci                @D.foo.setter
2577db96d56Sopenharmony_ci                def foo(self, val): pass
2587db96d56Sopenharmony_ci            self.assertFalse(E.foo.__isabstractmethod__)
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_ci        def test_metaclass_abc(self):
2617db96d56Sopenharmony_ci            # Metaclasses can be ABCs, too.
2627db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
2637db96d56Sopenharmony_ci                @abc.abstractmethod
2647db96d56Sopenharmony_ci                def x(self):
2657db96d56Sopenharmony_ci                    pass
2667db96d56Sopenharmony_ci            self.assertEqual(A.__abstractmethods__, {"x"})
2677db96d56Sopenharmony_ci            class meta(type, A):
2687db96d56Sopenharmony_ci                def x(self):
2697db96d56Sopenharmony_ci                    return 1
2707db96d56Sopenharmony_ci            class C(metaclass=meta):
2717db96d56Sopenharmony_ci                pass
2727db96d56Sopenharmony_ci
2737db96d56Sopenharmony_ci        def test_registration_basics(self):
2747db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
2757db96d56Sopenharmony_ci                pass
2767db96d56Sopenharmony_ci            class B(object):
2777db96d56Sopenharmony_ci                pass
2787db96d56Sopenharmony_ci            b = B()
2797db96d56Sopenharmony_ci            self.assertFalse(issubclass(B, A))
2807db96d56Sopenharmony_ci            self.assertFalse(issubclass(B, (A,)))
2817db96d56Sopenharmony_ci            self.assertNotIsInstance(b, A)
2827db96d56Sopenharmony_ci            self.assertNotIsInstance(b, (A,))
2837db96d56Sopenharmony_ci            B1 = A.register(B)
2847db96d56Sopenharmony_ci            self.assertTrue(issubclass(B, A))
2857db96d56Sopenharmony_ci            self.assertTrue(issubclass(B, (A,)))
2867db96d56Sopenharmony_ci            self.assertIsInstance(b, A)
2877db96d56Sopenharmony_ci            self.assertIsInstance(b, (A,))
2887db96d56Sopenharmony_ci            self.assertIs(B1, B)
2897db96d56Sopenharmony_ci            class C(B):
2907db96d56Sopenharmony_ci                pass
2917db96d56Sopenharmony_ci            c = C()
2927db96d56Sopenharmony_ci            self.assertTrue(issubclass(C, A))
2937db96d56Sopenharmony_ci            self.assertTrue(issubclass(C, (A,)))
2947db96d56Sopenharmony_ci            self.assertIsInstance(c, A)
2957db96d56Sopenharmony_ci            self.assertIsInstance(c, (A,))
2967db96d56Sopenharmony_ci
2977db96d56Sopenharmony_ci        def test_register_as_class_deco(self):
2987db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
2997db96d56Sopenharmony_ci                pass
3007db96d56Sopenharmony_ci            @A.register
3017db96d56Sopenharmony_ci            class B(object):
3027db96d56Sopenharmony_ci                pass
3037db96d56Sopenharmony_ci            b = B()
3047db96d56Sopenharmony_ci            self.assertTrue(issubclass(B, A))
3057db96d56Sopenharmony_ci            self.assertTrue(issubclass(B, (A,)))
3067db96d56Sopenharmony_ci            self.assertIsInstance(b, A)
3077db96d56Sopenharmony_ci            self.assertIsInstance(b, (A,))
3087db96d56Sopenharmony_ci            @A.register
3097db96d56Sopenharmony_ci            class C(B):
3107db96d56Sopenharmony_ci                pass
3117db96d56Sopenharmony_ci            c = C()
3127db96d56Sopenharmony_ci            self.assertTrue(issubclass(C, A))
3137db96d56Sopenharmony_ci            self.assertTrue(issubclass(C, (A,)))
3147db96d56Sopenharmony_ci            self.assertIsInstance(c, A)
3157db96d56Sopenharmony_ci            self.assertIsInstance(c, (A,))
3167db96d56Sopenharmony_ci            self.assertIs(C, A.register(C))
3177db96d56Sopenharmony_ci
3187db96d56Sopenharmony_ci        def test_isinstance_invalidation(self):
3197db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
3207db96d56Sopenharmony_ci                pass
3217db96d56Sopenharmony_ci            class B:
3227db96d56Sopenharmony_ci                pass
3237db96d56Sopenharmony_ci            b = B()
3247db96d56Sopenharmony_ci            self.assertFalse(isinstance(b, A))
3257db96d56Sopenharmony_ci            self.assertFalse(isinstance(b, (A,)))
3267db96d56Sopenharmony_ci            token_old = abc_get_cache_token()
3277db96d56Sopenharmony_ci            A.register(B)
3287db96d56Sopenharmony_ci            token_new = abc_get_cache_token()
3297db96d56Sopenharmony_ci            self.assertGreater(token_new, token_old)
3307db96d56Sopenharmony_ci            self.assertTrue(isinstance(b, A))
3317db96d56Sopenharmony_ci            self.assertTrue(isinstance(b, (A,)))
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci        def test_registration_builtins(self):
3347db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
3357db96d56Sopenharmony_ci                pass
3367db96d56Sopenharmony_ci            A.register(int)
3377db96d56Sopenharmony_ci            self.assertIsInstance(42, A)
3387db96d56Sopenharmony_ci            self.assertIsInstance(42, (A,))
3397db96d56Sopenharmony_ci            self.assertTrue(issubclass(int, A))
3407db96d56Sopenharmony_ci            self.assertTrue(issubclass(int, (A,)))
3417db96d56Sopenharmony_ci            class B(A):
3427db96d56Sopenharmony_ci                pass
3437db96d56Sopenharmony_ci            B.register(str)
3447db96d56Sopenharmony_ci            class C(str): pass
3457db96d56Sopenharmony_ci            self.assertIsInstance("", A)
3467db96d56Sopenharmony_ci            self.assertIsInstance("", (A,))
3477db96d56Sopenharmony_ci            self.assertTrue(issubclass(str, A))
3487db96d56Sopenharmony_ci            self.assertTrue(issubclass(str, (A,)))
3497db96d56Sopenharmony_ci            self.assertTrue(issubclass(C, A))
3507db96d56Sopenharmony_ci            self.assertTrue(issubclass(C, (A,)))
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_ci        def test_registration_edge_cases(self):
3537db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
3547db96d56Sopenharmony_ci                pass
3557db96d56Sopenharmony_ci            A.register(A)  # should pass silently
3567db96d56Sopenharmony_ci            class A1(A):
3577db96d56Sopenharmony_ci                pass
3587db96d56Sopenharmony_ci            self.assertRaises(RuntimeError, A1.register, A)  # cycles not allowed
3597db96d56Sopenharmony_ci            class B(object):
3607db96d56Sopenharmony_ci                pass
3617db96d56Sopenharmony_ci            A1.register(B)  # ok
3627db96d56Sopenharmony_ci            A1.register(B)  # should pass silently
3637db96d56Sopenharmony_ci            class C(A):
3647db96d56Sopenharmony_ci                pass
3657db96d56Sopenharmony_ci            A.register(C)  # should pass silently
3667db96d56Sopenharmony_ci            self.assertRaises(RuntimeError, C.register, A)  # cycles not allowed
3677db96d56Sopenharmony_ci            C.register(B)  # ok
3687db96d56Sopenharmony_ci
3697db96d56Sopenharmony_ci        def test_register_non_class(self):
3707db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
3717db96d56Sopenharmony_ci                pass
3727db96d56Sopenharmony_ci            self.assertRaisesRegex(TypeError, "Can only register classes",
3737db96d56Sopenharmony_ci                                   A.register, 4)
3747db96d56Sopenharmony_ci
3757db96d56Sopenharmony_ci        def test_registration_transitiveness(self):
3767db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
3777db96d56Sopenharmony_ci                pass
3787db96d56Sopenharmony_ci            self.assertTrue(issubclass(A, A))
3797db96d56Sopenharmony_ci            self.assertTrue(issubclass(A, (A,)))
3807db96d56Sopenharmony_ci            class B(metaclass=abc_ABCMeta):
3817db96d56Sopenharmony_ci                pass
3827db96d56Sopenharmony_ci            self.assertFalse(issubclass(A, B))
3837db96d56Sopenharmony_ci            self.assertFalse(issubclass(A, (B,)))
3847db96d56Sopenharmony_ci            self.assertFalse(issubclass(B, A))
3857db96d56Sopenharmony_ci            self.assertFalse(issubclass(B, (A,)))
3867db96d56Sopenharmony_ci            class C(metaclass=abc_ABCMeta):
3877db96d56Sopenharmony_ci                pass
3887db96d56Sopenharmony_ci            A.register(B)
3897db96d56Sopenharmony_ci            class B1(B):
3907db96d56Sopenharmony_ci                pass
3917db96d56Sopenharmony_ci            self.assertTrue(issubclass(B1, A))
3927db96d56Sopenharmony_ci            self.assertTrue(issubclass(B1, (A,)))
3937db96d56Sopenharmony_ci            class C1(C):
3947db96d56Sopenharmony_ci                pass
3957db96d56Sopenharmony_ci            B1.register(C1)
3967db96d56Sopenharmony_ci            self.assertFalse(issubclass(C, B))
3977db96d56Sopenharmony_ci            self.assertFalse(issubclass(C, (B,)))
3987db96d56Sopenharmony_ci            self.assertFalse(issubclass(C, B1))
3997db96d56Sopenharmony_ci            self.assertFalse(issubclass(C, (B1,)))
4007db96d56Sopenharmony_ci            self.assertTrue(issubclass(C1, A))
4017db96d56Sopenharmony_ci            self.assertTrue(issubclass(C1, (A,)))
4027db96d56Sopenharmony_ci            self.assertTrue(issubclass(C1, B))
4037db96d56Sopenharmony_ci            self.assertTrue(issubclass(C1, (B,)))
4047db96d56Sopenharmony_ci            self.assertTrue(issubclass(C1, B1))
4057db96d56Sopenharmony_ci            self.assertTrue(issubclass(C1, (B1,)))
4067db96d56Sopenharmony_ci            C1.register(int)
4077db96d56Sopenharmony_ci            class MyInt(int):
4087db96d56Sopenharmony_ci                pass
4097db96d56Sopenharmony_ci            self.assertTrue(issubclass(MyInt, A))
4107db96d56Sopenharmony_ci            self.assertTrue(issubclass(MyInt, (A,)))
4117db96d56Sopenharmony_ci            self.assertIsInstance(42, A)
4127db96d56Sopenharmony_ci            self.assertIsInstance(42, (A,))
4137db96d56Sopenharmony_ci
4147db96d56Sopenharmony_ci        def test_issubclass_bad_arguments(self):
4157db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
4167db96d56Sopenharmony_ci                pass
4177db96d56Sopenharmony_ci
4187db96d56Sopenharmony_ci            with self.assertRaises(TypeError):
4197db96d56Sopenharmony_ci                issubclass({}, A)  # unhashable
4207db96d56Sopenharmony_ci
4217db96d56Sopenharmony_ci            with self.assertRaises(TypeError):
4227db96d56Sopenharmony_ci                issubclass(42, A)  # No __mro__
4237db96d56Sopenharmony_ci
4247db96d56Sopenharmony_ci            # Python version supports any iterable as __mro__.
4257db96d56Sopenharmony_ci            # But it's implementation detail and don't emulate it in C version.
4267db96d56Sopenharmony_ci            class C:
4277db96d56Sopenharmony_ci                __mro__ = 42  # __mro__ is not tuple
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_ci            with self.assertRaises(TypeError):
4307db96d56Sopenharmony_ci                issubclass(C(), A)
4317db96d56Sopenharmony_ci
4327db96d56Sopenharmony_ci            # bpo-34441: Check that issubclass() doesn't crash on bogus
4337db96d56Sopenharmony_ci            # classes.
4347db96d56Sopenharmony_ci            bogus_subclasses = [
4357db96d56Sopenharmony_ci                None,
4367db96d56Sopenharmony_ci                lambda x: [],
4377db96d56Sopenharmony_ci                lambda: 42,
4387db96d56Sopenharmony_ci                lambda: [42],
4397db96d56Sopenharmony_ci            ]
4407db96d56Sopenharmony_ci
4417db96d56Sopenharmony_ci            for i, func in enumerate(bogus_subclasses):
4427db96d56Sopenharmony_ci                class S(metaclass=abc_ABCMeta):
4437db96d56Sopenharmony_ci                    __subclasses__ = func
4447db96d56Sopenharmony_ci
4457db96d56Sopenharmony_ci                with self.subTest(i=i):
4467db96d56Sopenharmony_ci                    with self.assertRaises(TypeError):
4477db96d56Sopenharmony_ci                        issubclass(int, S)
4487db96d56Sopenharmony_ci
4497db96d56Sopenharmony_ci            # Also check that issubclass() propagates exceptions raised by
4507db96d56Sopenharmony_ci            # __subclasses__.
4517db96d56Sopenharmony_ci            exc_msg = "exception from __subclasses__"
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_ci            def raise_exc():
4547db96d56Sopenharmony_ci                raise Exception(exc_msg)
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_ci            class S(metaclass=abc_ABCMeta):
4577db96d56Sopenharmony_ci                __subclasses__ = raise_exc
4587db96d56Sopenharmony_ci
4597db96d56Sopenharmony_ci            with self.assertRaisesRegex(Exception, exc_msg):
4607db96d56Sopenharmony_ci                issubclass(int, S)
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ci        def test_subclasshook(self):
4637db96d56Sopenharmony_ci            class A(metaclass=abc.ABCMeta):
4647db96d56Sopenharmony_ci                @classmethod
4657db96d56Sopenharmony_ci                def __subclasshook__(cls, C):
4667db96d56Sopenharmony_ci                    if cls is A:
4677db96d56Sopenharmony_ci                        return 'foo' in C.__dict__
4687db96d56Sopenharmony_ci                    return NotImplemented
4697db96d56Sopenharmony_ci            self.assertFalse(issubclass(A, A))
4707db96d56Sopenharmony_ci            self.assertFalse(issubclass(A, (A,)))
4717db96d56Sopenharmony_ci            class B:
4727db96d56Sopenharmony_ci                foo = 42
4737db96d56Sopenharmony_ci            self.assertTrue(issubclass(B, A))
4747db96d56Sopenharmony_ci            self.assertTrue(issubclass(B, (A,)))
4757db96d56Sopenharmony_ci            class C:
4767db96d56Sopenharmony_ci                spam = 42
4777db96d56Sopenharmony_ci            self.assertFalse(issubclass(C, A))
4787db96d56Sopenharmony_ci            self.assertFalse(issubclass(C, (A,)))
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ci        def test_all_new_methods_are_called(self):
4817db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
4827db96d56Sopenharmony_ci                pass
4837db96d56Sopenharmony_ci            class B(object):
4847db96d56Sopenharmony_ci                counter = 0
4857db96d56Sopenharmony_ci                def __new__(cls):
4867db96d56Sopenharmony_ci                    B.counter += 1
4877db96d56Sopenharmony_ci                    return super().__new__(cls)
4887db96d56Sopenharmony_ci            class C(A, B):
4897db96d56Sopenharmony_ci                pass
4907db96d56Sopenharmony_ci            self.assertEqual(B.counter, 0)
4917db96d56Sopenharmony_ci            C()
4927db96d56Sopenharmony_ci            self.assertEqual(B.counter, 1)
4937db96d56Sopenharmony_ci
4947db96d56Sopenharmony_ci        def test_ABC_has___slots__(self):
4957db96d56Sopenharmony_ci            self.assertTrue(hasattr(abc.ABC, '__slots__'))
4967db96d56Sopenharmony_ci
4977db96d56Sopenharmony_ci        def test_tricky_new_works(self):
4987db96d56Sopenharmony_ci            def with_metaclass(meta, *bases):
4997db96d56Sopenharmony_ci                class metaclass(type):
5007db96d56Sopenharmony_ci                    def __new__(cls, name, this_bases, d):
5017db96d56Sopenharmony_ci                        return meta(name, bases, d)
5027db96d56Sopenharmony_ci                return type.__new__(metaclass, 'temporary_class', (), {})
5037db96d56Sopenharmony_ci            class A: ...
5047db96d56Sopenharmony_ci            class B: ...
5057db96d56Sopenharmony_ci            class C(with_metaclass(abc_ABCMeta, A, B)):
5067db96d56Sopenharmony_ci                pass
5077db96d56Sopenharmony_ci            self.assertEqual(C.__class__, abc_ABCMeta)
5087db96d56Sopenharmony_ci
5097db96d56Sopenharmony_ci        def test_update_del(self):
5107db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
5117db96d56Sopenharmony_ci                @abc.abstractmethod
5127db96d56Sopenharmony_ci                def foo(self):
5137db96d56Sopenharmony_ci                    pass
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_ci            del A.foo
5167db96d56Sopenharmony_ci            self.assertEqual(A.__abstractmethods__, {'foo'})
5177db96d56Sopenharmony_ci            self.assertFalse(hasattr(A, 'foo'))
5187db96d56Sopenharmony_ci
5197db96d56Sopenharmony_ci            abc.update_abstractmethods(A)
5207db96d56Sopenharmony_ci
5217db96d56Sopenharmony_ci            self.assertEqual(A.__abstractmethods__, set())
5227db96d56Sopenharmony_ci            A()
5237db96d56Sopenharmony_ci
5247db96d56Sopenharmony_ci
5257db96d56Sopenharmony_ci        def test_update_new_abstractmethods(self):
5267db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
5277db96d56Sopenharmony_ci                @abc.abstractmethod
5287db96d56Sopenharmony_ci                def bar(self):
5297db96d56Sopenharmony_ci                    pass
5307db96d56Sopenharmony_ci
5317db96d56Sopenharmony_ci            @abc.abstractmethod
5327db96d56Sopenharmony_ci            def updated_foo(self):
5337db96d56Sopenharmony_ci                pass
5347db96d56Sopenharmony_ci
5357db96d56Sopenharmony_ci            A.foo = updated_foo
5367db96d56Sopenharmony_ci            abc.update_abstractmethods(A)
5377db96d56Sopenharmony_ci            self.assertEqual(A.__abstractmethods__, {'foo', 'bar'})
5387db96d56Sopenharmony_ci            msg = "class A with abstract methods bar, foo"
5397db96d56Sopenharmony_ci            self.assertRaisesRegex(TypeError, msg, A)
5407db96d56Sopenharmony_ci
5417db96d56Sopenharmony_ci        def test_update_implementation(self):
5427db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
5437db96d56Sopenharmony_ci                @abc.abstractmethod
5447db96d56Sopenharmony_ci                def foo(self):
5457db96d56Sopenharmony_ci                    pass
5467db96d56Sopenharmony_ci
5477db96d56Sopenharmony_ci            class B(A):
5487db96d56Sopenharmony_ci                pass
5497db96d56Sopenharmony_ci
5507db96d56Sopenharmony_ci            msg = "class B with abstract method foo"
5517db96d56Sopenharmony_ci            self.assertRaisesRegex(TypeError, msg, B)
5527db96d56Sopenharmony_ci            self.assertEqual(B.__abstractmethods__, {'foo'})
5537db96d56Sopenharmony_ci
5547db96d56Sopenharmony_ci            B.foo = lambda self: None
5557db96d56Sopenharmony_ci
5567db96d56Sopenharmony_ci            abc.update_abstractmethods(B)
5577db96d56Sopenharmony_ci
5587db96d56Sopenharmony_ci            B()
5597db96d56Sopenharmony_ci            self.assertEqual(B.__abstractmethods__, set())
5607db96d56Sopenharmony_ci
5617db96d56Sopenharmony_ci        def test_update_as_decorator(self):
5627db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
5637db96d56Sopenharmony_ci                @abc.abstractmethod
5647db96d56Sopenharmony_ci                def foo(self):
5657db96d56Sopenharmony_ci                    pass
5667db96d56Sopenharmony_ci
5677db96d56Sopenharmony_ci            def class_decorator(cls):
5687db96d56Sopenharmony_ci                cls.foo = lambda self: None
5697db96d56Sopenharmony_ci                return cls
5707db96d56Sopenharmony_ci
5717db96d56Sopenharmony_ci            @abc.update_abstractmethods
5727db96d56Sopenharmony_ci            @class_decorator
5737db96d56Sopenharmony_ci            class B(A):
5747db96d56Sopenharmony_ci                pass
5757db96d56Sopenharmony_ci
5767db96d56Sopenharmony_ci            B()
5777db96d56Sopenharmony_ci            self.assertEqual(B.__abstractmethods__, set())
5787db96d56Sopenharmony_ci
5797db96d56Sopenharmony_ci        def test_update_non_abc(self):
5807db96d56Sopenharmony_ci            class A:
5817db96d56Sopenharmony_ci                pass
5827db96d56Sopenharmony_ci
5837db96d56Sopenharmony_ci            @abc.abstractmethod
5847db96d56Sopenharmony_ci            def updated_foo(self):
5857db96d56Sopenharmony_ci                pass
5867db96d56Sopenharmony_ci
5877db96d56Sopenharmony_ci            A.foo = updated_foo
5887db96d56Sopenharmony_ci            abc.update_abstractmethods(A)
5897db96d56Sopenharmony_ci            A()
5907db96d56Sopenharmony_ci            self.assertFalse(hasattr(A, '__abstractmethods__'))
5917db96d56Sopenharmony_ci
5927db96d56Sopenharmony_ci        def test_update_del_implementation(self):
5937db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
5947db96d56Sopenharmony_ci                @abc.abstractmethod
5957db96d56Sopenharmony_ci                def foo(self):
5967db96d56Sopenharmony_ci                    pass
5977db96d56Sopenharmony_ci
5987db96d56Sopenharmony_ci            class B(A):
5997db96d56Sopenharmony_ci                def foo(self):
6007db96d56Sopenharmony_ci                    pass
6017db96d56Sopenharmony_ci
6027db96d56Sopenharmony_ci            B()
6037db96d56Sopenharmony_ci
6047db96d56Sopenharmony_ci            del B.foo
6057db96d56Sopenharmony_ci
6067db96d56Sopenharmony_ci            abc.update_abstractmethods(B)
6077db96d56Sopenharmony_ci
6087db96d56Sopenharmony_ci            msg = "class B with abstract method foo"
6097db96d56Sopenharmony_ci            self.assertRaisesRegex(TypeError, msg, B)
6107db96d56Sopenharmony_ci
6117db96d56Sopenharmony_ci        def test_update_layered_implementation(self):
6127db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
6137db96d56Sopenharmony_ci                @abc.abstractmethod
6147db96d56Sopenharmony_ci                def foo(self):
6157db96d56Sopenharmony_ci                    pass
6167db96d56Sopenharmony_ci
6177db96d56Sopenharmony_ci            class B(A):
6187db96d56Sopenharmony_ci                pass
6197db96d56Sopenharmony_ci
6207db96d56Sopenharmony_ci            class C(B):
6217db96d56Sopenharmony_ci                def foo(self):
6227db96d56Sopenharmony_ci                    pass
6237db96d56Sopenharmony_ci
6247db96d56Sopenharmony_ci            C()
6257db96d56Sopenharmony_ci
6267db96d56Sopenharmony_ci            del C.foo
6277db96d56Sopenharmony_ci
6287db96d56Sopenharmony_ci            abc.update_abstractmethods(C)
6297db96d56Sopenharmony_ci
6307db96d56Sopenharmony_ci            msg = "class C with abstract method foo"
6317db96d56Sopenharmony_ci            self.assertRaisesRegex(TypeError, msg, C)
6327db96d56Sopenharmony_ci
6337db96d56Sopenharmony_ci        def test_update_multi_inheritance(self):
6347db96d56Sopenharmony_ci            class A(metaclass=abc_ABCMeta):
6357db96d56Sopenharmony_ci                @abc.abstractmethod
6367db96d56Sopenharmony_ci                def foo(self):
6377db96d56Sopenharmony_ci                    pass
6387db96d56Sopenharmony_ci
6397db96d56Sopenharmony_ci            class B(metaclass=abc_ABCMeta):
6407db96d56Sopenharmony_ci                def foo(self):
6417db96d56Sopenharmony_ci                    pass
6427db96d56Sopenharmony_ci
6437db96d56Sopenharmony_ci            class C(B, A):
6447db96d56Sopenharmony_ci                @abc.abstractmethod
6457db96d56Sopenharmony_ci                def foo(self):
6467db96d56Sopenharmony_ci                    pass
6477db96d56Sopenharmony_ci
6487db96d56Sopenharmony_ci            self.assertEqual(C.__abstractmethods__, {'foo'})
6497db96d56Sopenharmony_ci
6507db96d56Sopenharmony_ci            del C.foo
6517db96d56Sopenharmony_ci
6527db96d56Sopenharmony_ci            abc.update_abstractmethods(C)
6537db96d56Sopenharmony_ci
6547db96d56Sopenharmony_ci            self.assertEqual(C.__abstractmethods__, set())
6557db96d56Sopenharmony_ci
6567db96d56Sopenharmony_ci            C()
6577db96d56Sopenharmony_ci
6587db96d56Sopenharmony_ci
6597db96d56Sopenharmony_ci    class TestABCWithInitSubclass(unittest.TestCase):
6607db96d56Sopenharmony_ci        def test_works_with_init_subclass(self):
6617db96d56Sopenharmony_ci            class abc_ABC(metaclass=abc_ABCMeta):
6627db96d56Sopenharmony_ci                __slots__ = ()
6637db96d56Sopenharmony_ci            saved_kwargs = {}
6647db96d56Sopenharmony_ci            class ReceivesClassKwargs:
6657db96d56Sopenharmony_ci                def __init_subclass__(cls, **kwargs):
6667db96d56Sopenharmony_ci                    super().__init_subclass__()
6677db96d56Sopenharmony_ci                    saved_kwargs.update(kwargs)
6687db96d56Sopenharmony_ci            class Receiver(ReceivesClassKwargs, abc_ABC, x=1, y=2, z=3):
6697db96d56Sopenharmony_ci                pass
6707db96d56Sopenharmony_ci            self.assertEqual(saved_kwargs, dict(x=1, y=2, z=3))
6717db96d56Sopenharmony_ci
6727db96d56Sopenharmony_ci        def test_positional_only_and_kwonlyargs_with_init_subclass(self):
6737db96d56Sopenharmony_ci            saved_kwargs = {}
6747db96d56Sopenharmony_ci
6757db96d56Sopenharmony_ci            class A:
6767db96d56Sopenharmony_ci                def __init_subclass__(cls, **kwargs):
6777db96d56Sopenharmony_ci                    super().__init_subclass__()
6787db96d56Sopenharmony_ci                    saved_kwargs.update(kwargs)
6797db96d56Sopenharmony_ci
6807db96d56Sopenharmony_ci            class B(A, metaclass=abc_ABCMeta, name="test"):
6817db96d56Sopenharmony_ci                pass
6827db96d56Sopenharmony_ci            self.assertEqual(saved_kwargs, dict(name="test"))
6837db96d56Sopenharmony_ci
6847db96d56Sopenharmony_ci    return TestLegacyAPI, TestABC, TestABCWithInitSubclass
6857db96d56Sopenharmony_ci
6867db96d56Sopenharmony_ciTestLegacyAPI_Py, TestABC_Py, TestABCWithInitSubclass_Py = test_factory(abc.ABCMeta,
6877db96d56Sopenharmony_ci                                                                        abc.get_cache_token)
6887db96d56Sopenharmony_ciTestLegacyAPI_C, TestABC_C, TestABCWithInitSubclass_C = test_factory(_py_abc.ABCMeta,
6897db96d56Sopenharmony_ci                                                                     _py_abc.get_cache_token)
6907db96d56Sopenharmony_ci
6917db96d56Sopenharmony_ciif __name__ == "__main__":
6927db96d56Sopenharmony_ci    unittest.main()
693