-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Narrowing str | dict[str, str] with isinstance and .get() #13351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I've been looking at this and figured out so far that when mypy accepts the The problem I'm having is that I'm not familiar with how |
I looked into this a bit too. Here's a more self-contained reproducer: from __future__ import annotations
from typing import TypeVar
T = TypeVar("T")
class MyDict:
def get_item(self) -> str: ...
def get(self, x: T) -> str | T: ...
def first() -> None:
tag_name: str | MyDict
if isinstance(tag_name, MyDict):
tag_name = tag_name.get("asd")
reveal_type(tag_name)
def second() -> None:
tag_name: str | MyDict
if isinstance(tag_name, MyDict):
tag_name = tag_name.get_item()
reveal_type(tag_name) Next I tried: def third() -> None:
tag_name: str | MyDict
if isinstance(tag_name, MyDict):
reveal_type(tag_name) # MyDict
reveal_type(tag_name.get("asd")) # str
tag_name = tag_name.get("asd")
reveal_type(tag_name) # str | MyDict When I do I think the bug is that |
I think its about the assignment back to the typed expression. This also exhibits the same behavior and follows a similar data path, but doesn't have type narrowing in the same way.
Its the union of a type and a generic that turns out to be the same type assigned back to a variable with the union type. If the type hint on tag_name is omitted:
then when it gets to the function Edit: Made the example more minimal |
In my example the type of Your example, modified to match what I consider to be this issue's scope, would be: from typing import TypeVar
T = TypeVar("T")
def func(default: T) -> str | T: ...
def example() -> None:
tag_name: str | int
if isinstance(tag_name, str):
tag_name = func("a")
reveal_type(tag_name) # str | int :( |
Fixed in #14151 |
Bug Report
To Reproduce
Expected Behavior
str
str
Actual Behavior
Union[str, dict[str, str]]
str
Your Environment
latest mypy
The text was updated successfully, but these errors were encountered: