PEP 647: Added clarification about the type narrowing mechanics (#1753)

This commit is contained in:
Eric Traut 2020-12-30 14:26:05 -08:00 committed by GitHub
parent bb84af267d
commit 1f1928e4f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 23 additions and 0 deletions

View File

@ -192,6 +192,12 @@ However, it is not required that the return type be strictly narrower. This
allows for cases like the example above where ``List[str]`` is not assignable allows for cases like the example above where ``List[str]`` is not assignable
to ``List[object]``. to ``List[object]``.
When a conditional statement includes a call to a user-defined type guard
function, the expression passed as the first argument to the type guard
function should be assumed by a static type checker to take on the type
specified in the TypeGuard return type, unless and until it is further
narrowed within the conditional code block.
Some built-in type guards provide narrowing for both positive and negative Some built-in type guards provide narrowing for both positive and negative
tests (in both the ``if`` and ``else`` clauses). For example, consider the tests (in both the ``if`` and ``else`` clauses). For example, consider the
type guard for an expression of the form `x is None`. If `x` has a type that type guard for an expression of the form `x is None`. If `x` has a type that
@ -291,6 +297,23 @@ in type safety and will not write their type guard functions in a way that will
undermine type safety or produce nonsensical results. undermine type safety or produce nonsensical results.
Conditionally Applying TypeGuard Type
-------------------------------------
It was suggested that the expression passed as the first argument to a type
guard function should retain is existing type if the type of the expression was
a proper subtype of the type specified in the TypeGuard return type.
For example, if the type guard function is ```def f(value: object) ->
TypeGuard[float]``` and the expression passed to this function is of type
```int```, it would retain the ```int``` type rather than take on the
```float``` type indicated by the TypeGuard return type. This proposal was
rejected because it added complexity, inconsistency, and opened up additional
questions about the proper behavior if the type of the expression was of
composite types like unions or type variables with multiple constraints. It was
decided that the added complexity and inconsistency was not justified given
that it would provide little or no added value.
Narrowing of Arbitrary Parameters Narrowing of Arbitrary Parameters
--------------------------------- ---------------------------------