add support for abstract class and static methods #5867

This commit is contained in:
Benjamin Peterson 2010-08-17 00:52:52 +00:00
parent 36e791179c
commit 45c257f193
4 changed files with 107 additions and 1 deletions

View 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.

View 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.

View 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

View File

@ -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.