ยปCore Development>Code coverage>Lib/abc.py

Python code coverage for Lib/abc.py

#countcontent
1n/a# Copyright 2007 Google, Inc. All Rights Reserved.
2n/a# Licensed to PSF under a Contributor Agreement.
3n/a
4n/a"""Abstract Base Classes (ABCs) according to PEP 3119."""
5n/a
6n/afrom _weakrefset import WeakSet
7n/a
8n/a
9n/adef abstractmethod(funcobj):
10n/a """A decorator indicating abstract methods.
11n/a
12n/a Requires that the metaclass is ABCMeta or derived from it. A
13n/a class that has a metaclass derived from ABCMeta cannot be
14n/a instantiated unless all of its abstract methods are overridden.
15n/a The abstract methods can be called using any of the normal
16n/a 'super' call mechanisms.
17n/a
18n/a Usage:
19n/a
20n/a class C(metaclass=ABCMeta):
21n/a @abstractmethod
22n/a def my_abstract_method(self, ...):
23n/a ...
24n/a """
25n/a funcobj.__isabstractmethod__ = True
26n/a return funcobj
27n/a
28n/a
29n/aclass abstractclassmethod(classmethod):
30n/a """
31n/a A decorator indicating abstract classmethods.
32n/a
33n/a Similar to abstractmethod.
34n/a
35n/a Usage:
36n/a
37n/a class C(metaclass=ABCMeta):
38n/a @abstractclassmethod
39n/a def my_abstract_classmethod(cls, ...):
40n/a ...
41n/a
42n/a 'abstractclassmethod' is deprecated. Use 'classmethod' with
43n/a 'abstractmethod' instead.
44n/a """
45n/a
46n/a __isabstractmethod__ = True
47n/a
48n/a def __init__(self, callable):
49n/a callable.__isabstractmethod__ = True
50n/a super().__init__(callable)
51n/a
52n/a
53n/aclass abstractstaticmethod(staticmethod):
54n/a """
55n/a A decorator indicating abstract staticmethods.
56n/a
57n/a Similar to abstractmethod.
58n/a
59n/a Usage:
60n/a
61n/a class C(metaclass=ABCMeta):
62n/a @abstractstaticmethod
63n/a def my_abstract_staticmethod(...):
64n/a ...
65n/a
66n/a 'abstractstaticmethod' is deprecated. Use 'staticmethod' with
67n/a 'abstractmethod' instead.
68n/a """
69n/a
70n/a __isabstractmethod__ = True
71n/a
72n/a def __init__(self, callable):
73n/a callable.__isabstractmethod__ = True
74n/a super().__init__(callable)
75n/a
76n/a
77n/aclass abstractproperty(property):
78n/a """
79n/a A decorator indicating abstract properties.
80n/a
81n/a Requires that the metaclass is ABCMeta or derived from it. A
82n/a class that has a metaclass derived from ABCMeta cannot be
83n/a instantiated unless all of its abstract properties are overridden.
84n/a The abstract properties can be called using any of the normal
85n/a 'super' call mechanisms.
86n/a
87n/a Usage:
88n/a
89n/a class C(metaclass=ABCMeta):
90n/a @abstractproperty
91n/a def my_abstract_property(self):
92n/a ...
93n/a
94n/a This defines a read-only property; you can also define a read-write
95n/a abstract property using the 'long' form of property declaration:
96n/a
97n/a class C(metaclass=ABCMeta):
98n/a def getx(self): ...
99n/a def setx(self, value): ...
100n/a x = abstractproperty(getx, setx)
101n/a
102n/a 'abstractproperty' is deprecated. Use 'property' with 'abstractmethod'
103n/a instead.
104n/a """
105n/a
106n/a __isabstractmethod__ = True
107n/a
108n/a
109n/aclass ABCMeta(type):
110n/a
111n/a """Metaclass for defining Abstract Base Classes (ABCs).
112n/a
113n/a Use this metaclass to create an ABC. An ABC can be subclassed
114n/a directly, and then acts as a mix-in class. You can also register
115n/a unrelated concrete classes (even built-in classes) and unrelated
116n/a ABCs as 'virtual subclasses' -- these and their descendants will
117n/a be considered subclasses of the registering ABC by the built-in
118n/a issubclass() function, but the registering ABC won't show up in
119n/a their MRO (Method Resolution Order) nor will method
120n/a implementations defined by the registering ABC be callable (not
121n/a even via super()).
122n/a
123n/a """
124n/a
125n/a # A global counter that is incremented each time a class is
126n/a # registered as a virtual subclass of anything. It forces the
127n/a # negative cache to be cleared before its next use.
128n/a # Note: this counter is private. Use `abc.get_cache_token()` for
129n/a # external code.
130n/a _abc_invalidation_counter = 0
131n/a
132n/a def __new__(mcls, name, bases, namespace):
133n/a cls = super().__new__(mcls, name, bases, namespace)
134n/a # Compute set of abstract method names
135n/a abstracts = {name
136n/a for name, value in namespace.items()
137n/a if getattr(value, "__isabstractmethod__", False)}
138n/a for base in bases:
139n/a for name in getattr(base, "__abstractmethods__", set()):
140n/a value = getattr(cls, name, None)
141n/a if getattr(value, "__isabstractmethod__", False):
142n/a abstracts.add(name)
143n/a cls.__abstractmethods__ = frozenset(abstracts)
144n/a # Set up inheritance registry
145n/a cls._abc_registry = WeakSet()
146n/a cls._abc_cache = WeakSet()
147n/a cls._abc_negative_cache = WeakSet()
148n/a cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
149n/a return cls
150n/a
151n/a def register(cls, subclass):
152n/a """Register a virtual subclass of an ABC.
153n/a
154n/a Returns the subclass, to allow usage as a class decorator.
155n/a """
156n/a if not isinstance(subclass, type):
157n/a raise TypeError("Can only register classes")
158n/a if issubclass(subclass, cls):
159n/a return subclass # Already a subclass
160n/a # Subtle: test for cycles *after* testing for "already a subclass";
161n/a # this means we allow X.register(X) and interpret it as a no-op.
162n/a if issubclass(cls, subclass):
163n/a # This would create a cycle, which is bad for the algorithm below
164n/a raise RuntimeError("Refusing to create an inheritance cycle")
165n/a cls._abc_registry.add(subclass)
166n/a ABCMeta._abc_invalidation_counter += 1 # Invalidate negative cache
167n/a return subclass
168n/a
169n/a def _dump_registry(cls, file=None):
170n/a """Debug helper to print the ABC registry."""
171n/a print("Class: %s.%s" % (cls.__module__, cls.__qualname__), file=file)
172n/a print("Inv.counter: %s" % ABCMeta._abc_invalidation_counter, file=file)
173n/a for name in sorted(cls.__dict__.keys()):
174n/a if name.startswith("_abc_"):
175n/a value = getattr(cls, name)
176n/a print("%s: %r" % (name, value), file=file)
177n/a
178n/a def __instancecheck__(cls, instance):
179n/a """Override for isinstance(instance, cls)."""
180n/a # Inline the cache checking
181n/a subclass = instance.__class__
182n/a if subclass in cls._abc_cache:
183n/a return True
184n/a subtype = type(instance)
185n/a if subtype is subclass:
186n/a if (cls._abc_negative_cache_version ==
187n/a ABCMeta._abc_invalidation_counter and
188n/a subclass in cls._abc_negative_cache):
189n/a return False
190n/a # Fall back to the subclass check.
191n/a return cls.__subclasscheck__(subclass)
192n/a return any(cls.__subclasscheck__(c) for c in {subclass, subtype})
193n/a
194n/a def __subclasscheck__(cls, subclass):
195n/a """Override for issubclass(subclass, cls)."""
196n/a # Check cache
197n/a if subclass in cls._abc_cache:
198n/a return True
199n/a # Check negative cache; may have to invalidate
200n/a if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
201n/a # Invalidate the negative cache
202n/a cls._abc_negative_cache = WeakSet()
203n/a cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
204n/a elif subclass in cls._abc_negative_cache:
205n/a return False
206n/a # Check the subclass hook
207n/a ok = cls.__subclasshook__(subclass)
208n/a if ok is not NotImplemented:
209n/a assert isinstance(ok, bool)
210n/a if ok:
211n/a cls._abc_cache.add(subclass)
212n/a else:
213n/a cls._abc_negative_cache.add(subclass)
214n/a return ok
215n/a # Check if it's a direct subclass
216n/a if cls in getattr(subclass, '__mro__', ()):
217n/a cls._abc_cache.add(subclass)
218n/a return True
219n/a # Check if it's a subclass of a registered class (recursive)
220n/a for rcls in cls._abc_registry:
221n/a if issubclass(subclass, rcls):
222n/a cls._abc_cache.add(subclass)
223n/a return True
224n/a # Check if it's a subclass of a subclass (recursive)
225n/a for scls in cls.__subclasses__():
226n/a if issubclass(subclass, scls):
227n/a cls._abc_cache.add(subclass)
228n/a return True
229n/a # No dice; update negative cache
230n/a cls._abc_negative_cache.add(subclass)
231n/a return False
232n/a
233n/a
234n/aclass ABC(metaclass=ABCMeta):
235n/a """Helper class that provides a standard way to create an ABC using
236n/a inheritance.
237n/a """
238n/a pass
239n/a
240n/a
241n/adef get_cache_token():
242n/a """Returns the current ABC cache token.
243n/a
244n/a The token is an opaque object (supporting equality testing) identifying the
245n/a current version of the ABC cache for virtual subclasses. The token changes
246n/a with every call to ``register()`` on any ABC.
247n/a """
248n/a return ABCMeta._abc_invalidation_counter