Skip to content

[ty] Preserve Divergent when materializing recursive aliases#24245

Merged
charliermarsh merged 1 commit intomainfrom
charlie/panic-1
Mar 27, 2026
Merged

[ty] Preserve Divergent when materializing recursive aliases#24245
charliermarsh merged 1 commit intomainfrom
charlie/panic-1

Conversation

@charliermarsh
Copy link
Copy Markdown
Member

@charliermarsh charliermarsh commented Mar 27, 2026

Summary

TypeMapping::Materialize now preserves DynamicType::Divergent instead of collapsing it to object or Never, so the cycle marker remains intact during recursive alias solving.

Closes astral-sh/ty#3134.

@astral-sh-bot astral-sh-bot bot added the ty Multi-file analysis & type inference label Mar 27, 2026
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 27, 2026

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 86.59%. The percentage of expected errors that received a diagnostic held steady at 80.96%. The number of fully passing files held steady at 68/132.

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 27, 2026

Memory usage report

Memory usage unchanged ✅

@AlexWaygood
Copy link
Copy Markdown
Member

Beep boop, here is your ecosystem analysis that astral-bot failed to post as a comment 🤖


ecosystem-analyzer results

Lint rule Added Removed Changed
index-out-of-bounds 1 0 0
invalid-assignment 1 0 0
Total 2 0 0

Raw diff:

rotki (https://github.com/rotki/rotki)
+ rotkehlchen/exchanges/coinbase.py:466:40 error[invalid-assignment] Object of type `dict[str, list[dict[Unknown, Unknown]]]` is not assignable to `defaultdict[str, list[dict[Unknown, Unknown]]]`

scipy (https://github.com/scipy/scipy)
+ scipy/interpolate/_interpolate.py:2262:56 error[index-out-of-bounds] Index 1 is out of bounds for tuple `tuple[int]` with length 1

(it's uploaded to https://github.com/astral-sh/ruff/actions/runs/23653467204?pr=24245)

Comment on lines +5590 to +5593
// `Divergent` is an internal cycle marker rather than a gradual type like
// `Any` or `Unknown`. Materializing it away would destroy the marker we rely
// on for recursive alias convergence.
Type::Dynamic(DynamicType::Divergent(_)) => self,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need a TODO here for the fact that we elsewhere treat Divergent as a dynamic type, so it could result in odd behavior to fail to materialize it away. I suspect that odd behavior is less bad than a stack overflow, so I'm ok going ahead with the fix and leaving this as TODO.

One option could be to have variants of Divergent that behave as Never or as object, rather than as a dynamic type, but still are marked as Divergent for cycle normalization purposes, and return those variants here.

I think solving this will almost certainly mean making Divergent a top level Type variant rather than a sub-variant of Type::Dynamic.

@charliermarsh charliermarsh enabled auto-merge (squash) March 27, 2026 17:32
@charliermarsh charliermarsh added the bug Something isn't working label Mar 27, 2026
@charliermarsh charliermarsh merged commit 29bf84e into main Mar 27, 2026
48 checks passed
@charliermarsh charliermarsh deleted the charlie/panic-1 branch March 27, 2026 17:38
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 27, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-await 40 0 0
index-out-of-bounds 1 0 0
invalid-assignment 1 0 0
invalid-return-type 1 0 0
Total 43 0 0

Changes in flaky projects detected. Raw diff output excludes flaky projects; see the HTML report for details.

Raw diff:

rotki (https://github.com/rotki/rotki)
+ rotkehlchen/exchanges/coinbase.py:466:40 error[invalid-assignment] Object of type `dict[str, list[dict[Unknown, Unknown]]]` is not assignable to `defaultdict[str, list[dict[Unknown, Unknown]]]`

scipy (https://github.com/scipy/scipy)
+ scipy/interpolate/_interpolate.py:2264:56 error[index-out-of-bounds] Index 1 is out of bounds for tuple `tuple[int]` with length 1

Full report with detailed diff (timing results)

charliermarsh added a commit that referenced this pull request Mar 30, 2026
## Summary

This PR follows
#24245 (comment),
making `Divergent` a top-level type rather than a `DynamicType` variant.
charliermarsh added a commit that referenced this pull request Mar 30, 2026
## Summary

This PR follows
#24245 (comment) such
that we preserve the top or bottom materialization on `Divergent`
materializing recursive types.
carljm added a commit that referenced this pull request Mar 31, 2026
* main: (40 commits)
  [ty] resolve union-likes in emitting union attribute errors (#24263)
  [ty] Improve support for `Callable` type context (#23888)
  [ty] Propagate type context through `await` expressions (#24256)
  [`pyflakes`] Flag annotated variable redeclarations as `F811` in preview mode (#24244)
  [ty] Preserve `Divergent` when materializing recursive aliases (#24245)
  Fix W391 fixes for consecutive empty notebook cells (#24236)
  [flake8-bugbear] Clarify RUF071 fix safety for non-path string comparisons (#24149)
  [ty] Ban type qualifiers in PEP-695 type aliases (#24242)
  [ty] Include keyword-prefixed symbols in completions for attributes (#24232)
  [ty] Add tests for TypedDict method overloads on unions (#24230)
  [ty] report unused bindings as unnecessary hint diagnostics (#23305)
  Remove unused `non_root` variable (#24238)
  Extend F507 to flag %-format strings with zero placeholders (#24215)
  [`flake8-simplify`] Suppress `SIM105` for `except*` before Python 3.12 (#23869)
  Ignore pre-initialization references in SIM113 (#24235)
  Parenthesize expression in RUF050 fix (#24234)
  Publish playgrounds using the `release-playground` environment (#24223)
  [ty] Fix instance-attribute lookup in methods of protocol classes (#24213)
  [ty] Used shared expression cache during generic call inference (#24219)
  [ty] make `Type::BoundMethod` include instances of same-named methods bound to a subclass (#24039)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stack overflow on recursive TypeIs with Callable

3 participants