]> granicus.if.org Git - python/commitdiff
add support for abstract class and static methods #5867
authorBenjamin Peterson <benjamin@python.org>
Tue, 17 Aug 2010 00:52:52 +0000 (00:52 +0000)
committerBenjamin Peterson <benjamin@python.org>
Tue, 17 Aug 2010 00:52:52 +0000 (00:52 +0000)
Doc/library/abc.rst
Lib/abc.py
Lib/test/test_abc.py
Misc/NEWS

index 5e87e969b544ef9ca56f08bca0ab2df43dd3c305..319b1643c7fc37351c27268c68b9e3118b9ae67e 100644 (file)
@@ -157,6 +157,32 @@ It also provides the following decorators:
       multiple-inheritance.
 
 
+.. decorator:: abstractclassmethod(function)
+
+   A subclass of the built-in :func:`classmethod`, indicating an abstract
+   classmethod. Otherwise it is similar to :func:`abstractmethod`.
+
+   Usage::
+
+      class C(metaclass=ABCMeta):
+          @abstractclassmethod
+          def my_abstract_classmethod(cls, ...):
+              ...
+
+
+.. decorator:: abstractstaticmethod(function)
+
+   A subclass of the built-in :func:`staticmethod`, indicating an abstract
+   staticmethod. Otherwise it is similar to :func:`abstractmethod`.
+
+   Usage::
+
+      class C(metaclass=ABCMeta):
+          @abstractstaticmethod
+          def my_abstract_staticmethod(...):
+              ...
+
+
 .. function:: abstractproperty(fget=None, fset=None, fdel=None, doc=None)
 
    A subclass of the built-in :func:`property`, indicating an abstract property.
index 0f980363046034c816756759b684691b087ec4e6..a6c2dc48779d6ab339db70a21a81f56607b89856 100644 (file)
@@ -25,6 +25,46 @@ def abstractmethod(funcobj):
     return funcobj
 
 
+class abstractclassmethod(classmethod):
+    """A decorator indicating abstract classmethods.
+
+    Similar to abstractmethod.
+
+    Usage:
+
+        class C(metaclass=ABCMeta):
+            @abstractclassmethod
+            def my_abstract_classmethod(cls, ...):
+                ...
+    """
+
+    __isabstractmethod__ = True
+
+    def __init__(self, callable):
+        callable.__isabstractmethod__ = True
+        super().__init__(callable)
+
+
+class abstractstaticmethod(staticmethod):
+    """A decorator indicating abstract staticmethods.
+
+    Similar to abstractmethod.
+
+    Usage:
+
+        class C(metaclass=ABCMeta):
+            @abstractstaticmethod
+            def my_abstract_staticmethod(...):
+                ...
+    """
+
+    __isabstractmethod__ = True
+
+    def __init__(self, callable):
+        callable.__isabstractmethod__ = True
+        super().__init__(callable)
+
+
 class abstractproperty(property):
     """A decorator indicating abstract properties.
 
index a6e7062418f7a9a859c36b5d5d9fc0975d6d6d88..7fa18fb249f71094bb94b96095eee4bd81274928 100644 (file)
@@ -34,8 +34,46 @@ class TestABC(unittest.TestCase):
             def foo(self): return super().foo
         self.assertEqual(D().foo, 3)
 
+    def test_abstractclassmethod_basics(self):
+        @abc.abstractclassmethod
+        def foo(cls): pass
+        self.assertEqual(foo.__isabstractmethod__, True)
+        @classmethod
+        def bar(cls): pass
+        self.assertEqual(hasattr(bar, "__isabstractmethod__"), False)
+
+        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.assertEqual(foo.__isabstractmethod__, True)
+        @staticmethod
+        def bar(): pass
+        self.assertEqual(hasattr(bar, "__isabstractmethod__"), False)
+
+        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]:
+        for abstractthing in [abc.abstractmethod, abc.abstractproperty,
+                              abc.abstractclassmethod,
+                              abc.abstractstaticmethod]:
             class C(metaclass=abc.ABCMeta):
                 @abstractthing
                 def foo(self): pass  # abstract
index 904d0c2135ec335fd24d5bab48a0edd307d4f23c..53643de34716da1d9426e0862757243168c3f4b4 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -90,6 +90,8 @@ Extensions
 Library
 -------
 
+- Issue #5867: Add abc.abstractclassmethod and abc.abstractstaticmethod.
+
 - Issue #9605: posix.getlogin() decodes the username with file filesystem
   encoding and surrogateescape error handler. Patch written by David Watson.