Haibo Huang | d883030 | 2020-03-03 10:09:46 -0800 | [diff] [blame] | 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 | |
| 7 | def 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 | |
| 28 | class 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 | |
| 41 | class 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 | |
| 54 | class abstractproperty(property): |
| 55 | """A decorator indicating abstract properties. |
| 56 | |
| 57 | Deprecated, use 'property' with 'abstractmethod' instead. |
| 58 | """ |
| 59 | |
| 60 | __isabstractmethod__ = True |
| 61 | |
| 62 | |
| 63 | try: |
| 64 | from _abc import (get_cache_token, _abc_init, _abc_register, |
| 65 | _abc_instancecheck, _abc_subclasscheck, _get_dump, |
| 66 | _reset_registry, _reset_caches) |
| 67 | except ImportError: |
| 68 | from _py_abc import ABCMeta, get_cache_token |
| 69 | ABCMeta.__module__ = 'abc' |
| 70 | else: |
| 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 | |
| 125 | class ABC(metaclass=ABCMeta): |
| 126 | """Helper class that provides a standard way to create an ABC using |
| 127 | inheritance. |
| 128 | """ |
| 129 | __slots__ = () |