PEP 586: Add section about Final (#996)

This commit adds a section discussion how Literal types interact with
Final from PEP 591, if both PEPs are accepted. In short, it states
that type checkers are expected to understand that assignment statements
of the form `var: Final = value` are a way of declaring `var` to
effectively be of type `Literal[value]` in certain cases.
This commit is contained in:
Michael Lee 2019-04-16 09:41:35 -07:00 committed by Guido van Rossum
parent ad7f2b2f6c
commit 6d205a43fa
1 changed files with 41 additions and 1 deletions

View File

@ -290,7 +290,7 @@ enum member?
In cases like these, we always assume the user meant to construct a
literal string. If the user wants a forward reference, they must wrap
the entire literal type in a string -- e.g. ``"Literal[Color.RED]"``.
the entire literal type in a string -- e.g. ``"Literal[Color.RED]"``.
Literals, enums, and Any
------------------------
@ -430,6 +430,9 @@ We expect similar behavior when using functions like getattr::
reveal_type(getattr(t, b)) # Revealed type is 'Callable[[int], str]'
getattr(t, c) # Error: No attribute named 'blah' in Test
**Note:** See `Interactions with Final`_ for a proposal on how we can
express the variable declarations above in a more compact manner.
Interactions with overloads
---------------------------
@ -588,8 +591,44 @@ involving Literal bools. For example, we can combine ``Literal[True]``,
scalar += 3 # Type checks: type of 'scalar' is narrowed to 'int'
else:
scalar += "foo" # Type checks: type of 'scalar' is narrowed to 'str'
Interactions with Final
-----------------------
`PEP 591 <pep-591_>`_ proposes adding a "Final" qualifier to the typing
ecosystem. This qualifier can be used to declare that some variable or
attribute cannot be reassigned::
foo: Final = 3
foo = 4 # Error: 'foo' is declared to be Final
Note that in the example above, we know that ``foo`` will always be equal to
exactly ``3``. A type checker can use this information to deduce that ``foo``
is valid to use in any context that expects a ``Literal[3]``::
def expects_three(x: Literal[3]) -> None: ...
expects_three(foo) # Type checks, since 'foo' is Final and equal to 3
The ``Final`` qualifier serves as a shorthand for declaring that a variable
is *effectively Literal*.
If both this PEP and PEP 591 are accepted, type checkers are expected to
support this shortcut. Specifically, given a variable or attribute assignment
of the form ``var: Final = value`` where ``value`` is a valid parameter for
``Literal[...]``, type checkers should understand that ``var`` may be used in
any context that expects a ``Literal[value]``.
Type checkers are not obligated to understand any other uses of Final. For
example, whether or not the following program type checks is left unspecified::
# Note: The assignment does not exactly match the form 'var: Final = value'.
bar1: Final[int] = 3
expects_three(bar1) # May or may not be accepted by type checkers
# Note: "Literal[1 + 2]" is not a legal type.
bar2: Final = 1 + 2
expects_three(bar2) # MAy or may not be accepted by type checkers
Rejected or out-of-scope ideas
==============================
@ -709,6 +748,7 @@ something similar to how
.. _pep-484-enums: https://www.python.org/dev/peps/pep-0484/#support-for-singleton-types-in-unions
.. _pep-591: https://www.python.org/dev/peps/pep-0591/
Acknowledgements
================