blob: 1cbf96a61f238f6b40f65682dedc7e2786a028b9 [file] [log] [blame]
Guido van Rossum8518bdc2007-06-14 00:03:37 +00001# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
3
4"""Abstract Base Classes (ABCs) according to PEP 3119."""
5
Raymond Hettinger93fa6082008-02-05 00:20:01 +00006from _weakrefset import WeakSet
Guido van Rossum8518bdc2007-06-14 00:03:37 +00007
Łukasz Langaeadd8cf2013-05-25 18:41:50 +02008
Guido van Rossum8518bdc2007-06-14 00:03:37 +00009def abstractmethod(funcobj):
10 """A decorator indicating abstract methods.
11
12 Requires that the metaclass is ABCMeta or derived from it. A
13 class that has a metaclass derived from ABCMeta cannot be
14 instantiated unless all of its abstract methods are overridden.
Walter Dörwald6e359bd2009-05-04 16:10:10 +000015 The abstract methods can be called using any of the normal
Guido van Rossum8518bdc2007-06-14 00:03:37 +000016 'super' call mechanisms.
17
18 Usage:
19
20 class C(metaclass=ABCMeta):
21 @abstractmethod
22 def my_abstract_method(self, ...):
23 ...
24 """
25 funcobj.__isabstractmethod__ = True
26 return funcobj
27
28
Benjamin Peterson45c257f2010-08-17 00:52:52 +000029class abstractclassmethod(classmethod):
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -050030 """
31 A decorator indicating abstract classmethods.
Benjamin Peterson45c257f2010-08-17 00:52:52 +000032
33 Similar to abstractmethod.
34
35 Usage:
36
37 class C(metaclass=ABCMeta):
38 @abstractclassmethod
39 def my_abstract_classmethod(cls, ...):
40 ...
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -050041
42 'abstractclassmethod' is deprecated. Use 'classmethod' with
43 'abstractmethod' instead.
Benjamin Peterson45c257f2010-08-17 00:52:52 +000044 """
45
46 __isabstractmethod__ = True
47
48 def __init__(self, callable):
49 callable.__isabstractmethod__ = True
50 super().__init__(callable)
51
52
53class abstractstaticmethod(staticmethod):
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -050054 """
55 A decorator indicating abstract staticmethods.
Benjamin Peterson45c257f2010-08-17 00:52:52 +000056
57 Similar to abstractmethod.
58
59 Usage:
60
61 class C(metaclass=ABCMeta):
62 @abstractstaticmethod
63 def my_abstract_staticmethod(...):
64 ...
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -050065
66 'abstractstaticmethod' is deprecated. Use 'staticmethod' with
67 'abstractmethod' instead.
Benjamin Peterson45c257f2010-08-17 00:52:52 +000068 """
69
70 __isabstractmethod__ = True
71
72 def __init__(self, callable):
73 callable.__isabstractmethod__ = True
74 super().__init__(callable)
75
76
Guido van Rossumb31339f2007-08-01 17:32:28 +000077class abstractproperty(property):
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -050078 """
79 A decorator indicating abstract properties.
Guido van Rossumb31339f2007-08-01 17:32:28 +000080
81 Requires that the metaclass is ABCMeta or derived from it. A
82 class that has a metaclass derived from ABCMeta cannot be
83 instantiated unless all of its abstract properties are overridden.
Walter Dörwald6e359bd2009-05-04 16:10:10 +000084 The abstract properties can be called using any of the normal
Guido van Rossum70d2b892007-08-01 17:52:23 +000085 'super' call mechanisms.
Guido van Rossumb31339f2007-08-01 17:32:28 +000086
87 Usage:
88
89 class C(metaclass=ABCMeta):
90 @abstractproperty
91 def my_abstract_property(self):
92 ...
93
94 This defines a read-only property; you can also define a read-write
95 abstract property using the 'long' form of property declaration:
96
97 class C(metaclass=ABCMeta):
98 def getx(self): ...
99 def setx(self, value): ...
100 x = abstractproperty(getx, setx)
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -0500101
102 'abstractproperty' is deprecated. Use 'property' with 'abstractmethod'
103 instead.
Guido van Rossumb31339f2007-08-01 17:32:28 +0000104 """
Benjamin Petersonbfebb7b2011-12-15 15:34:02 -0500105
Guido van Rossumb31339f2007-08-01 17:32:28 +0000106 __isabstractmethod__ = True
107
108
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000109class ABCMeta(type):
110
111 """Metaclass for defining Abstract Base Classes (ABCs).
112
113 Use this metaclass to create an ABC. An ABC can be subclassed
114 directly, and then acts as a mix-in class. You can also register
115 unrelated concrete classes (even built-in classes) and unrelated
116 ABCs as 'virtual subclasses' -- these and their descendants will
117 be considered subclasses of the registering ABC by the built-in
118 issubclass() function, but the registering ABC won't show up in
119 their MRO (Method Resolution Order) nor will method
120 implementations defined by the registering ABC be callable (not
121 even via super()).
122
123 """
124
125 # A global counter that is incremented each time a class is
126 # registered as a virtual subclass of anything. It forces the
127 # negative cache to be cleared before its next use.
Łukasz Langaeadd8cf2013-05-25 18:41:50 +0200128 # Note: this counter is private. Use `abc.get_cache_token()` for
129 # external code.
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000130 _abc_invalidation_counter = 0
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000131
132 def __new__(mcls, name, bases, namespace):
Guido van Rossumbb5f5902007-06-14 03:27:55 +0000133 cls = super().__new__(mcls, name, bases, namespace)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000134 # Compute set of abstract method names
135 abstracts = {name
136 for name, value in namespace.items()
137 if getattr(value, "__isabstractmethod__", False)}
138 for base in bases:
139 for name in getattr(base, "__abstractmethods__", set()):
140 value = getattr(cls, name, None)
141 if getattr(value, "__isabstractmethod__", False):
142 abstracts.add(name)
Christian Heimes9e7f1d22008-02-28 12:27:11 +0000143 cls.__abstractmethods__ = frozenset(abstracts)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000144 # Set up inheritance registry
Georg Brandl3b8cb172007-10-23 06:26:46 +0000145 cls._abc_registry = WeakSet()
146 cls._abc_cache = WeakSet()
147 cls._abc_negative_cache = WeakSet()
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000148 cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000149 return cls
150
Christian Heimes45031df2007-11-30 15:13:13 +0000151 def register(cls, subclass):
Éric Araujo6c3787c2011-02-24 18:03:10 +0000152 """Register a virtual subclass of an ABC.
153
154 Returns the subclass, to allow usage as a class decorator.
155 """
Benjamin Petersond6326642010-01-27 02:25:58 +0000156 if not isinstance(subclass, type):
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000157 raise TypeError("Can only register classes")
158 if issubclass(subclass, cls):
Éric Araujo6c3787c2011-02-24 18:03:10 +0000159 return subclass # Already a subclass
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000160 # Subtle: test for cycles *after* testing for "already a subclass";
161 # this means we allow X.register(X) and interpret it as a no-op.
162 if issubclass(cls, subclass):
163 # This would create a cycle, which is bad for the algorithm below
164 raise RuntimeError("Refusing to create an inheritance cycle")
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000165 cls._abc_registry.add(subclass)
166 ABCMeta._abc_invalidation_counter += 1 # Invalidate negative cache
Éric Araujo6c3787c2011-02-24 18:03:10 +0000167 return subclass
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000168
169 def _dump_registry(cls, file=None):
170 """Debug helper to print the ABC registry."""
Serhiy Storchaka521e5862014-07-22 15:00:37 +0300171 print("Class: %s.%s" % (cls.__module__, cls.__qualname__), file=file)
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000172 print("Inv.counter: %s" % ABCMeta._abc_invalidation_counter, file=file)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000173 for name in sorted(cls.__dict__.keys()):
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000174 if name.startswith("_abc_"):
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000175 value = getattr(cls, name)
176 print("%s: %r" % (name, value), file=file)
177
178 def __instancecheck__(cls, instance):
179 """Override for isinstance(instance, cls)."""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000180 # Inline the cache checking
181 subclass = instance.__class__
182 if subclass in cls._abc_cache:
183 return True
184 subtype = type(instance)
185 if subtype is subclass:
186 if (cls._abc_negative_cache_version ==
187 ABCMeta._abc_invalidation_counter and
188 subclass in cls._abc_negative_cache):
189 return False
190 # Fall back to the subclass check.
191 return cls.__subclasscheck__(subclass)
192 return any(cls.__subclasscheck__(c) for c in {subclass, subtype})
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000193
194 def __subclasscheck__(cls, subclass):
195 """Override for issubclass(subclass, cls)."""
196 # Check cache
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000197 if subclass in cls._abc_cache:
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000198 return True
199 # Check negative cache; may have to invalidate
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000200 if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000201 # Invalidate the negative cache
Georg Brandl3b8cb172007-10-23 06:26:46 +0000202 cls._abc_negative_cache = WeakSet()
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000203 cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
204 elif subclass in cls._abc_negative_cache:
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000205 return False
206 # Check the subclass hook
207 ok = cls.__subclasshook__(subclass)
208 if ok is not NotImplemented:
209 assert isinstance(ok, bool)
210 if ok:
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000211 cls._abc_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000212 else:
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000213 cls._abc_negative_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000214 return ok
215 # Check if it's a direct subclass
Christian Heimes043d6f62008-01-07 17:19:16 +0000216 if cls in getattr(subclass, '__mro__', ()):
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000217 cls._abc_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000218 return True
219 # Check if it's a subclass of a registered class (recursive)
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000220 for rcls in cls._abc_registry:
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000221 if issubclass(subclass, rcls):
Nick Coghlan33794a72008-09-02 10:43:28 +0000222 cls._abc_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000223 return True
224 # Check if it's a subclass of a subclass (recursive)
225 for scls in cls.__subclasses__():
226 if issubclass(subclass, scls):
Nick Coghlan33794a72008-09-02 10:43:28 +0000227 cls._abc_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000228 return True
229 # No dice; update negative cache
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000230 cls._abc_negative_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000231 return False
Andrew Svetlovb67596d2012-12-13 19:09:33 +0200232
Łukasz Langaeadd8cf2013-05-25 18:41:50 +0200233
Andrew Svetlovb67596d2012-12-13 19:09:33 +0200234class ABC(metaclass=ABCMeta):
235 """Helper class that provides a standard way to create an ABC using
236 inheritance.
237 """
238 pass
Łukasz Langaeadd8cf2013-05-25 18:41:50 +0200239
240
241def get_cache_token():
242 """Returns the current ABC cache token.
243
R David Murray3edcc782013-12-24 16:13:32 -0500244 The token is an opaque object (supporting equality testing) identifying the
245 current version of the ABC cache for virtual subclasses. The token changes
246 with every call to ``register()`` on any ABC.
Łukasz Langaeadd8cf2013-05-25 18:41:50 +0200247 """
248 return ABCMeta._abc_invalidation_counter