123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- # Copyright 2007 Google, Inc. All Rights Reserved.
- # Licensed to PSF under a Contributor Agreement.
- """Abstract Base Classes (ABCs) according to PEP 3119."""
- def abstractmethod(funcobj):
- """A decorator indicating abstract methods.
- Requires that the metaclass is ABCMeta or derived from it. A
- class that has a metaclass derived from ABCMeta cannot be
- instantiated unless all of its abstract methods are overridden.
- The abstract methods can be called using any of the normal
- 'super' call mechanisms. abstractmethod() may be used to declare
- abstract methods for properties and descriptors.
- Usage:
- class C(metaclass=ABCMeta):
- @abstractmethod
- def my_abstract_method(self, ...):
- ...
- """
- funcobj.__isabstractmethod__ = True
- return funcobj
- class abstractclassmethod(classmethod):
- """A decorator indicating abstract classmethods.
- Deprecated, use 'classmethod' with 'abstractmethod' instead:
- class C(ABC):
- @classmethod
- @abstractmethod
- def my_abstract_classmethod(cls, ...):
- ...
- """
- __isabstractmethod__ = True
- def __init__(self, callable):
- callable.__isabstractmethod__ = True
- super().__init__(callable)
- class abstractstaticmethod(staticmethod):
- """A decorator indicating abstract staticmethods.
- Deprecated, use 'staticmethod' with 'abstractmethod' instead:
- class C(ABC):
- @staticmethod
- @abstractmethod
- def my_abstract_staticmethod(...):
- ...
- """
- __isabstractmethod__ = True
- def __init__(self, callable):
- callable.__isabstractmethod__ = True
- super().__init__(callable)
- class abstractproperty(property):
- """A decorator indicating abstract properties.
- Deprecated, use 'property' with 'abstractmethod' instead:
- class C(ABC):
- @property
- @abstractmethod
- def my_abstract_property(self):
- ...
- """
- __isabstractmethod__ = True
- try:
- from _abc import (get_cache_token, _abc_init, _abc_register,
- _abc_instancecheck, _abc_subclasscheck, _get_dump,
- _reset_registry, _reset_caches)
- except ImportError:
- from _py_abc import ABCMeta, get_cache_token
- ABCMeta.__module__ = 'abc'
- else:
- class ABCMeta(type):
- """Metaclass for defining Abstract Base Classes (ABCs).
- Use this metaclass to create an ABC. An ABC can be subclassed
- directly, and then acts as a mix-in class. You can also register
- unrelated concrete classes (even built-in classes) and unrelated
- ABCs as 'virtual subclasses' -- these and their descendants will
- be considered subclasses of the registering ABC by the built-in
- issubclass() function, but the registering ABC won't show up in
- their MRO (Method Resolution Order) nor will method
- implementations defined by the registering ABC be callable (not
- even via super()).
- """
- def __new__(mcls, name, bases, namespace, **kwargs):
- cls = super().__new__(mcls, name, bases, namespace, **kwargs)
- _abc_init(cls)
- return cls
- def register(cls, subclass):
- """Register a virtual subclass of an ABC.
- Returns the subclass, to allow usage as a class decorator.
- """
- return _abc_register(cls, subclass)
- def __instancecheck__(cls, instance):
- """Override for isinstance(instance, cls)."""
- return _abc_instancecheck(cls, instance)
- def __subclasscheck__(cls, subclass):
- """Override for issubclass(subclass, cls)."""
- return _abc_subclasscheck(cls, subclass)
- def _dump_registry(cls, file=None):
- """Debug helper to print the ABC registry."""
- print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
- print(f"Inv. counter: {get_cache_token()}", file=file)
- (_abc_registry, _abc_cache, _abc_negative_cache,
- _abc_negative_cache_version) = _get_dump(cls)
- print(f"_abc_registry: {_abc_registry!r}", file=file)
- print(f"_abc_cache: {_abc_cache!r}", file=file)
- print(f"_abc_negative_cache: {_abc_negative_cache!r}", file=file)
- print(f"_abc_negative_cache_version: {_abc_negative_cache_version!r}",
- file=file)
- def _abc_registry_clear(cls):
- """Clear the registry (for debugging or testing)."""
- _reset_registry(cls)
- def _abc_caches_clear(cls):
- """Clear the caches (for debugging or testing)."""
- _reset_caches(cls)
- class ABC(metaclass=ABCMeta):
- """Helper class that provides a standard way to create an ABC using
- inheritance.
- """
- __slots__ = ()
|