Open
Description
With astral-sh/ruff#18750 merged, we now consider all reachable bindings for nonlocal types. This can cause overly wide union types in cases where the inner scope is only executed after narrowing the type in the outer scope through an assignment. For example:
def outer(x=None):
# …
x = 1
def inner():
reveal_type(x) # Unknown | None | Literal[1], should not contain `None`
inner()
This should be fixed by considering the position of the inner scope within the enclosing scope. Only bindings that appear after the definition of the inner scope should be considered.
A similar problem appears with type narrowing through conditions.
def outer(x: int | None):
if x is not None:
def inner():
reveal_type(x) # int | None, should be int
inner()
Fixing this as well might follow a similar strategy, if we implement the "treat every new narrowing of a definition as a new definition" strategy proposed in #690.