summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_abc.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_abc.py')
-rw-r--r--Lib/test/test_abc.py153
1 files changed, 85 insertions, 68 deletions
diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py
index 6a8c3a1..d86f97c 100644
--- a/Lib/test/test_abc.py
+++ b/Lib/test/test_abc.py
@@ -3,8 +3,8 @@
"""Unit tests for abc.py."""
-import unittest, weakref
-from test import test_support
+import unittest
+from test import support
import abc
from inspect import isabstract
@@ -26,28 +26,64 @@ class TestABC(unittest.TestCase):
def bar(self): pass
self.assertFalse(hasattr(bar, "__isabstractmethod__"))
- class C:
- __metaclass__ = abc.ABCMeta
+ class C(metaclass=abc.ABCMeta):
@abc.abstractproperty
def foo(self): return 3
class D(C):
@property
- def foo(self): return super(D, self).foo
+ def foo(self): return super().foo
self.assertEqual(D().foo, 3)
+ def test_abstractclassmethod_basics(self):
+ @abc.abstractclassmethod
+ def foo(cls): pass
+ self.assertTrue(foo.__isabstractmethod__)
+ @classmethod
+ def bar(cls): pass
+ self.assertFalse(hasattr(bar, "__isabstractmethod__"))
+
+ class C(metaclass=abc.ABCMeta):
+ @abc.abstractclassmethod
+ def foo(cls): return cls.__name__
+ self.assertRaises(TypeError, C)
+ class D(C):
+ @classmethod
+ def foo(cls): return super().foo()
+ self.assertEqual(D.foo(), 'D')
+ self.assertEqual(D().foo(), 'D')
+
+ def test_abstractstaticmethod_basics(self):
+ @abc.abstractstaticmethod
+ def foo(): pass
+ self.assertTrue(foo.__isabstractmethod__)
+ @staticmethod
+ def bar(): pass
+ self.assertFalse(hasattr(bar, "__isabstractmethod__"))
+
+ class C(metaclass=abc.ABCMeta):
+ @abc.abstractstaticmethod
+ def foo(): return 3
+ self.assertRaises(TypeError, C)
+ class D(C):
+ @staticmethod
+ def foo(): return 4
+ self.assertEqual(D.foo(), 4)
+ self.assertEqual(D().foo(), 4)
+
def test_abstractmethod_integration(self):
- for abstractthing in [abc.abstractmethod, abc.abstractproperty]:
- class C:
- __metaclass__ = abc.ABCMeta
+ for abstractthing in [abc.abstractmethod, abc.abstractproperty,
+ abc.abstractclassmethod,
+ abc.abstractstaticmethod]:
+ class C(metaclass=abc.ABCMeta):
@abstractthing
def foo(self): pass # abstract
def bar(self): pass # concrete
- self.assertEqual(C.__abstractmethods__, set(["foo"]))
+ self.assertEqual(C.__abstractmethods__, {"foo"})
self.assertRaises(TypeError, C) # because foo is abstract
self.assertTrue(isabstract(C))
class D(C):
def bar(self): pass # concrete override of concrete
- self.assertEqual(D.__abstractmethods__, set(["foo"]))
+ self.assertEqual(D.__abstractmethods__, {"foo"})
self.assertRaises(TypeError, D) # because foo is still abstract
self.assertTrue(isabstract(D))
class E(D):
@@ -58,32 +94,26 @@ class TestABC(unittest.TestCase):
class F(E):
@abstractthing
def bar(self): pass # abstract override of concrete
- self.assertEqual(F.__abstractmethods__, set(["bar"]))
+ self.assertEqual(F.__abstractmethods__, {"bar"})
self.assertRaises(TypeError, F) # because bar is abstract now
self.assertTrue(isabstract(F))
- def test_subclass_oldstyle_class(self):
- class A:
- __metaclass__ = abc.ABCMeta
- class OldstyleClass:
- pass
- self.assertFalse(issubclass(OldstyleClass, A))
- self.assertFalse(issubclass(A, OldstyleClass))
-
- def test_isinstance_class(self):
- class A:
- __metaclass__ = abc.ABCMeta
- class OldstyleClass:
+ def test_metaclass_abc(self):
+ # Metaclasses can be ABCs, too.
+ class A(metaclass=abc.ABCMeta):
+ @abc.abstractmethod
+ def x(self):
+ pass
+ self.assertEqual(A.__abstractmethods__, {"x"})
+ class meta(type, A):
+ def x(self):
+ return 1
+ class C(metaclass=meta):
pass
- self.assertFalse(isinstance(OldstyleClass, A))
- self.assertTrue(isinstance(OldstyleClass, type(OldstyleClass)))
- self.assertFalse(isinstance(A, OldstyleClass))
- # This raises a recursion depth error, but is low-priority:
- # self.assertTrue(isinstance(A, abc.ABCMeta))
def test_registration_basics(self):
- class A:
- __metaclass__ = abc.ABCMeta
+ class A(metaclass=abc.ABCMeta):
+ pass
class B(object):
pass
b = B()
@@ -105,9 +135,9 @@ class TestABC(unittest.TestCase):
self.assertIsInstance(c, (A,))
def test_isinstance_invalidation(self):
- class A:
- __metaclass__ = abc.ABCMeta
- class B(object):
+ class A(metaclass=abc.ABCMeta):
+ pass
+ class B:
pass
b = B()
self.assertFalse(isinstance(b, A))
@@ -117,8 +147,8 @@ class TestABC(unittest.TestCase):
self.assertTrue(isinstance(b, (A,)))
def test_registration_builtins(self):
- class A:
- __metaclass__ = abc.ABCMeta
+ class A(metaclass=abc.ABCMeta):
+ pass
A.register(int)
self.assertIsInstance(42, A)
self.assertIsInstance(42, (A,))
@@ -126,15 +156,18 @@ class TestABC(unittest.TestCase):
self.assertTrue(issubclass(int, (A,)))
class B(A):
pass
- B.register(basestring)
+ B.register(str)
+ class C(str): pass
self.assertIsInstance("", A)
self.assertIsInstance("", (A,))
self.assertTrue(issubclass(str, A))
self.assertTrue(issubclass(str, (A,)))
+ self.assertTrue(issubclass(C, A))
+ self.assertTrue(issubclass(C, (A,)))
def test_registration_edge_cases(self):
- class A:
- __metaclass__ = abc.ABCMeta
+ class A(metaclass=abc.ABCMeta):
+ pass
A.register(A) # should pass silently
class A1(A):
pass
@@ -150,24 +183,24 @@ class TestABC(unittest.TestCase):
C.register(B) # ok
def test_register_non_class(self):
- class A(object):
- __metaclass__ = abc.ABCMeta
- self.assertRaisesRegexp(TypeError, "Can only register classes",
- A.register, 4)
+ class A(metaclass=abc.ABCMeta):
+ pass
+ self.assertRaisesRegex(TypeError, "Can only register classes",
+ A.register, 4)
def test_registration_transitiveness(self):
- class A:
- __metaclass__ = abc.ABCMeta
+ class A(metaclass=abc.ABCMeta):
+ pass
self.assertTrue(issubclass(A, A))
self.assertTrue(issubclass(A, (A,)))
- class B:
- __metaclass__ = abc.ABCMeta
+ class B(metaclass=abc.ABCMeta):
+ pass
self.assertFalse(issubclass(A, B))
self.assertFalse(issubclass(A, (B,)))
self.assertFalse(issubclass(B, A))
self.assertFalse(issubclass(B, (A,)))
- class C:
- __metaclass__ = abc.ABCMeta
+ class C(metaclass=abc.ABCMeta):
+ pass
A.register(B)
class B1(B):
pass
@@ -195,38 +228,22 @@ class TestABC(unittest.TestCase):
self.assertIsInstance(42, (A,))
def test_all_new_methods_are_called(self):
- class A:
- __metaclass__ = abc.ABCMeta
+ class A(metaclass=abc.ABCMeta):
+ pass
class B(object):
counter = 0
def __new__(cls):
B.counter += 1
- return super(B, cls).__new__(cls)
+ return super().__new__(cls)
class C(A, B):
pass
self.assertEqual(B.counter, 0)
C()
self.assertEqual(B.counter, 1)
- def test_cache_leak(self):
- # See issue #2521.
- class A(object):
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def f(self):
- pass
- class C(A):
- def f(self):
- A.f(self)
- r = weakref.ref(C)
- # Trigger cache.
- C().f()
- del C
- test_support.gc_collect()
- self.assertEqual(r(), None)
def test_main():
- test_support.run_unittest(TestABC)
+ support.run_unittest(TestABC)
if __name__ == "__main__":