-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Closed
Closed
Copy link
Labels
bugmypy got something wrongmypy got something wrongfalse-positivemypy gave an error on correct codemypy gave an error on correct codepriority-0-hightopic-type-narrowingConditional type narrowing / binderConditional type narrowing / binder
Description
Bug Report
Mypy sometimes loses track of the narrowed type of a variable, at least when the variable can be uninitialized in some code paths. This can happen when variables is both initialized and narrowed in a conditional block.
To Reproduce
if int():
x: int | str
x = 0
x = str(x)
reveal_type(x) # int | str
Expected Behavior
Revealed type is str
.
Actual Behavior
Revealed type is int | str
.
Discussion
Here are some more realistic examples:
def cond() -> bool:
return True
if cond():
x: int | str
x = 0
x = str(x)
if cond():
reveal_type(x) # int | str
for i in [1]:
y: int | bytes
y = 0
y = bytes(y)
reveal_type(y) # int | bytes
def f(x: int | None) -> int:
return x or 1
def g() -> None:
if cond():
if int():
z = None
else:
z = 1
z = f(z)
if cond():
reveal_type(z) # int | None
def h() -> None:
if cond():
if int():
z = 1
else:
z = None
z = f(z)
if cond():
reveal_type(z) # int | None
This issue interferes with inferring union types from assignments (#18568).
@ilevkivskyi Do you have an idea of how to fix this, since you did some work on the binder recently? If a variable hasn't been assigned in some conditional code path, maybe the type should be treated as Never
when merging types from different code paths?
Metadata
Metadata
Assignees
Labels
bugmypy got something wrongmypy got something wrongfalse-positivemypy gave an error on correct codemypy gave an error on correct codepriority-0-hightopic-type-narrowingConditional type narrowing / binderConditional type narrowing / binder