1# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
3
4"""Abstract Base Classes (ABCs) according to PEP 3119."""
5
6
7def abstractmethod(funcobj):
8    """A decorator indicating abstract methods.
9
10    Requires that the metaclass is ABCMeta or derived from it.  A
11    class that has a metaclass derived from ABCMeta cannot be
12    instantiated unless all of its abstract methods are overridden.
13    The abstract methods can be called using any of the normal
14    'super' call mechanisms.  abstractmethod() may be used to declare
15    abstract methods for properties and descriptors.
16
17    Usage:
18
19        class C(metaclass=ABCMeta):
20            @abstractmethod
21            def my_abstract_method(self, ...):
22                ...
23    """
24    funcobj.__isabstractmethod__ = True
25    return funcobj
26
27
28class abstractclassmethod(classmethod):
29    """A decorator indicating abstract classmethods.
30
31    Deprecated, use 'classmethod' with 'abstractmethod' instead.
32    """
33
34    __isabstractmethod__ = True
35
36    def __init__(self, callable):
37        callable.__isabstractmethod__ = True
38        super().__init__(callable)
39
40
41class abstractstaticmethod(staticmethod):
42    """A decorator indicating abstract staticmethods.
43
44    Deprecated, use 'staticmethod' with 'abstractmethod' instead.
45    """
46
47    __isabstractmethod__ = True
48
49    def __init__(self, callable):
50        callable.__isabstractmethod__ = True
51        super().__init__(callable)
52
53
54class abstractproperty(property):
55    """A decorator indicating abstract properties.
56
57    Deprecated, use 'property' with 'abstractmethod' instead.
58    """
59
60    __isabstractmethod__ = True
61
62
63try:
64    from _abc import (get_cache_token, _abc_init, _abc_register,
65                      _abc_instancecheck, _abc_subclasscheck, _get_dump,
66                      _reset_registry, _reset_caches)
67except ImportError:
68    from _py_abc import ABCMeta, get_cache_token
69    ABCMeta.__module__ = 'abc'
70else:
71    class ABCMeta(type):
72        """Metaclass for defining Abstract Base Classes (ABCs).
73
74        Use this metaclass to create an ABC.  An ABC can be subclassed
75        directly, and then acts as a mix-in class.  You can also register
76        unrelated concrete classes (even built-in classes) and unrelated
77        ABCs as 'virtual subclasses' -- these and their descendants will
78        be considered subclasses of the registering ABC by the built-in
79        issubclass() function, but the registering ABC won't show up in
80        their MRO (Method Resolution Order) nor will method
81        implementations defined by the registering ABC be callable (not
82        even via super()).
83        """
84        def __new__(mcls, name, bases, namespace, **kwargs):
85            cls = super().__new__(mcls, name, bases, namespace, **kwargs)
86            _abc_init(cls)
87            return cls
88
89        def register(cls, subclass):
90            """Register a virtual subclass of an ABC.
91
92            Returns the subclass, to allow usage as a class decorator.
93            """
94            return _abc_register(cls, subclass)
95
96        def __instancecheck__(cls, instance):
97            """Override for isinstance(instance, cls)."""
98            return _abc_instancecheck(cls, instance)
99
100        def __subclasscheck__(cls, subclass):
101            """Override for issubclass(subclass, cls)."""
102            return _abc_subclasscheck(cls, subclass)
103
104        def _dump_registry(cls, file=None):
105            """Debug helper to print the ABC registry."""
106            print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
107            print(f"Inv. counter: {get_cache_token()}", file=file)
108            (_abc_registry, _abc_cache, _abc_negative_cache,
109             _abc_negative_cache_version) = _get_dump(cls)
110            print(f"_abc_registry: {_abc_registry!r}", file=file)
111            print(f"_abc_cache: {_abc_cache!r}", file=file)
112            print(f"_abc_negative_cache: {_abc_negative_cache!r}", file=file)
113            print(f"_abc_negative_cache_version: {_abc_negative_cache_version!r}",
114                  file=file)
115
116        def _abc_registry_clear(cls):
117            """Clear the registry (for debugging or testing)."""
118            _reset_registry(cls)
119
120        def _abc_caches_clear(cls):
121            """Clear the caches (for debugging or testing)."""
122            _reset_caches(cls)
123
124
125class ABC(metaclass=ABCMeta):
126    """Helper class that provides a standard way to create an ABC using
127    inheritance.
128    """
129    __slots__ = ()
130