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