17db96d56Sopenharmony_ci# Copyright 2007 Google, Inc. All Rights Reserved.
27db96d56Sopenharmony_ci# Licensed to PSF under a Contributor Agreement.
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci"""Abstract Base Classes (ABCs) according to PEP 3119."""
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_cidef abstractmethod(funcobj):
87db96d56Sopenharmony_ci    """A decorator indicating abstract methods.
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci    Requires that the metaclass is ABCMeta or derived from it.  A
117db96d56Sopenharmony_ci    class that has a metaclass derived from ABCMeta cannot be
127db96d56Sopenharmony_ci    instantiated unless all of its abstract methods are overridden.
137db96d56Sopenharmony_ci    The abstract methods can be called using any of the normal
147db96d56Sopenharmony_ci    'super' call mechanisms.  abstractmethod() may be used to declare
157db96d56Sopenharmony_ci    abstract methods for properties and descriptors.
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci    Usage:
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci        class C(metaclass=ABCMeta):
207db96d56Sopenharmony_ci            @abstractmethod
217db96d56Sopenharmony_ci            def my_abstract_method(self, arg1, arg2, argN):
227db96d56Sopenharmony_ci                ...
237db96d56Sopenharmony_ci    """
247db96d56Sopenharmony_ci    funcobj.__isabstractmethod__ = True
257db96d56Sopenharmony_ci    return funcobj
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ciclass abstractclassmethod(classmethod):
297db96d56Sopenharmony_ci    """A decorator indicating abstract classmethods.
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_ci    Deprecated, use 'classmethod' with 'abstractmethod' instead:
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci        class C(ABC):
347db96d56Sopenharmony_ci            @classmethod
357db96d56Sopenharmony_ci            @abstractmethod
367db96d56Sopenharmony_ci            def my_abstract_classmethod(cls, ...):
377db96d56Sopenharmony_ci                ...
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci    """
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci    __isabstractmethod__ = True
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci    def __init__(self, callable):
447db96d56Sopenharmony_ci        callable.__isabstractmethod__ = True
457db96d56Sopenharmony_ci        super().__init__(callable)
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_ciclass abstractstaticmethod(staticmethod):
497db96d56Sopenharmony_ci    """A decorator indicating abstract staticmethods.
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_ci    Deprecated, use 'staticmethod' with 'abstractmethod' instead:
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci        class C(ABC):
547db96d56Sopenharmony_ci            @staticmethod
557db96d56Sopenharmony_ci            @abstractmethod
567db96d56Sopenharmony_ci            def my_abstract_staticmethod(...):
577db96d56Sopenharmony_ci                ...
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ci    """
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci    __isabstractmethod__ = True
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci    def __init__(self, callable):
647db96d56Sopenharmony_ci        callable.__isabstractmethod__ = True
657db96d56Sopenharmony_ci        super().__init__(callable)
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ciclass abstractproperty(property):
697db96d56Sopenharmony_ci    """A decorator indicating abstract properties.
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci    Deprecated, use 'property' with 'abstractmethod' instead:
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_ci        class C(ABC):
747db96d56Sopenharmony_ci            @property
757db96d56Sopenharmony_ci            @abstractmethod
767db96d56Sopenharmony_ci            def my_abstract_property(self):
777db96d56Sopenharmony_ci                ...
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_ci    """
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci    __isabstractmethod__ = True
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_citry:
857db96d56Sopenharmony_ci    from _abc import (get_cache_token, _abc_init, _abc_register,
867db96d56Sopenharmony_ci                      _abc_instancecheck, _abc_subclasscheck, _get_dump,
877db96d56Sopenharmony_ci                      _reset_registry, _reset_caches)
887db96d56Sopenharmony_ciexcept ImportError:
897db96d56Sopenharmony_ci    from _py_abc import ABCMeta, get_cache_token
907db96d56Sopenharmony_ci    ABCMeta.__module__ = 'abc'
917db96d56Sopenharmony_cielse:
927db96d56Sopenharmony_ci    class ABCMeta(type):
937db96d56Sopenharmony_ci        """Metaclass for defining Abstract Base Classes (ABCs).
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci        Use this metaclass to create an ABC.  An ABC can be subclassed
967db96d56Sopenharmony_ci        directly, and then acts as a mix-in class.  You can also register
977db96d56Sopenharmony_ci        unrelated concrete classes (even built-in classes) and unrelated
987db96d56Sopenharmony_ci        ABCs as 'virtual subclasses' -- these and their descendants will
997db96d56Sopenharmony_ci        be considered subclasses of the registering ABC by the built-in
1007db96d56Sopenharmony_ci        issubclass() function, but the registering ABC won't show up in
1017db96d56Sopenharmony_ci        their MRO (Method Resolution Order) nor will method
1027db96d56Sopenharmony_ci        implementations defined by the registering ABC be callable (not
1037db96d56Sopenharmony_ci        even via super()).
1047db96d56Sopenharmony_ci        """
1057db96d56Sopenharmony_ci        def __new__(mcls, name, bases, namespace, /, **kwargs):
1067db96d56Sopenharmony_ci            cls = super().__new__(mcls, name, bases, namespace, **kwargs)
1077db96d56Sopenharmony_ci            _abc_init(cls)
1087db96d56Sopenharmony_ci            return cls
1097db96d56Sopenharmony_ci
1107db96d56Sopenharmony_ci        def register(cls, subclass):
1117db96d56Sopenharmony_ci            """Register a virtual subclass of an ABC.
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ci            Returns the subclass, to allow usage as a class decorator.
1147db96d56Sopenharmony_ci            """
1157db96d56Sopenharmony_ci            return _abc_register(cls, subclass)
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_ci        def __instancecheck__(cls, instance):
1187db96d56Sopenharmony_ci            """Override for isinstance(instance, cls)."""
1197db96d56Sopenharmony_ci            return _abc_instancecheck(cls, instance)
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ci        def __subclasscheck__(cls, subclass):
1227db96d56Sopenharmony_ci            """Override for issubclass(subclass, cls)."""
1237db96d56Sopenharmony_ci            return _abc_subclasscheck(cls, subclass)
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci        def _dump_registry(cls, file=None):
1267db96d56Sopenharmony_ci            """Debug helper to print the ABC registry."""
1277db96d56Sopenharmony_ci            print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
1287db96d56Sopenharmony_ci            print(f"Inv. counter: {get_cache_token()}", file=file)
1297db96d56Sopenharmony_ci            (_abc_registry, _abc_cache, _abc_negative_cache,
1307db96d56Sopenharmony_ci             _abc_negative_cache_version) = _get_dump(cls)
1317db96d56Sopenharmony_ci            print(f"_abc_registry: {_abc_registry!r}", file=file)
1327db96d56Sopenharmony_ci            print(f"_abc_cache: {_abc_cache!r}", file=file)
1337db96d56Sopenharmony_ci            print(f"_abc_negative_cache: {_abc_negative_cache!r}", file=file)
1347db96d56Sopenharmony_ci            print(f"_abc_negative_cache_version: {_abc_negative_cache_version!r}",
1357db96d56Sopenharmony_ci                  file=file)
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ci        def _abc_registry_clear(cls):
1387db96d56Sopenharmony_ci            """Clear the registry (for debugging or testing)."""
1397db96d56Sopenharmony_ci            _reset_registry(cls)
1407db96d56Sopenharmony_ci
1417db96d56Sopenharmony_ci        def _abc_caches_clear(cls):
1427db96d56Sopenharmony_ci            """Clear the caches (for debugging or testing)."""
1437db96d56Sopenharmony_ci            _reset_caches(cls)
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_cidef update_abstractmethods(cls):
1477db96d56Sopenharmony_ci    """Recalculate the set of abstract methods of an abstract class.
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ci    If a class has had one of its abstract methods implemented after the
1507db96d56Sopenharmony_ci    class was created, the method will not be considered implemented until
1517db96d56Sopenharmony_ci    this function is called. Alternatively, if a new abstract method has been
1527db96d56Sopenharmony_ci    added to the class, it will only be considered an abstract method of the
1537db96d56Sopenharmony_ci    class after this function is called.
1547db96d56Sopenharmony_ci
1557db96d56Sopenharmony_ci    This function should be called before any use is made of the class,
1567db96d56Sopenharmony_ci    usually in class decorators that add methods to the subject class.
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_ci    Returns cls, to allow usage as a class decorator.
1597db96d56Sopenharmony_ci
1607db96d56Sopenharmony_ci    If cls is not an instance of ABCMeta, does nothing.
1617db96d56Sopenharmony_ci    """
1627db96d56Sopenharmony_ci    if not hasattr(cls, '__abstractmethods__'):
1637db96d56Sopenharmony_ci        # We check for __abstractmethods__ here because cls might by a C
1647db96d56Sopenharmony_ci        # implementation or a python implementation (especially during
1657db96d56Sopenharmony_ci        # testing), and we want to handle both cases.
1667db96d56Sopenharmony_ci        return cls
1677db96d56Sopenharmony_ci
1687db96d56Sopenharmony_ci    abstracts = set()
1697db96d56Sopenharmony_ci    # Check the existing abstract methods of the parents, keep only the ones
1707db96d56Sopenharmony_ci    # that are not implemented.
1717db96d56Sopenharmony_ci    for scls in cls.__bases__:
1727db96d56Sopenharmony_ci        for name in getattr(scls, '__abstractmethods__', ()):
1737db96d56Sopenharmony_ci            value = getattr(cls, name, None)
1747db96d56Sopenharmony_ci            if getattr(value, "__isabstractmethod__", False):
1757db96d56Sopenharmony_ci                abstracts.add(name)
1767db96d56Sopenharmony_ci    # Also add any other newly added abstract methods.
1777db96d56Sopenharmony_ci    for name, value in cls.__dict__.items():
1787db96d56Sopenharmony_ci        if getattr(value, "__isabstractmethod__", False):
1797db96d56Sopenharmony_ci            abstracts.add(name)
1807db96d56Sopenharmony_ci    cls.__abstractmethods__ = frozenset(abstracts)
1817db96d56Sopenharmony_ci    return cls
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ci
1847db96d56Sopenharmony_ciclass ABC(metaclass=ABCMeta):
1857db96d56Sopenharmony_ci    """Helper class that provides a standard way to create an ABC using
1867db96d56Sopenharmony_ci    inheritance.
1877db96d56Sopenharmony_ci    """
1887db96d56Sopenharmony_ci    __slots__ = ()
189