Should it be possible to use get_args on literals for type narrowing?
I tried it in Pyright but it doesn’t seem to work.
Seems like a useful feature to have.
I’m sure it seems obvious to you but I have no idea what you are asking/suggesting.
Maybe demonstrate what you mean by showing some code that doesn’t type check and explaining what you want to a type checker to do.
Sorry for not being clear.
I was thinking about something like:
from typing import Literal, TypeAlias, get_args, reveal_type
Alphabet: TypeAlias = Literal['a', 'b', 'c']
def get_x() -> str:
return 'a'
x = get_x()
if x in get_args(Alphabet):
# it would be great if the inferred type of `x` was Alphabet as opposed to str
print(reveal_type(x))
else:
print(reveal_type(x))
The following seems to work:
from typing import Literal, TypeAlias, TypeIs, get_args, reveal_type
Alphabet: TypeAlias = Literal['a', 'b', 'c']
def is_alphabet(a: str) -> TypeIs[Alphabet]:
return a in get_args(Alphabet)
def get_x() -> str:
return 'a'
x = get_x()
if is_alphabet(x):
print(reveal_type(x))
But it would be nice for it to work without the need of wrapping the check into a TypeIs. Not sure if it’s possible.
Keep in mind that your is_alphabet
example won’t work anymore at runtime once you add either a Union
, Annotated
, or a TypeAliasType
in the mix, even though static type-checkers would consider it equivalent.
All these reasons are why I’m not satisfied with this solution.
1 Like
You can do it like this:
Alphabet: TypeAlias = Literal[...]
alphabet: tuple[Alphabet, ...] = get_args(Alphabet)
x = str("a")
reveal_type(x)
if x in alphabet:
reveal_type(x)