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:
parent
ad7f2b2f6c
commit
6d205a43fa
42
pep-0586.rst
42
pep-0586.rst
|
@ -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
|
||||
================
|
||||
|
|
Loading…
Reference in New Issue