[ty] Full-scope bidirectional inference for unconstrained container literals by ibraheemdev · Pull Request #25279 · astral-sh/ruff (original) (raw)
thejchap pushed a commit to thejchap/ruff that referenced this pull request
…iterals (astral-sh#25279)
Implements full-scope bidirectional inference for collection literals that are not constrained at their definition, e.g.,
x = []
x.append(1)
x.append("2")
reveal_type(x) # revealed: list[int | str]In particular, this PR considers empty, unannotated collection literals
to be unconstrained, e.g., lst = [], and looks ahead in their
containing scope for potentially constraining uses, which are:
- Return statements involving the collection object, e.g.,
return lst. - Annotated assignments involving the collection object, e.g.,
x: list[int] = lst. - Bound-method calls on the collection object, e.g.,
lst.append(1). - Subscript assignments on the collection object, e.g.,
lst[0] = "hello".
The inferred type of the collection literal is the union of all constraints on the element type, collected from all constraining uses in the containing scope. Note that operations through reassignments, arbitrary function calls, augmented assignments, nested bound-method calls, etc., are not currently tracked.
Note that because this PR only considers unconstrained collection
literals, for which we previously inferred Unknown types, the
ecosystem report consists primarily of new diagnostics. These are
ideally removing false negatives, but likely introduces many false
positives as well, because the heuristic implemented is not perfect.
However, this approach is quite easily extended to unannotated
collection literals that are not empty, which seems to remove a couple
hundred ecosystem diagnostics, but I'd like to intentionally limit the
scope of this change (and the performance/memory usage impact).
Part of astral-sh/ty#1473.
anishgirianish pushed a commit to anishgirianish/ruff that referenced this pull request
…iterals (astral-sh#25279)
Implements full-scope bidirectional inference for collection literals that are not constrained at their definition, e.g.,
x = []
x.append(1)
x.append("2")
reveal_type(x) # revealed: list[int | str]In particular, this PR considers empty, unannotated collection literals
to be unconstrained, e.g., lst = [], and looks ahead in their
containing scope for potentially constraining uses, which are:
- Return statements involving the collection object, e.g.,
return lst. - Annotated assignments involving the collection object, e.g.,
x: list[int] = lst. - Bound-method calls on the collection object, e.g.,
lst.append(1). - Subscript assignments on the collection object, e.g.,
lst[0] = "hello".
The inferred type of the collection literal is the union of all constraints on the element type, collected from all constraining uses in the containing scope. Note that operations through reassignments, arbitrary function calls, augmented assignments, nested bound-method calls, etc., are not currently tracked.
Note that because this PR only considers unconstrained collection
literals, for which we previously inferred Unknown types, the
ecosystem report consists primarily of new diagnostics. These are
ideally removing false negatives, but likely introduces many false
positives as well, because the heuristic implemented is not perfect.
However, this approach is quite easily extended to unannotated
collection literals that are not empty, which seems to remove a couple
hundred ecosystem diagnostics, but I'd like to intentionally limit the
scope of this change (and the performance/memory usage impact).
Part of astral-sh/ty#1473.
ibraheemdev added a commit that referenced this pull request
…rals (#25280)
Extends #25279 to support full-scope inference for all unannotated collection literals, even those that are non-empty, e.g.,
x = [1]
x.append("2")
reveal_type(x) # revealed: list[int | str]This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})