Skip to content

[ty] Narrow tuple expression match subjects - #25871

Closed
charliermarsh wants to merge 1 commit into
charlie/pattern-asfrom
charlie/narrow-tuple-match-subjects
Closed

[ty] Narrow tuple expression match subjects#25871
charliermarsh wants to merge 1 commit into
charlie/pattern-asfrom
charlie/narrow-tuple-match-subjects

Conversation

@charliermarsh

Copy link
Copy Markdown
Member

Summary

This is stacked on #25637, which provides the complete-pattern element inference reused here.

Prior to this change, we narrowed a tuple value used as a match subject, but not the names used to construct a tuple expression:

class A: ...
class A1(A): ...
class B: ...
class B1(B): ...

def f(a: A, b: B) -> None:
    match a, b:
        case [A1(), B1()]:
            reveal_type(a)  # revealed: A1
            reveal_type(b)  # revealed: B1

This projects a successful exact sequence match back onto each simple-name tuple element. We retain whole-pattern filtering from #25637 and intersect constraints for repeated names. We do not project failed matches because they do not identify which element failed, and we exclude more complex subject expressions because they can rebind or mutate an earlier place before the case body.

We also preserve unconstrained or alternatives when combining pattern constraints, so one constrained alternative cannot narrow the overall match.

Closes astral-sh/ty#3743.

@astral-sh-bot astral-sh-bot Bot added the ty Multi-file analysis & type inference label Jun 11, 2026
@astral-sh-bot

astral-sh-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 94.36%. The percentage of expected errors that received a diagnostic held steady at 88.82%. The number of fully passing files held steady at 93/134.

@astral-sh-bot

astral-sh-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot

astral-sh-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

Lint rule Added Removed Changed
unresolved-attribute 0 12 0
invalid-argument-type 3 6 0
unsupported-operator 0 2 0
invalid-assignment 0 0 1
no-matching-overload 0 1 0
Total 3 21 1
Raw diff (25 changes)
jax (https://github.com/google/jax)
- jax/experimental/mosaic/gpu/constraints.py:544:13 error[invalid-argument-type] Argument to function `splat_is_compatible_with_tiled` is incorrect: Expected `WGSplatFragLayout`, found `WGSplatFragLayout | WGStridedFragLayout | TiledLayout`
- jax/experimental/mosaic/gpu/constraints.py:544:28 error[invalid-argument-type] Argument to function `splat_is_compatible_with_tiled` is incorrect: Expected `TiledLayout`, found `WGSplatFragLayout | WGStridedFragLayout | TiledLayout`
- jax/experimental/mosaic/gpu/constraints.py:548:13 error[invalid-argument-type] Argument to function `_is_supported_tiled_relayout` is incorrect: Expected `TiledLayout`, found `WGSplatFragLayout | WGStridedFragLayout | TiledLayout`
- jax/experimental/mosaic/gpu/constraints.py:548:28 error[invalid-argument-type] Argument to function `_is_supported_tiled_relayout` is incorrect: Expected `TiledLayout`, found `WGSplatFragLayout | WGStridedFragLayout | TiledLayout`

kopf (https://github.com/nolar/kopf)
- kopf/_cogs/structs/references.py:305:45 error[no-matching-overload] No overload of bound method `Pattern.fullmatch` matches arguments
- kopf/_cogs/structs/references.py:306:24 error[unresolved-attribute] Attribute `split` is not defined on `Marker`, `(Resource, /) -> bool`, `None` in union `str | Marker | ((Resource, /) -> bool) | None`
- kopf/_cogs/structs/references.py:307:55 error[unresolved-attribute] Attribute `split` is not defined on `Marker`, `(Resource, /) -> bool`, `None` in union `str | Marker | ((Resource, /) -> bool) | None`
- kopf/_cogs/structs/references.py:308:53 error[unresolved-attribute] Attribute `split` is not defined on `Marker`, `(Resource, /) -> bool`, `None` in union `str | Marker | ((Resource, /) -> bool) | None`
- kopf/_cogs/structs/references.py:309:54 error[unresolved-attribute] Attribute `split` is not defined on `Marker`, `(Resource, /) -> bool`, `None` in union `str | Marker | ((Resource, /) -> bool) | None`
- kopf/_cogs/structs/references.py:310:45 error[unsupported-operator] Operator `in` is not supported between objects of type `Literal["."]` and `str | Marker | ((Resource, /) -> bool) | None`
- kopf/_cogs/structs/references.py:311:51 error[unresolved-attribute] Attribute `split` is not defined on `Marker`, `(Resource, /) -> bool`, `None` in union `str | Marker | ((Resource, /) -> bool) | None`
- kopf/_cogs/structs/references.py:312:54 error[unresolved-attribute] Attribute `split` is not defined on `Marker`, `(Resource, /) -> bool`, `None` in union `str | Marker | ((Resource, /) -> bool) | None`
- kopf/_cogs/structs/references.py:315:42 error[unsupported-operator] Operator `in` is not supported between objects of type `Literal["/"]` and `str | Marker | ((Resource, /) -> bool) | None`
- kopf/_cogs/structs/references.py:316:51 error[unresolved-attribute] Attribute `rsplit` is not defined on `Marker`, `(Resource, /) -> bool`, `None` in union `str | Marker | ((Resource, /) -> bool) | None`
- kopf/_cogs/structs/references.py:317:53 error[unresolved-attribute] Attribute `rsplit` is not defined on `Marker`, `(Resource, /) -> bool`, `None` in union `str | Marker | ((Resource, /) -> bool) | None`
+ kopf/_cogs/structs/diffs.py:180:52 error[invalid-argument-type] Argument to function `diff_iter` is incorrect: Expected `tuple[str, ...]`, found `tuple[object, ...]`
+ kopf/_cogs/structs/diffs.py:182:52 error[invalid-argument-type] Argument to function `diff_iter` is incorrect: Expected `tuple[str, ...]`, found `tuple[object, ...]`
+ kopf/_cogs/structs/diffs.py:184:54 error[invalid-argument-type] Argument to function `diff_iter` is incorrect: Expected `tuple[str, ...]`, found `tuple[object, ...]`

pylint (https://github.com/pycqa/pylint)
- pylint/checkers/utils.py:2123:20 error[unresolved-attribute] Attribute `name` is not defined on `AssignAttr` in union `AssignName | AssignAttr`
- pylint/checkers/utils.py:2123:35 error[unresolved-attribute] Object of type `NodeNG | None` has no attribute `name`
- pylint/checkers/utils.py:2125:42 error[unresolved-attribute] Attribute `as_string` is not defined on `None` in union `NodeNG | None`
- pylint/checkers/utils.py:2127:45 error[invalid-argument-type] Argument to function `subscript_chain_is_equal` is incorrect: Expected `Subscript`, found `AssignName | AssignAttr`
- pylint/checkers/utils.py:2127:53 error[invalid-argument-type] Argument to function `subscript_chain_is_equal` is incorrect: Expected `Subscript`, found `NodeNG | None`

pytest (https://github.com/pytest-dev/pytest)
- src/_pytest/assertion/rewrite.py:1127:21 error[unresolved-attribute] Object of type `expr` has no attribute `target`
- src/_pytest/assertion/rewrite.py:1128:21 error[invalid-assignment] Invalid subscript assignment with key of type `@Todo` and value of type `expr` on object of type `dict[str, str]`
+ src/_pytest/assertion/rewrite.py:1128:21 error[invalid-assignment] Invalid subscript assignment with key of type `@Todo` and value of type `NamedExpr` on object of type `dict[str, str]`

Full report with detailed diff (timing results)

@charliermarsh

Copy link
Copy Markdown
Member Author

Superseded by #25874, which implements tuple-subject narrowing directly on main by targeting the bindings captured when the match subject is evaluated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant