xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/abc.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker# Copyright 2007 Google, Inc. All Rights Reserved.
2*cda5da8dSAndroid Build Coastguard Worker# Licensed to PSF under a Contributor Agreement.
3*cda5da8dSAndroid Build Coastguard Worker
4*cda5da8dSAndroid Build Coastguard Worker"""Abstract Base Classes (ABCs) according to PEP 3119."""
5*cda5da8dSAndroid Build Coastguard Worker
6*cda5da8dSAndroid Build Coastguard Worker
7*cda5da8dSAndroid Build Coastguard Workerdef abstractmethod(funcobj):
8*cda5da8dSAndroid Build Coastguard Worker    """A decorator indicating abstract methods.
9*cda5da8dSAndroid Build Coastguard Worker
10*cda5da8dSAndroid Build Coastguard Worker    Requires that the metaclass is ABCMeta or derived from it.  A
11*cda5da8dSAndroid Build Coastguard Worker    class that has a metaclass derived from ABCMeta cannot be
12*cda5da8dSAndroid Build Coastguard Worker    instantiated unless all of its abstract methods are overridden.
13*cda5da8dSAndroid Build Coastguard Worker    The abstract methods can be called using any of the normal
14*cda5da8dSAndroid Build Coastguard Worker    'super' call mechanisms.  abstractmethod() may be used to declare
15*cda5da8dSAndroid Build Coastguard Worker    abstract methods for properties and descriptors.
16*cda5da8dSAndroid Build Coastguard Worker
17*cda5da8dSAndroid Build Coastguard Worker    Usage:
18*cda5da8dSAndroid Build Coastguard Worker
19*cda5da8dSAndroid Build Coastguard Worker        class C(metaclass=ABCMeta):
20*cda5da8dSAndroid Build Coastguard Worker            @abstractmethod
21*cda5da8dSAndroid Build Coastguard Worker            def my_abstract_method(self, arg1, arg2, argN):
22*cda5da8dSAndroid Build Coastguard Worker                ...
23*cda5da8dSAndroid Build Coastguard Worker    """
24*cda5da8dSAndroid Build Coastguard Worker    funcobj.__isabstractmethod__ = True
25*cda5da8dSAndroid Build Coastguard Worker    return funcobj
26*cda5da8dSAndroid Build Coastguard Worker
27*cda5da8dSAndroid Build Coastguard Worker
28*cda5da8dSAndroid Build Coastguard Workerclass abstractclassmethod(classmethod):
29*cda5da8dSAndroid Build Coastguard Worker    """A decorator indicating abstract classmethods.
30*cda5da8dSAndroid Build Coastguard Worker
31*cda5da8dSAndroid Build Coastguard Worker    Deprecated, use 'classmethod' with 'abstractmethod' instead:
32*cda5da8dSAndroid Build Coastguard Worker
33*cda5da8dSAndroid Build Coastguard Worker        class C(ABC):
34*cda5da8dSAndroid Build Coastguard Worker            @classmethod
35*cda5da8dSAndroid Build Coastguard Worker            @abstractmethod
36*cda5da8dSAndroid Build Coastguard Worker            def my_abstract_classmethod(cls, ...):
37*cda5da8dSAndroid Build Coastguard Worker                ...
38*cda5da8dSAndroid Build Coastguard Worker
39*cda5da8dSAndroid Build Coastguard Worker    """
40*cda5da8dSAndroid Build Coastguard Worker
41*cda5da8dSAndroid Build Coastguard Worker    __isabstractmethod__ = True
42*cda5da8dSAndroid Build Coastguard Worker
43*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, callable):
44*cda5da8dSAndroid Build Coastguard Worker        callable.__isabstractmethod__ = True
45*cda5da8dSAndroid Build Coastguard Worker        super().__init__(callable)
46*cda5da8dSAndroid Build Coastguard Worker
47*cda5da8dSAndroid Build Coastguard Worker
48*cda5da8dSAndroid Build Coastguard Workerclass abstractstaticmethod(staticmethod):
49*cda5da8dSAndroid Build Coastguard Worker    """A decorator indicating abstract staticmethods.
50*cda5da8dSAndroid Build Coastguard Worker
51*cda5da8dSAndroid Build Coastguard Worker    Deprecated, use 'staticmethod' with 'abstractmethod' instead:
52*cda5da8dSAndroid Build Coastguard Worker
53*cda5da8dSAndroid Build Coastguard Worker        class C(ABC):
54*cda5da8dSAndroid Build Coastguard Worker            @staticmethod
55*cda5da8dSAndroid Build Coastguard Worker            @abstractmethod
56*cda5da8dSAndroid Build Coastguard Worker            def my_abstract_staticmethod(...):
57*cda5da8dSAndroid Build Coastguard Worker                ...
58*cda5da8dSAndroid Build Coastguard Worker
59*cda5da8dSAndroid Build Coastguard Worker    """
60*cda5da8dSAndroid Build Coastguard Worker
61*cda5da8dSAndroid Build Coastguard Worker    __isabstractmethod__ = True
62*cda5da8dSAndroid Build Coastguard Worker
63*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, callable):
64*cda5da8dSAndroid Build Coastguard Worker        callable.__isabstractmethod__ = True
65*cda5da8dSAndroid Build Coastguard Worker        super().__init__(callable)
66*cda5da8dSAndroid Build Coastguard Worker
67*cda5da8dSAndroid Build Coastguard Worker
68*cda5da8dSAndroid Build Coastguard Workerclass abstractproperty(property):
69*cda5da8dSAndroid Build Coastguard Worker    """A decorator indicating abstract properties.
70*cda5da8dSAndroid Build Coastguard Worker
71*cda5da8dSAndroid Build Coastguard Worker    Deprecated, use 'property' with 'abstractmethod' instead:
72*cda5da8dSAndroid Build Coastguard Worker
73*cda5da8dSAndroid Build Coastguard Worker        class C(ABC):
74*cda5da8dSAndroid Build Coastguard Worker            @property
75*cda5da8dSAndroid Build Coastguard Worker            @abstractmethod
76*cda5da8dSAndroid Build Coastguard Worker            def my_abstract_property(self):
77*cda5da8dSAndroid Build Coastguard Worker                ...
78*cda5da8dSAndroid Build Coastguard Worker
79*cda5da8dSAndroid Build Coastguard Worker    """
80*cda5da8dSAndroid Build Coastguard Worker
81*cda5da8dSAndroid Build Coastguard Worker    __isabstractmethod__ = True
82*cda5da8dSAndroid Build Coastguard Worker
83*cda5da8dSAndroid Build Coastguard Worker
84*cda5da8dSAndroid Build Coastguard Workertry:
85*cda5da8dSAndroid Build Coastguard Worker    from _abc import (get_cache_token, _abc_init, _abc_register,
86*cda5da8dSAndroid Build Coastguard Worker                      _abc_instancecheck, _abc_subclasscheck, _get_dump,
87*cda5da8dSAndroid Build Coastguard Worker                      _reset_registry, _reset_caches)
88*cda5da8dSAndroid Build Coastguard Workerexcept ImportError:
89*cda5da8dSAndroid Build Coastguard Worker    from _py_abc import ABCMeta, get_cache_token
90*cda5da8dSAndroid Build Coastguard Worker    ABCMeta.__module__ = 'abc'
91*cda5da8dSAndroid Build Coastguard Workerelse:
92*cda5da8dSAndroid Build Coastguard Worker    class ABCMeta(type):
93*cda5da8dSAndroid Build Coastguard Worker        """Metaclass for defining Abstract Base Classes (ABCs).
94*cda5da8dSAndroid Build Coastguard Worker
95*cda5da8dSAndroid Build Coastguard Worker        Use this metaclass to create an ABC.  An ABC can be subclassed
96*cda5da8dSAndroid Build Coastguard Worker        directly, and then acts as a mix-in class.  You can also register
97*cda5da8dSAndroid Build Coastguard Worker        unrelated concrete classes (even built-in classes) and unrelated
98*cda5da8dSAndroid Build Coastguard Worker        ABCs as 'virtual subclasses' -- these and their descendants will
99*cda5da8dSAndroid Build Coastguard Worker        be considered subclasses of the registering ABC by the built-in
100*cda5da8dSAndroid Build Coastguard Worker        issubclass() function, but the registering ABC won't show up in
101*cda5da8dSAndroid Build Coastguard Worker        their MRO (Method Resolution Order) nor will method
102*cda5da8dSAndroid Build Coastguard Worker        implementations defined by the registering ABC be callable (not
103*cda5da8dSAndroid Build Coastguard Worker        even via super()).
104*cda5da8dSAndroid Build Coastguard Worker        """
105*cda5da8dSAndroid Build Coastguard Worker        def __new__(mcls, name, bases, namespace, /, **kwargs):
106*cda5da8dSAndroid Build Coastguard Worker            cls = super().__new__(mcls, name, bases, namespace, **kwargs)
107*cda5da8dSAndroid Build Coastguard Worker            _abc_init(cls)
108*cda5da8dSAndroid Build Coastguard Worker            return cls
109*cda5da8dSAndroid Build Coastguard Worker
110*cda5da8dSAndroid Build Coastguard Worker        def register(cls, subclass):
111*cda5da8dSAndroid Build Coastguard Worker            """Register a virtual subclass of an ABC.
112*cda5da8dSAndroid Build Coastguard Worker
113*cda5da8dSAndroid Build Coastguard Worker            Returns the subclass, to allow usage as a class decorator.
114*cda5da8dSAndroid Build Coastguard Worker            """
115*cda5da8dSAndroid Build Coastguard Worker            return _abc_register(cls, subclass)
116*cda5da8dSAndroid Build Coastguard Worker
117*cda5da8dSAndroid Build Coastguard Worker        def __instancecheck__(cls, instance):
118*cda5da8dSAndroid Build Coastguard Worker            """Override for isinstance(instance, cls)."""
119*cda5da8dSAndroid Build Coastguard Worker            return _abc_instancecheck(cls, instance)
120*cda5da8dSAndroid Build Coastguard Worker
121*cda5da8dSAndroid Build Coastguard Worker        def __subclasscheck__(cls, subclass):
122*cda5da8dSAndroid Build Coastguard Worker            """Override for issubclass(subclass, cls)."""
123*cda5da8dSAndroid Build Coastguard Worker            return _abc_subclasscheck(cls, subclass)
124*cda5da8dSAndroid Build Coastguard Worker
125*cda5da8dSAndroid Build Coastguard Worker        def _dump_registry(cls, file=None):
126*cda5da8dSAndroid Build Coastguard Worker            """Debug helper to print the ABC registry."""
127*cda5da8dSAndroid Build Coastguard Worker            print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
128*cda5da8dSAndroid Build Coastguard Worker            print(f"Inv. counter: {get_cache_token()}", file=file)
129*cda5da8dSAndroid Build Coastguard Worker            (_abc_registry, _abc_cache, _abc_negative_cache,
130*cda5da8dSAndroid Build Coastguard Worker             _abc_negative_cache_version) = _get_dump(cls)
131*cda5da8dSAndroid Build Coastguard Worker            print(f"_abc_registry: {_abc_registry!r}", file=file)
132*cda5da8dSAndroid Build Coastguard Worker            print(f"_abc_cache: {_abc_cache!r}", file=file)
133*cda5da8dSAndroid Build Coastguard Worker            print(f"_abc_negative_cache: {_abc_negative_cache!r}", file=file)
134*cda5da8dSAndroid Build Coastguard Worker            print(f"_abc_negative_cache_version: {_abc_negative_cache_version!r}",
135*cda5da8dSAndroid Build Coastguard Worker                  file=file)
136*cda5da8dSAndroid Build Coastguard Worker
137*cda5da8dSAndroid Build Coastguard Worker        def _abc_registry_clear(cls):
138*cda5da8dSAndroid Build Coastguard Worker            """Clear the registry (for debugging or testing)."""
139*cda5da8dSAndroid Build Coastguard Worker            _reset_registry(cls)
140*cda5da8dSAndroid Build Coastguard Worker
141*cda5da8dSAndroid Build Coastguard Worker        def _abc_caches_clear(cls):
142*cda5da8dSAndroid Build Coastguard Worker            """Clear the caches (for debugging or testing)."""
143*cda5da8dSAndroid Build Coastguard Worker            _reset_caches(cls)
144*cda5da8dSAndroid Build Coastguard Worker
145*cda5da8dSAndroid Build Coastguard Worker
146*cda5da8dSAndroid Build Coastguard Workerdef update_abstractmethods(cls):
147*cda5da8dSAndroid Build Coastguard Worker    """Recalculate the set of abstract methods of an abstract class.
148*cda5da8dSAndroid Build Coastguard Worker
149*cda5da8dSAndroid Build Coastguard Worker    If a class has had one of its abstract methods implemented after the
150*cda5da8dSAndroid Build Coastguard Worker    class was created, the method will not be considered implemented until
151*cda5da8dSAndroid Build Coastguard Worker    this function is called. Alternatively, if a new abstract method has been
152*cda5da8dSAndroid Build Coastguard Worker    added to the class, it will only be considered an abstract method of the
153*cda5da8dSAndroid Build Coastguard Worker    class after this function is called.
154*cda5da8dSAndroid Build Coastguard Worker
155*cda5da8dSAndroid Build Coastguard Worker    This function should be called before any use is made of the class,
156*cda5da8dSAndroid Build Coastguard Worker    usually in class decorators that add methods to the subject class.
157*cda5da8dSAndroid Build Coastguard Worker
158*cda5da8dSAndroid Build Coastguard Worker    Returns cls, to allow usage as a class decorator.
159*cda5da8dSAndroid Build Coastguard Worker
160*cda5da8dSAndroid Build Coastguard Worker    If cls is not an instance of ABCMeta, does nothing.
161*cda5da8dSAndroid Build Coastguard Worker    """
162*cda5da8dSAndroid Build Coastguard Worker    if not hasattr(cls, '__abstractmethods__'):
163*cda5da8dSAndroid Build Coastguard Worker        # We check for __abstractmethods__ here because cls might by a C
164*cda5da8dSAndroid Build Coastguard Worker        # implementation or a python implementation (especially during
165*cda5da8dSAndroid Build Coastguard Worker        # testing), and we want to handle both cases.
166*cda5da8dSAndroid Build Coastguard Worker        return cls
167*cda5da8dSAndroid Build Coastguard Worker
168*cda5da8dSAndroid Build Coastguard Worker    abstracts = set()
169*cda5da8dSAndroid Build Coastguard Worker    # Check the existing abstract methods of the parents, keep only the ones
170*cda5da8dSAndroid Build Coastguard Worker    # that are not implemented.
171*cda5da8dSAndroid Build Coastguard Worker    for scls in cls.__bases__:
172*cda5da8dSAndroid Build Coastguard Worker        for name in getattr(scls, '__abstractmethods__', ()):
173*cda5da8dSAndroid Build Coastguard Worker            value = getattr(cls, name, None)
174*cda5da8dSAndroid Build Coastguard Worker            if getattr(value, "__isabstractmethod__", False):
175*cda5da8dSAndroid Build Coastguard Worker                abstracts.add(name)
176*cda5da8dSAndroid Build Coastguard Worker    # Also add any other newly added abstract methods.
177*cda5da8dSAndroid Build Coastguard Worker    for name, value in cls.__dict__.items():
178*cda5da8dSAndroid Build Coastguard Worker        if getattr(value, "__isabstractmethod__", False):
179*cda5da8dSAndroid Build Coastguard Worker            abstracts.add(name)
180*cda5da8dSAndroid Build Coastguard Worker    cls.__abstractmethods__ = frozenset(abstracts)
181*cda5da8dSAndroid Build Coastguard Worker    return cls
182*cda5da8dSAndroid Build Coastguard Worker
183*cda5da8dSAndroid Build Coastguard Worker
184*cda5da8dSAndroid Build Coastguard Workerclass ABC(metaclass=ABCMeta):
185*cda5da8dSAndroid Build Coastguard Worker    """Helper class that provides a standard way to create an ABC using
186*cda5da8dSAndroid Build Coastguard Worker    inheritance.
187*cda5da8dSAndroid Build Coastguard Worker    """
188*cda5da8dSAndroid Build Coastguard Worker    __slots__ = ()
189