1edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Copyright 2007 Google, Inc. All Rights Reserved.
2edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Licensed to PSF under a Contributor Agreement.
3edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
4edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep"""Unit tests for abc.py."""
5edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
6edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport unittest, weakref
7edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom test import test_support
8edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
9edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport abc
10edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom inspect import isabstract
11edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
12edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
13edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestABC(unittest.TestCase):
14edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
15edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_abstractmethod_basics(self):
16edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        @abc.abstractmethod
17edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def foo(self): pass
18edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(foo.__isabstractmethod__)
19edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def bar(self): pass
20edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(hasattr(bar, "__isabstractmethod__"))
21edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
22edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_abstractproperty_basics(self):
23edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        @abc.abstractproperty
24edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def foo(self): pass
25edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(foo.__isabstractmethod__)
26edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def bar(self): pass
27edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(hasattr(bar, "__isabstractmethod__"))
28edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
29edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class C:
30edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
31edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            @abc.abstractproperty
32edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            def foo(self): return 3
33edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class D(C):
34edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            @property
35edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            def foo(self): return super(D, self).foo
36edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(D().foo, 3)
37edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
38edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_abstractmethod_integration(self):
39edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        for abstractthing in [abc.abstractmethod, abc.abstractproperty]:
40edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            class C:
41edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                __metaclass__ = abc.ABCMeta
42edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                @abstractthing
43edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                def foo(self): pass  # abstract
44edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                def bar(self): pass  # concrete
45edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertEqual(C.__abstractmethods__, set(["foo"]))
46edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertRaises(TypeError, C)  # because foo is abstract
47edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertTrue(isabstract(C))
48edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            class D(C):
49edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                def bar(self): pass  # concrete override of concrete
50edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertEqual(D.__abstractmethods__, set(["foo"]))
51edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertRaises(TypeError, D)  # because foo is still abstract
52edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertTrue(isabstract(D))
53edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            class E(D):
54edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                def foo(self): pass
55edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertEqual(E.__abstractmethods__, set())
56edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            E()  # now foo is concrete, too
57edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertFalse(isabstract(E))
58edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            class F(E):
59edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                @abstractthing
60edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                def bar(self): pass  # abstract override of concrete
61edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertEqual(F.__abstractmethods__, set(["bar"]))
62edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertRaises(TypeError, F)  # because bar is abstract now
63edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertTrue(isabstract(F))
64edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
65edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_subclass_oldstyle_class(self):
66edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A:
67edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
68edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class OldstyleClass:
69edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
70edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(OldstyleClass, A))
71edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(A, OldstyleClass))
72edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
73edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_isinstance_class(self):
74edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A:
75edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
76edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class OldstyleClass:
77edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
78edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(isinstance(OldstyleClass, A))
79edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(isinstance(OldstyleClass, type(OldstyleClass)))
80edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(isinstance(A, OldstyleClass))
81edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # This raises a recursion depth error, but is low-priority:
82edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # self.assertTrue(isinstance(A, abc.ABCMeta))
83edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
84edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_registration_basics(self):
85edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A:
86edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
87edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class B(object):
88edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
89edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        b = B()
90edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(B, A))
91edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(B, (A,)))
92edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertNotIsInstance(b, A)
93edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertNotIsInstance(b, (A,))
94edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A.register(B)
95edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(B, A))
96edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(B, (A,)))
97edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance(b, A)
98edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance(b, (A,))
99edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class C(B):
100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        c = C()
102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(C, A))
103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(C, (A,)))
104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance(c, A)
105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance(c, (A,))
106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_isinstance_invalidation(self):
108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A:
109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class B(object):
111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        b = B()
113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(isinstance(b, A))
114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(isinstance(b, (A,)))
115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A.register(B)
116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(isinstance(b, A))
117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(isinstance(b, (A,)))
118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_registration_builtins(self):
120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A:
121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A.register(int)
123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance(42, A)
124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance(42, (A,))
125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(int, A))
126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(int, (A,)))
127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class B(A):
128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        B.register(basestring)
130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance("", A)
131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance("", (A,))
132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(str, A))
133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(str, (A,)))
134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_registration_edge_cases(self):
136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A:
137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A.register(A)  # should pass silently
139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A1(A):
140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertRaises(RuntimeError, A1.register, A)  # cycles not allowed
142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class B(object):
143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A1.register(B)  # ok
145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A1.register(B)  # should pass silently
146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class C(A):
147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A.register(C)  # should pass silently
149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertRaises(RuntimeError, C.register, A)  # cycles not allowed
150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        C.register(B)  # ok
151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_register_non_class(self):
153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A(object):
154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertRaisesRegexp(TypeError, "Can only register classes",
156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                A.register, 4)
157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_registration_transitiveness(self):
159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A:
160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(A, A))
162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(A, (A,)))
163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class B:
164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(A, B))
166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(A, (B,)))
167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(B, A))
168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(B, (A,)))
169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class C:
170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        A.register(B)
172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class B1(B):
173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(B1, A))
175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(B1, (A,)))
176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class C1(C):
177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        B1.register(C1)
179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(C, B))
180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(C, (B,)))
181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(C, B1))
182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertFalse(issubclass(C, (B1,)))
183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(C1, A))
184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(C1, (A,)))
185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(C1, B))
186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(C1, (B,)))
187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(C1, B1))
188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(C1, (B1,)))
189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        C1.register(int)
190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class MyInt(int):
191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(MyInt, A))
193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertTrue(issubclass(MyInt, (A,)))
194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance(42, A)
195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertIsInstance(42, (A,))
196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_all_new_methods_are_called(self):
198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A:
199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class B(object):
201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            counter = 0
202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            def __new__(cls):
203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                B.counter += 1
204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return super(B, cls).__new__(cls)
205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class C(A, B):
206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            pass
207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(B.counter, 0)
208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        C()
209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(B.counter, 1)
210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_cache_leak(self):
212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # See issue #2521.
213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class A(object):
214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            __metaclass__ = abc.ABCMeta
215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            @abc.abstractmethod
216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            def f(self):
217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                pass
218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        class C(A):
219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            def f(self):
220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                A.f(self)
221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        r = weakref.ref(C)
222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Trigger cache.
223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        C().f()
224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        del C
225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        test_support.gc_collect()
226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(r(), None)
227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef test_main():
229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    test_support.run_unittest(TestABC)
230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepif __name__ == "__main__":
233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    unittest.main()
234