mirror of
https://github.com/python/cpython.git
synced 2025-11-02 11:08:57 +00:00
add support for abstract class and static methods #5867
This commit is contained in:
parent
36e791179c
commit
45c257f193
4 changed files with 107 additions and 1 deletions
|
|
@ -157,6 +157,32 @@ It also provides the following decorators:
|
||||||
multiple-inheritance.
|
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)
|
.. function:: abstractproperty(fget=None, fset=None, fdel=None, doc=None)
|
||||||
|
|
||||||
A subclass of the built-in :func:`property`, indicating an abstract property.
|
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
|
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):
|
class abstractproperty(property):
|
||||||
"""A decorator indicating abstract properties.
|
"""A decorator indicating abstract properties.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,46 @@ class TestABC(unittest.TestCase):
|
||||||
def foo(self): return super().foo
|
def foo(self): return super().foo
|
||||||
self.assertEqual(D().foo, 3)
|
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):
|
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):
|
class C(metaclass=abc.ABCMeta):
|
||||||
@abstractthing
|
@abstractthing
|
||||||
def foo(self): pass # abstract
|
def foo(self): pass # abstract
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,8 @@ Extensions
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #5867: Add abc.abstractclassmethod and abc.abstractstaticmethod.
|
||||||
|
|
||||||
- Issue #9605: posix.getlogin() decodes the username with file filesystem
|
- Issue #9605: posix.getlogin() decodes the username with file filesystem
|
||||||
encoding and surrogateescape error handler. Patch written by David Watson.
|
encoding and surrogateescape error handler. Patch written by David Watson.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue