diff options
author | Ivan Levkivskyi <levkivskyi@gmail.com> | 2019-05-26 08:37:07 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-26 08:37:07 (GMT) |
commit | f367242d10ef36db38133a39ab7627f63099cba4 (patch) | |
tree | 9e6b8d67b14a69fda120cc5433013b6d1f7b6c35 /Lib/typing.py | |
parent | 47dd2f9fd86c32a79e77fef1fbb1ce25dc929de6 (diff) | |
download | cpython-f367242d10ef36db38133a39ab7627f63099cba4.zip cpython-f367242d10ef36db38133a39ab7627f63099cba4.tar.gz cpython-f367242d10ef36db38133a39ab7627f63099cba4.tar.bz2 |
bpo-37045: PEP 591: Add final qualifiers to typing module (GH-13571)
The implementation is straightforward, it just mimics `ClassVar` (since the latter is also a name/access qualifier, not really a type). Also it is essentially copied from `typing_extensions`.
Diffstat (limited to 'Lib/typing.py')
-rw-r--r-- | Lib/typing.py | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/Lib/typing.py b/Lib/typing.py index 7aab162..06a7eb0 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -35,6 +35,7 @@ __all__ = [ 'Any', 'Callable', 'ClassVar', + 'Final', 'Generic', 'Optional', 'Tuple', @@ -92,6 +93,7 @@ __all__ = [ # One-off things. 'AnyStr', 'cast', + 'final', 'get_type_hints', 'NewType', 'no_type_check', @@ -121,7 +123,7 @@ def _type_check(arg, msg, is_argument=True): """ invalid_generic_forms = (Generic, _Protocol) if is_argument: - invalid_generic_forms = invalid_generic_forms + (ClassVar, ) + invalid_generic_forms = invalid_generic_forms + (ClassVar, Final) if arg is None: return type(None) @@ -336,8 +338,8 @@ class _SpecialForm(_Final, _Immutable, _root=True): @_tp_cache def __getitem__(self, parameters): - if self._name == 'ClassVar': - item = _type_check(parameters, 'ClassVar accepts only single type.') + if self._name in ('ClassVar', 'Final'): + item = _type_check(parameters, f'{self._name} accepts only single type.') return _GenericAlias(self, (item,)) if self._name == 'Union': if parameters == (): @@ -398,6 +400,24 @@ ClassVar = _SpecialForm('ClassVar', doc= be used with isinstance() or issubclass(). """) +Final = _SpecialForm('Final', doc= + """Special typing construct to indicate final names to type checkers. + + A final name cannot be re-assigned or overridden in a subclass. + For example: + + MAX_SIZE: Final = 9000 + MAX_SIZE += 1 # Error reported by type checker + + class Connection: + TIMEOUT: Final[int] = 10 + + class FastConnector(Connection): + TIMEOUT = 1 # Error reported by type checker + + There is no runtime checking of these properties. + """) + Union = _SpecialForm('Union', doc= """Union type; Union[X, Y] means either X or Y. @@ -1085,6 +1105,32 @@ def overload(func): return _overload_dummy +def final(f): + """A decorator to indicate final methods and final classes. + + Use this decorator to indicate to type checkers that the decorated + method cannot be overridden, and decorated class cannot be subclassed. + For example: + + class Base: + @final + def done(self) -> None: + ... + class Sub(Base): + def done(self) -> None: # Error reported by type checker + ... + + @final + class Leaf: + ... + class Other(Leaf): # Error reported by type checker + ... + + There is no runtime checking of these properties. + """ + return f + + class _ProtocolMeta(type): """Internal metaclass for _Protocol. |