Skip to content

Commit fddbe68

Browse files
committed
Merge pull request #2 from JakeNarkizian/master
Add @abstractstaticmethod and @abstractclassmethod
2 parents de992b2 + c294e10 commit fddbe68

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

src/bd2k/util/objects.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,93 @@
22
from bd2k.util import sync_memoize
33

44

5+
class abstractclassmethod( classmethod ):
6+
"""
7+
This class defines a decorator that allows the decorated class to be both an abstract method
8+
and a class method.
9+
10+
Shamelessly stolen from
11+
12+
http://stackoverflow.com/questions/11217878/python-2-7-combine-abc-abstractmethod-and-classmethod
13+
14+
>>> from abc import ABCMeta
15+
16+
>>> class DemoABC:
17+
... __metaclass__ = ABCMeta
18+
...
19+
... @abstractclassmethod
20+
... def from_int(cls, n):
21+
... return cls()
22+
23+
>>> class DemoConcrete(DemoABC):
24+
... @classmethod
25+
... def from_int(cls, n):
26+
... return cls(2*n)
27+
...
28+
... def __init__(self, n):
29+
... print ('Initializing with %s' % n)
30+
31+
>>> d = DemoConcrete(5) # Succeeds by calling a concrete __init__()
32+
Initializing with 5
33+
34+
>>> d = DemoConcrete.from_int(5) # Succeeds by calling a concrete from_int()
35+
Initializing with 10
36+
37+
>>> DemoABC() # Fails because from_int() is abstract
38+
Traceback (most recent call last):
39+
...
40+
TypeError: Can't instantiate abstract class DemoABC with abstract methods from_int
41+
42+
>>> DemoABC.from_int(5) # Fails because from_int() is not implemented
43+
Traceback (most recent call last):
44+
...
45+
TypeError: Can't instantiate abstract class DemoABC with abstract methods from_int
46+
"""
47+
__isabstractmethod__ = True
48+
49+
def __init__(self, callable):
50+
callable.__isabstractmethod__ = True
51+
super(abstractclassmethod, self).__init__(callable)
52+
53+
54+
class abstractstaticmethod( staticmethod ):
55+
"""
56+
This class defines a decorator that allows the decorated class to be both an abstract method
57+
and a static method.
58+
59+
Based on code found at
60+
61+
http://stackoverflow.com/questions/11217878/python-2-7-combine-abc-abstractmethod-and-classmethod
62+
63+
>>> from abc import ABCMeta
64+
65+
>>> class DemoABC:
66+
... __metaclass__ = ABCMeta
67+
...
68+
... @abstractstaticmethod
69+
... def f(n):
70+
... raise NotImplementedError()
71+
72+
>>> class DemoConcrete(DemoABC):
73+
... @staticmethod
74+
... def f(n):
75+
... return (2*n)
76+
77+
>>> d = DemoABC.f(5) # Fails because f() is not implemented
78+
Traceback (most recent call last):
79+
...
80+
NotImplementedError
81+
82+
>>> DemoConcrete.f(5) # Succeeds by calling a concrete f()
83+
10
84+
"""
85+
__isabstractmethod__ = True
86+
87+
def __init__(self, callable):
88+
callable.__isabstractmethod__ = True
89+
super(abstractstaticmethod, self).__init__(callable)
90+
91+
592
class InnerClass( object ):
693
"""
794
Note that this is EXPERIMENTAL code.

0 commit comments

Comments
 (0)