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