Closed
Description
Feature
It would be great if mypy could detect and type narrow strings to Literals if this is statically detectable.
I.e. if accessing TypedDict or Enum values
Pitch
from typing import TypedDict
class Part(TypedDict, total=False):
a: int
b: int
class Full(Part, total=False):
c: int
def make_part(full: Full) -> Part:
part: Part = {}
for k, v in full.items():
if k in Part.__annotations__:
part[k]=v # error: TypedDict key must be a string literal; expected one of ("a", "b") [literal-required]
return part
Currently there is no way to type this kind of expression without a # type: ignore
.
It would be nice if mypy could detect that if k in Part.__annotations__
will narrow k
to the Literal of all key of Part
.
Also if k == "a"
isn't working at the moment, but at least for this I am able to write a TypeGuard
.
Also if Literals are explicitly defined, we loose this once we are with a loop
Even if the literal is defined explictly, it gets lost in a for loop
def make_part_two(full: Full) -> Part:
part: Part = {}
keys: Final = ("a", "b")
reveal_type(keys) # tuple[Literal['a']?, Literal['b']?]
ok = full[keys[0]]
for key in keys:
reveal_type(key) # str
part[key] = full[key] # literal-required
If explicitly given as keys: tuple[Literal["a", "b"], ...]
it works also in the for loop but I don't want to duplicate these values...