My impression is this is a cross between typing.cast and `isinstance` checks. What's the difference between this and `typing.cast https://docs.python.org/3/library/typing.html#typing.cast`? It seems a little stricter, because the return type in the TypeGuard must be narrower than the input type?
On Wed, Sep 30, 2020 at 2:40 PM Eric Traut email@example.com wrote:
I occasionally receive questions from pyright users about extending type narrowing to handle cases that are not possible with today’s Python type system.
Typescript provides a useful facility called [user-defined type guards]( https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-define...) that allows users to extend the notion of type narrowing. It would be straightforward to add this idea to Python. Do others think this would be useful, and is there any interest in standardizing this?
Here’s a concrete proposal. We could add a new generic type called `TypeGuard` in the `typing` module. It would be a subclass of bool, defined simply as:
class TypeGuard(bool, Generic[_T]): pass
If any function or method accepts one parameter and returns a `TypeGuard` type, a type checker would assume that the argument passed to this function can be narrowed to the type specified in the `TypeGuard` type argument.
Here are a few examples:
from typing import Any, Generic, List, Tuple, TypeGuard, TypeVar _T = TypeVar("_T") def is_two_element_tuple(val: Tuple[_T, ...]) -> TypeGuard[Tuple[_T, _T]]: return TypeGuard(len(val) == 2) def foo(names: Tuple[str, ...]): if is_two_element_tuple(names): reveal_type(names) # Tuple[str, str] def is_string_list(val: List[object]) -> TypeGuard[List[str]]: return TypeGuard(all(isinstance(x, str) for x in val)) def bar(stuff: List[Any]): if is_string_list(stuff): reveal_type(stuff) # List[str]
Eric Traut Contributor to Pyright and Pylance Microsoft Corp. _______________________________________________ Typing-sig mailing list -- firstname.lastname@example.org To unsubscribe send an email to email@example.com https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: firstname.lastname@example.org