blob: 9bdc36dce65eab515c121ec0bee64adbc83060c6 [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
Natebd583ef2017-03-15 11:39:22 -0700132 def __new__(mcls, name, bases, namespace, **kwargs):
133 cls = super().__new__(mcls, name, bases, namespace, **kwargs)
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)
yahya-abou-imranae12f5d2018-01-12 10:18:44 +0100173 for name in cls.__dict__:
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)
yahya-abou-imranae12f5d2018-01-12 10:18:44 +0100176 if isinstance(value, WeakSet):
177 value = set(value)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000178 print("%s: %r" % (name, value), file=file)
179
180 def __instancecheck__(cls, instance):
181 """Override for isinstance(instance, cls)."""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000182 # Inline the cache checking
183 subclass = instance.__class__
184 if subclass in cls._abc_cache:
185 return True
186 subtype = type(instance)
187 if subtype is subclass:
188 if (cls._abc_negative_cache_version ==
189 ABCMeta._abc_invalidation_counter and
190 subclass in cls._abc_negative_cache):
191 return False
192 # Fall back to the subclass check.
193 return cls.__subclasscheck__(subclass)
194 return any(cls.__subclasscheck__(c) for c in {subclass, subtype})
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000195
196 def __subclasscheck__(cls, subclass):
197 """Override for issubclass(subclass, cls)."""
198 # Check cache
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000199 if subclass in cls._abc_cache:
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000200 return True
201 # Check negative cache; may have to invalidate
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000202 if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000203 # Invalidate the negative cache
Georg Brandl3b8cb172007-10-23 06:26:46 +0000204 cls._abc_negative_cache = WeakSet()
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000205 cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
206 elif subclass in cls._abc_negative_cache:
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000207 return False
208 # Check the subclass hook
209 ok = cls.__subclasshook__(subclass)
210 if ok is not NotImplemented:
211 assert isinstance(ok, bool)
212 if ok:
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000213 cls._abc_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000214 else:
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000215 cls._abc_negative_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000216 return ok
217 # Check if it's a direct subclass
Christian Heimes043d6f62008-01-07 17:19:16 +0000218 if cls in getattr(subclass, '__mro__', ()):
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000219 cls._abc_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000220 return True
221 # Check if it's a subclass of a registered class (recursive)
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000222 for rcls in cls._abc_registry:
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000223 if issubclass(subclass, rcls):
Nick Coghlan33794a72008-09-02 10:43:28 +0000224 cls._abc_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000225 return True
226 # Check if it's a subclass of a subclass (recursive)
227 for scls in cls.__subclasses__():
228 if issubclass(subclass, scls):
Nick Coghlan33794a72008-09-02 10:43:28 +0000229 cls._abc_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000230 return True
231 # No dice; update negative cache
Guido van Rossumc1e315d2007-08-20 19:29:24 +0000232 cls._abc_negative_cache.add(subclass)
Guido van Rossum8518bdc2007-06-14 00:03:37 +0000233 return False
Andrew Svetlovb67596d2012-12-13 19:09:33 +0200234
Łukasz Langaeadd8cf2013-05-25 18:41:50 +0200235
Andrew Svetlovb67596d2012-12-13 19:09:33 +0200236class ABC(metaclass=ABCMeta):
237 """Helper class that provides a standard way to create an ABC using
238 inheritance.
239 """
Aaron Hall, MBAff487392017-06-06 15:34:57 -0400240 __slots__ = ()
Łukasz Langaeadd8cf2013-05-25 18:41:50 +0200241
242
243def get_cache_token():
244 """Returns the current ABC cache token.
245
R David Murray3edcc782013-12-24 16:13:32 -0500246 The token is an opaque object (supporting equality testing) identifying the
247 current version of the ABC cache for virtual subclasses. The token changes
248 with every call to ``register()`` on any ABC.
Łukasz Langaeadd8cf2013-05-25 18:41:50 +0200249 """
250 return ABCMeta._abc_invalidation_counter