Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ty] Use assignability for divergent constraints#26334

Merged
mtshiba merged 1 commit into
mainfrom
fix-divergent-union-assignability
Jun 24, 2026
Merged

[ty] Use assignability for divergent constraints#26334
mtshiba merged 1 commit into
mainfrom
fix-divergent-union-assignability

Conversation

@mtshiba

@mtshiba mtshiba commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

#26288 fixed a crash by preventing when_constraint_set_assignable_to_owned
from returning a trivial always result for top-level Divergent pairs. The
underlying issue was that the owned fast path and the lazy relation checker
could disagree: the fast path treated some Divergent assignability checks as
always satisfied, while the lazy relation checker treated top-level Divergent
as never assignable.

This patch resolves the inconsistency in the relation checker instead.
Unmaterialized Divergent is assignability-compatible in both eager and lazy
assignability, while it is still not a subtype of arbitrary types and still must
not be eliminated by redundancy/union simplification.

With the lazy relation checker aligned with the fast path, we no longer need the
top-level Divergent exclusion in is_trivially_constraint_set_assignable_to.
The regression test from #26288 still passes, and the unit test now asserts that
constraint-set assignability treats Divergent consistently.

Test Plan

unit test updated

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

astral-sh-bot Bot commented Jun 24, 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.47%. The percentage of expected errors that received a diagnostic held steady at 89.10%. The number of fully passing files held steady at 95/134.

@astral-sh-bot

astral-sh-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

Memory usage report

Summary

Project Old New Diff Outcome
flake8 29.13MB 29.13MB -0.00% (820.00B) ⬇️
trio 70.60MB 70.58MB -0.02% (12.16kB) ⬇️
prefect 450.68MB 450.53MB -0.03% (159.64kB) ⬇️
sphinx 167.52MB 167.30MB -0.13% (224.17kB) ⬇️

Significant changes

Click to expand detailed breakdown

flake8

Name Old New Diff Outcome
when_constraint_set_assignable_to_owned_impl::interned_arguments 31.45kB 28.79kB -8.47% (2.66kB) ⬇️
when_constraint_set_assignable_to_owned_impl 102.79kB 101.66kB -1.10% (1.13kB) ⬇️
UnionType<'db>::from_two_elements_::interned_arguments 11.17kB 10.23kB -8.46% (968.00B) ⬇️
Type<'db>::apply_specialization_inner_::interned_arguments 174.53kB 175.31kB +0.45% (800.00B) ⬇️
UnionType<'db>::from_two_elements_ 6.31kB 5.79kB -8.29% (536.00B) ⬇️
Type<'db>::apply_specialization_inner_ 118.16kB 118.65kB +0.42% (504.00B) ⬇️
Specialization 174.56kB 175.00kB +0.25% (448.00B) ⬇️
is_possibly_constraint_set_assignable::interned_arguments 19.08kB 19.34kB +1.35% (264.00B) ⬇️
Type<'db>::class_member_with_policy_ 234.07kB 234.31kB +0.10% (248.00B) ⬇️
member_lookup_with_policy_inner::interned_arguments 204.84kB 205.08kB +0.11% (240.00B) ⬇️
CallableType 209.30kB 209.52kB +0.10% (224.00B) ⬇️
Type<'db>::class_member_with_policy_::interned_arguments 168.49kB 168.70kB +0.12% (208.00B) ⬇️
IntersectionType<'db>::from_two_elements_::interned_arguments 6.19kB 6.36kB +2.78% (176.00B) ⬇️
FunctionType 226.75kB 226.92kB +0.08% (176.00B) ⬇️
infer_expression_types_impl 640.41kB 640.57kB +0.02% (160.00B) ⬇️
... 15 more

trio

Name Old New Diff Outcome
when_constraint_set_assignable_to_owned_impl::interned_arguments 79.75kB 74.68kB -6.36% (5.07kB) ⬇️
when_constraint_set_assignable_to_owned_impl 272.52kB 269.54kB -1.09% (2.98kB) ⬇️
UnionType<'db>::from_two_elements_::interned_arguments 31.54kB 29.30kB -7.08% (2.23kB) ⬇️
UnionType<'db>::from_two_elements_ 18.05kB 16.82kB -6.84% (1.23kB) ⬇️
infer_definition_types 4.02MB 4.02MB -0.01% (264.00B) ⬇️
infer_expression_types_impl 4.35MB 4.35MB -0.01% (256.00B) ⬇️
loop_header_reachability 71.29kB 71.24kB -0.07% (48.00B) ⬇️
all_narrowing_constraints_for_expression 451.20kB 451.17kB -0.01% (32.00B) ⬇️
analyze_non_terminal_call 374.33kB 374.30kB -0.01% (32.00B) ⬇️
infer_expression_type_impl 37.52kB 37.50kB -0.04% (16.00B) ⬇️
is_possibly_constraint_set_assignable 34.13kB 34.15kB +0.05% (16.00B) ⬇️
StaticClassLiteral<'db>::implicit_attribute_inner_ 93.52kB 93.50kB -0.02% (16.00B) ⬇️
infer_scope_types_impl 2.43MB 2.43MB -0.00% (8.00B) ⬇️

prefect

Name Old New Diff Outcome
when_constraint_set_assignable_to_owned_impl::interned_arguments 638.26kB 571.74kB -10.42% (66.52kB) ⬇️
when_constraint_set_assignable_to_owned_impl 2.09MB 2.04MB -2.07% (44.16kB) ⬇️
UnionType<'db>::from_two_elements_::interned_arguments 287.38kB 265.46kB -7.63% (21.91kB) ⬇️
UnionType<'db>::from_two_elements_ 172.16kB 160.19kB -6.96% (11.98kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 3.36MB 3.35MB -0.07% (2.48kB) ⬇️
CallableType 2.87MB 2.87MB -0.07% (2.14kB) ⬇️
Specialization 2.66MB 2.66MB -0.07% (1.88kB) ⬇️
GenericAlias 1.10MB 1.10MB -0.12% (1.41kB) ⬇️
FunctionType 4.59MB 4.59MB -0.03% (1.25kB) ⬇️
StaticClassLiteral<'db>::try_mro_::interned_arguments 1.19MB 1.19MB -0.07% (864.00B) ⬇️
Type<'db>::apply_specialization_inner_::interned_arguments 2.95MB 2.95MB +0.03% (800.00B) ⬇️
member_lookup_with_policy_inner 10.12MB 10.12MB -0.01% (784.00B) ⬇️
infer_definition_types 50.57MB 50.57MB -0.00% (768.00B) ⬇️
is_redundant_with_impl::interned_arguments 2.33MB 2.33MB -0.03% (616.00B) ⬇️
UnionType 1.06MB 1.06MB +0.05% (576.00B) ⬇️
... 32 more

sphinx

Name Old New Diff Outcome
when_constraint_set_assignable_to_owned_impl::interned_arguments 326.73kB 277.23kB -15.15% (49.50kB) ⬇️
CallableType 1.48MB 1.44MB -2.47% (37.28kB) ⬇️
when_constraint_set_assignable_to_owned_impl 1005.04kB 969.53kB -3.53% (35.51kB) ⬇️
UnionType<'db>::from_two_elements_::interned_arguments 191.12kB 169.81kB -11.15% (21.31kB) ⬇️
FunctionType 1.79MB 1.78MB -0.77% (14.20kB) ⬇️
UnionType<'db>::from_two_elements_ 110.23kB 98.59kB -10.56% (11.64kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 1.79MB 1.78MB -0.45% (8.28kB) ⬇️
ProtocolInterface 186.34kB 179.02kB -3.93% (7.32kB) ⬇️
FunctionType<'db>::signature_ 1.61MB 1.61MB -0.43% (7.05kB) ⬇️
Type<'db>::apply_specialization_inner_::interned_arguments 1.54MB 1.53MB -0.40% (6.33kB) ⬇️
cached_protocol_interface 139.62kB 133.59kB -4.32% (6.03kB) ⬇️
Type<'db>::apply_specialization_inner_ 1.03MB 1.03MB -0.54% (5.72kB) ⬇️
StaticClassLiteral<'db>::try_mro_::interned_arguments 609.75kB 606.73kB -0.50% (3.02kB) ⬇️
is_equivalent_to_object_inner::interned_arguments 54.69kB 51.81kB -5.26% (2.88kB) ⬇️
is_equivalent_to_object_inner 48.27kB 45.76kB -5.21% (2.52kB) ⬇️
... 29 more

@astral-sh-bot

astral-sh-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-argument-type 0 1 3
unresolved-attribute 0 0 2
Total 0 1 5

Flaky changes detected. This PR summary excludes flaky changes; see the HTML report for details.

Raw diff:

jax (https://github.com/google/jax)
- jax/experimental/mosaic/gpu/fragmented_array.py:3050:17 error[invalid-argument-type] Method `__getitem__` of type `Overload[(index: SupportsIndex, /) -> bool | (Unknown & ~AlwaysFalsy), (index: slice[SupportsIndex | None, SupportsIndex | None, SupportsIndex | None], /) -> tuple[bool | (Unknown & ~AlwaysFalsy), ...]]` cannot be called with key of type `Replicated` on object of type `tuple[bool | (Unknown & ~AlwaysFalsy), ...]`
+ jax/experimental/mosaic/gpu/fragmented_array.py:3050:17 error[invalid-argument-type] Method `__getitem__` of type `Overload[(index: SupportsIndex, /) -> bool, (index: slice[SupportsIndex | None, SupportsIndex | None, SupportsIndex | None], /) -> tuple[bool, ...]]` cannot be called with key of type `Replicated` on object of type `tuple[bool, ...]`

spark (https://github.com/apache/spark)
- python/pyspark/pandas/series.py:2765:53 error[invalid-argument-type] Argument to bound method `InternalFrame.with_filter` is incorrect: Expected `Column | Series[Unknown]`, found `Unknown | Column | int`

sympy (https://github.com/sympy/sympy)
- sympy/printing/c.py:259:60 error[unresolved-attribute] Attribute `decimal_dig` is not defined on `IntBaseType` in union `FloatType | IntBaseType | Unknown`
+ sympy/printing/c.py:259:60 error[unresolved-attribute] Attribute `decimal_dig` is not defined on `IntBaseType` in union `FloatType | IntBaseType`
- sympy/printing/c.py:518:29 error[unresolved-attribute] Attribute `decimal_dig` is not defined on `FloatBaseType`, `IntBaseType` in union `FloatBaseType | IntBaseType | Unknown`
+ sympy/printing/c.py:518:29 error[unresolved-attribute] Object of type `FloatBaseType | IntBaseType` has no attribute `decimal_dig`

xarray (https://github.com/pydata/xarray)
- xarray/tests/test_interp.py:958:51 error[invalid-argument-type] Argument expression after ** must be a mapping with `str` key type: Found `Hashable`
+ xarray/tests/test_interp.py:958:51 error[invalid-argument-type] Argument expression after ** must be a mapping with `str` key type: Found `Hashable | DataArray`
- xarray/tests/test_interp.py:959:63 error[invalid-argument-type] Argument expression after ** must be a mapping with `str` key type: Found `Hashable`
+ xarray/tests/test_interp.py:959:63 error[invalid-argument-type] Argument expression after ** must be a mapping with `str` key type: Found `Hashable | DataArray`

Full report with detailed diff (timing results)

@mtshiba mtshiba force-pushed the fix-divergent-union-assignability branch from f803e7e to b81d4f5 Compare June 24, 2026 16:54
@mtshiba mtshiba marked this pull request as ready for review June 24, 2026 17:09
@mtshiba mtshiba requested a review from a team as a code owner June 24, 2026 17:09
@astral-sh-bot astral-sh-bot Bot requested a review from charliermarsh June 24, 2026 17:09
@mtshiba mtshiba merged commit 963ef2a into main Jun 24, 2026
66 of 67 checks passed
@mtshiba mtshiba deleted the fix-divergent-union-assignability branch June 24, 2026 17:09
charliermarsh added a commit that referenced this pull request Jun 24, 2026
## Summary

This reverts #26163 and its follow-up changes in #26230, #26246, #26274,
#26275, and #26316.

The recursive nominal-growth recovery replaces a previous cycle result
nested inside a specialization with `Divergent`. The follow-up
regressions show that this local replacement is not structurally safe:
multi-arm union recovery can lose stable arms, and variadic tuple growth
can continue after replacement. Addressing those cases required
increasingly shape-specific alignment and guards without a general way
to establish correspondence between fixed-point iterations.

This restores the cycle-recovery behavior from before #26163. The direct
self-referential `TypeOf` case and the regression coverage for
astral-sh/ty#3835 and astral-sh/ty#3838 continue to pass without the
heuristic and are retained. We remove only the cases that no longer
converge: `TypeOf` references nested in nominal specializations and the
nested-iterable case from astral-sh/ty#3827. The independent `Divergent`
constraint fixes from #26288 and #26334, including the regression
coverage for astral-sh/ty#3836, are also retained.
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.

2 participants