add support for abstract class and static methods #5867
This commit is contained in:
parent
36e791179c
commit
45c257f193
|
@ -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.
|
||||
|
|
40
Lib/abc.py
40
Lib/abc.py
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue