Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 # Copyright 2007 Google, Inc. All Rights Reserved. | 1 # Copyright 2007 Google, Inc. All Rights Reserved. |
2 # Licensed to PSF under a Contributor Agreement. | 2 # Licensed to PSF under a Contributor Agreement. |
3 | 3 |
4 """Abstract Base Classes (ABCs) according to PEP 3119.""" | 4 """Abstract Base Classes (ABCs) according to PEP 3119.""" |
5 | 5 |
6 from _weakrefset import WeakSet | 6 from _weakrefset import WeakSet |
7 | 7 |
8 def abstractmethod(funcobj): | 8 def abstractmethod(funcobj): |
9 """A decorator indicating abstract methods. | 9 """A decorator indicating abstract methods. |
10 | 10 |
11 Requires that the metaclass is ABCMeta or derived from it. A | 11 Requires that the metaclass is ABCMeta or derived from it. A |
12 class that has a metaclass derived from ABCMeta cannot be | 12 class that has a metaclass derived from ABCMeta cannot be |
13 instantiated unless all of its abstract methods are overridden. | 13 instantiated unless all of its abstract methods are overridden. |
14 The abstract methods can be called using any of the normal | 14 The abstract methods can be called using any of the normal |
15 'super' call mechanisms. | 15 'super' call mechanisms. |
16 | 16 |
17 Usage: | 17 Usage: |
18 | 18 |
19 class C(metaclass=ABCMeta): | 19 class C(metaclass=ABCMeta): |
20 @abstractmethod | 20 @abstractmethod |
21 def my_abstract_method(self, ...): | 21 def my_abstract_method(self, ...): |
22 ... | 22 ... |
23 """ | 23 """ |
24 funcobj.__isabstractmethod__ = True | 24 funcobj.__isabstractmethod__ = True |
25 return funcobj | 25 return funcobj |
26 | 26 |
27 | 27 |
28 class abstractclassmethod(classmethod): | 28 class abstractclassmethod(classmethod): |
29 """A decorator indicating abstract classmethods. | 29 """ |
30 A decorator indicating abstract classmethods. | |
30 | 31 |
31 Similar to abstractmethod. | 32 Similar to abstractmethod. |
32 | 33 |
33 Usage: | 34 Usage: |
34 | 35 |
35 class C(metaclass=ABCMeta): | 36 class C(metaclass=ABCMeta): |
36 @abstractclassmethod | 37 @abstractclassmethod |
37 def my_abstract_classmethod(cls, ...): | 38 def my_abstract_classmethod(cls, ...): |
38 ... | 39 ... |
40 | |
41 'abstractclassmethod' is deprecated. Use 'classmethod' with | |
42 'abstractmethod' instead. | |
39 """ | 43 """ |
40 | 44 |
41 __isabstractmethod__ = True | 45 __isabstractmethod__ = True |
42 | 46 |
43 def __init__(self, callable): | 47 def __init__(self, callable): |
44 callable.__isabstractmethod__ = True | 48 callable.__isabstractmethod__ = True |
45 super().__init__(callable) | 49 super().__init__(callable) |
46 | 50 |
47 | 51 |
48 class abstractstaticmethod(staticmethod): | 52 class abstractstaticmethod(staticmethod): |
49 """A decorator indicating abstract staticmethods. | 53 """ |
54 A decorator indicating abstract staticmethods. | |
50 | 55 |
51 Similar to abstractmethod. | 56 Similar to abstractmethod. |
52 | 57 |
53 Usage: | 58 Usage: |
54 | 59 |
55 class C(metaclass=ABCMeta): | 60 class C(metaclass=ABCMeta): |
56 @abstractstaticmethod | 61 @abstractstaticmethod |
57 def my_abstract_staticmethod(...): | 62 def my_abstract_staticmethod(...): |
58 ... | 63 ... |
64 | |
65 'abstractstaticmethod' is deprecated. Use 'staticmethod' with | |
66 'abstractmethod' instead. | |
59 """ | 67 """ |
60 | 68 |
61 __isabstractmethod__ = True | 69 __isabstractmethod__ = True |
62 | 70 |
63 def __init__(self, callable): | 71 def __init__(self, callable): |
64 callable.__isabstractmethod__ = True | 72 callable.__isabstractmethod__ = True |
65 super().__init__(callable) | 73 super().__init__(callable) |
66 | 74 |
67 | 75 |
68 class abstractproperty(property): | 76 class abstractproperty(property): |
69 """A decorator indicating abstract properties. | 77 """ |
78 A decorator indicating abstract properties. | |
70 | 79 |
71 Requires that the metaclass is ABCMeta or derived from it. A | 80 Requires that the metaclass is ABCMeta or derived from it. A |
72 class that has a metaclass derived from ABCMeta cannot be | 81 class that has a metaclass derived from ABCMeta cannot be |
73 instantiated unless all of its abstract properties are overridden. | 82 instantiated unless all of its abstract properties are overridden. |
74 The abstract properties can be called using any of the normal | 83 The abstract properties can be called using any of the normal |
75 'super' call mechanisms. | 84 'super' call mechanisms. |
76 | 85 |
77 Usage: | 86 Usage: |
78 | 87 |
79 class C(metaclass=ABCMeta): | 88 class C(metaclass=ABCMeta): |
80 @abstractproperty | 89 @abstractproperty |
81 def my_abstract_property(self): | 90 def my_abstract_property(self): |
82 ... | 91 ... |
83 | 92 |
84 This defines a read-only property; you can also define a read-write | 93 This defines a read-only property; you can also define a read-write |
85 abstract property using the 'long' form of property declaration: | 94 abstract property using the 'long' form of property declaration: |
86 | 95 |
87 class C(metaclass=ABCMeta): | 96 class C(metaclass=ABCMeta): |
88 def getx(self): ... | 97 def getx(self): ... |
89 def setx(self, value): ... | 98 def setx(self, value): ... |
90 x = abstractproperty(getx, setx) | 99 x = abstractproperty(getx, setx) |
91 """ | 100 |
92 warnings.warn( | 101 'abstractproperty' is deprecated. Use 'property' with 'abstractmethod' |
durban
2011/03/19 21:36:09
warnings is not imported. Also if you put the war
dsdale24
2011/03/19 22:13:42
Good point.
| |
93 "abstractproperty will be removed in future versions. " | 102 instead. |
94 "Use 'property' in conjunction with 'abstractmethod' instead.", | 103 """ |
95 DeprecationWarning, stacklevel=2 | 104 |
96 ) | |
97 __isabstractmethod__ = True | 105 __isabstractmethod__ = True |
98 | 106 |
99 | 107 |
100 class ABCMeta(type): | 108 class ABCMeta(type): |
101 | 109 |
102 """Metaclass for defining Abstract Base Classes (ABCs). | 110 """Metaclass for defining Abstract Base Classes (ABCs). |
103 | 111 |
104 Use this metaclass to create an ABC. An ABC can be subclassed | 112 Use this metaclass to create an ABC. An ABC can be subclassed |
105 directly, and then acts as a mix-in class. You can also register | 113 directly, and then acts as a mix-in class. You can also register |
106 unrelated concrete classes (even built-in classes) and unrelated | 114 unrelated concrete classes (even built-in classes) and unrelated |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 cls._abc_cache.add(subclass) | 219 cls._abc_cache.add(subclass) |
212 return True | 220 return True |
213 # Check if it's a subclass of a subclass (recursive) | 221 # Check if it's a subclass of a subclass (recursive) |
214 for scls in cls.__subclasses__(): | 222 for scls in cls.__subclasses__(): |
215 if issubclass(subclass, scls): | 223 if issubclass(subclass, scls): |
216 cls._abc_cache.add(subclass) | 224 cls._abc_cache.add(subclass) |
217 return True | 225 return True |
218 # No dice; update negative cache | 226 # No dice; update negative cache |
219 cls._abc_negative_cache.add(subclass) | 227 cls._abc_negative_cache.add(subclass) |
220 return False | 228 return False |
LEFT | RIGHT |