test_abc.py 7.5 KB

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