Skip to content

[ty] Update salsa to fix out-of-order query validation#22498

Merged
MichaReiser merged 1 commit intomainfrom
micha/cycle-validation-order
Jan 23, 2026
Merged

[ty] Update salsa to fix out-of-order query validation#22498
MichaReiser merged 1 commit intomainfrom
micha/cycle-validation-order

Conversation

@MichaReiser
Copy link
Member

@MichaReiser MichaReiser commented Jan 10, 2026

Summary

Pulls in the changes of salsa-rs/salsa#1061

I believe that this should fix all our known incremental salsa bugs, but I can't say for sure. But I suggest we close them optimistically and open them up again if we keep seeing them in the future.

Fixes astral-sh/ty#992
Fixes astral-sh/ty#1565

Test Plan

cargo test / mypy primer

@MichaReiser MichaReiser added bug Something isn't working ty Multi-file analysis & type inference labels Jan 10, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Jan 10, 2026

Typing conformance results

No changes detected ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Jan 10, 2026

mypy_primer results

Changes were detected when running on open source projects
prefect (https://github.com/PrefectHQ/prefect)
- src/integrations/prefect-dbt/prefect_dbt/core/settings.py:94:28: error[invalid-assignment] Object of type `T@resolve_block_document_references | int | dict[str, Any] | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
+ src/integrations/prefect-dbt/prefect_dbt/core/settings.py:94:28: error[invalid-assignment] Object of type `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
- src/prefect/cli/deploy/_core.py:86:21: error[invalid-assignment] Object of type `T@resolve_block_document_references | int | dict[str, Any] | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
+ src/prefect/cli/deploy/_core.py:86:21: error[invalid-assignment] Object of type `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
- src/prefect/deployments/runner.py:795:70: warning[possibly-missing-attribute] Attribute `__name__` may be missing on object of type `Unknown | (((...) -> Any) & ((*args: object, **kwargs: object) -> object))`
+ src/prefect/deployments/runner.py:795:70: warning[possibly-missing-attribute] Attribute `__name__` may be missing on object of type `Unknown | ((...) -> Any)`
- src/prefect/deployments/steps/core.py:137:38: error[invalid-argument-type] Argument is incorrect: Expected `T@resolve_variables`, found `T@resolve_block_document_references | int | dict[str, Any] | ... omitted 4 union elements`
+ src/prefect/deployments/steps/core.py:137:38: error[invalid-argument-type] Argument is incorrect: Expected `T@resolve_variables`, found `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements`
+ src/prefect/flow_engine.py:812:32: error[invalid-await] `Unknown | R@FlowRunEngine | Coroutine[Any, Any, R@FlowRunEngine]` is not awaitable
+ src/prefect/flow_engine.py:1401:24: error[invalid-await] `Unknown | R@AsyncFlowRunEngine | Coroutine[Any, Any, R@AsyncFlowRunEngine]` is not awaitable
+ src/prefect/flow_engine.py:1482:43: error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `Unknown | R@run_generator_flow_sync`
+ src/prefect/flow_engine.py:1490:21: warning[possibly-missing-attribute] Attribute `throw` may be missing on object of type `Unknown | R@run_generator_flow_sync`
+ src/prefect/flow_engine.py:1524:44: warning[possibly-missing-attribute] Attribute `__anext__` may be missing on object of type `Unknown | R@run_generator_flow_async`
+ src/prefect/flow_engine.py:1531:25: warning[possibly-missing-attribute] Attribute `throw` may be missing on object of type `Unknown | R@run_generator_flow_async`
- src/prefect/flows.py:286:34: error[unresolved-attribute] Object of type `((**P@Flow) -> R@Flow) & ((*args: object, **kwargs: object) -> object)` has no attribute `__name__`
+ src/prefect/flows.py:286:34: error[unresolved-attribute] Object of type `(**P@Flow) -> R@Flow` has no attribute `__name__`
- src/prefect/flows.py:404:68: error[unresolved-attribute] Object of type `((**P@Flow) -> R@Flow) & ((*args: object, **kwargs: object) -> object)` has no attribute `__name__`
+ src/prefect/flows.py:404:68: error[unresolved-attribute] Object of type `(**P@Flow) -> R@Flow` has no attribute `__name__`
- src/prefect/flows.py:1750:53: warning[unused-ignore-comment] Unused blanket `type: ignore` directive
- src/prefect/utilities/templating.py:320:13: error[invalid-assignment] Invalid subscript assignment with key of type `object` and value of type `T@resolve_block_document_references | int | dict[str, Any] | ... omitted 4 union elements` on object of type `dict[str, Any]`
+ src/prefect/utilities/templating.py:320:13: error[invalid-assignment] Invalid subscript assignment with key of type `object` and value of type `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements` on object of type `dict[str, Any]`
- src/prefect/utilities/templating.py:323:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_block_document_references | dict[str, Any]`, found `list[Unknown | T@resolve_block_document_references | int | ... omitted 5 union elements]`
+ src/prefect/utilities/templating.py:323:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_block_document_references | dict[str, Any]`, found `list[Unknown | dict[str, Any] | int | ... omitted 5 union elements]`
- src/prefect/workers/base.py:232:13: error[invalid-argument-type] Argument is incorrect: Expected `T@resolve_variables`, found `T@resolve_block_document_references | int | dict[str, Any] | ... omitted 4 union elements`
+ src/prefect/workers/base.py:232:13: error[invalid-argument-type] Argument is incorrect: Expected `T@resolve_variables`, found `dict[str, Any] | int | T@resolve_block_document_references | ... omitted 4 union elements`
- Found 5384 diagnostics
+ Found 5389 diagnostics

scikit-build-core (https://github.com/scikit-build/scikit-build-core)
+ src/scikit_build_core/build/wheel.py:99:20: error[no-matching-overload] No overload of bound method `__init__` matches arguments
- Found 46 diagnostics
+ Found 47 diagnostics

pandas-stubs (https://github.com/pandas-dev/pandas-stubs)
+ tests/frame/test_groupby.py:229:15: error[type-assertion-failure] Type `Series[Any]` does not match asserted type `Series[str | bytes | int | ... omitted 12 union elements]`
+ tests/frame/test_groupby.py:625:15: error[type-assertion-failure] Type `Series[Any]` does not match asserted type `Series[str | bytes | int | ... omitted 12 union elements]`
- Found 4456 diagnostics
+ Found 4458 diagnostics

core (https://github.com/home-assistant/core)
- homeassistant/util/variance.py:47:12: error[invalid-return-type] Return type does not match returned value: expected `(**_P@ignore_variance) -> _R@ignore_variance`, found `_Wrapped[_P@ignore_variance, int | _R@ignore_variance | float | datetime, _P@ignore_variance, _R@ignore_variance | int | float | datetime]`
- Found 14464 diagnostics
+ Found 14463 diagnostics

Memory usage changes were detected when running on open source projects
trio (https://github.com/python-trio/trio)
-     struct metadata = ~11MB
+     struct metadata = ~10MB
-     memo metadata = ~33MB
+     memo metadata = ~31MB

sphinx (https://github.com/sphinx-doc/sphinx)
- TOTAL MEMORY USAGE: ~301MB
+ TOTAL MEMORY USAGE: ~287MB

prefect (https://github.com/PrefectHQ/prefect)
-     memo metadata = ~167MB
+     memo metadata = ~194MB

@astral-sh-bot
Copy link

astral-sh-bot bot commented Jan 10, 2026

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

@MichaReiser
Copy link
Member Author

Okay, perf looks pretty neutral. Some of the panics look absolutely terrifying (yay, panics in unsafe code)

@MichaReiser MichaReiser force-pushed the micha/cycle-validation-order branch 3 times, most recently from 74f1b39 to f6fbd78 Compare January 11, 2026 14:57
@MichaReiser MichaReiser force-pushed the micha/cycle-validation-order branch 2 times, most recently from fb99923 to 044784d Compare January 19, 2026 14:10
@codspeed-hq
Copy link

codspeed-hq bot commented Jan 19, 2026

CodSpeed Performance Report

Merging this PR will not alter performance

Comparing micha/cycle-validation-order (f403785) with main (b912dfc)

Summary

✅ 53 untouched benchmarks

@MichaReiser
Copy link
Member Author

MichaReiser commented Jan 19, 2026

ouch (perf and memory usage)

@MichaReiser
Copy link
Member Author

But hey, all tests pass

@MichaReiser MichaReiser force-pushed the micha/cycle-validation-order branch from 044784d to d3b65dc Compare January 19, 2026 14:49
@MichaReiser
Copy link
Member Author

MichaReiser commented Jan 19, 2026

Okay, this looks less terrible. The memory regression is a bit brutal

@MichaReiser MichaReiser force-pushed the micha/cycle-validation-order branch from d3b65dc to c9b6675 Compare January 19, 2026 16:40
@AlexWaygood
Copy link
Member

Okay, this looks less terrible. The memory regression is a bit brutal

Notably, only on prefect, where we know (from our flaky mypy_primer comments of late) that we encounter some very bad cycles.

(Not saying we shouldn't be concerned about the memory regression, just speculating that that's one reason why it might show up especially on prefect, possibly?)

@MichaReiser
Copy link
Member Author

MichaReiser commented Jan 19, 2026

Yeah, I suspect that prefect has some very large cycles. This becomes an issue with the new approach, where we flatten all inputs (reads to tracked struct, inputs, and created interned values) for every cycle head. This leads to a lot of redundant metadata (we no longer get the nice binary-tree memory saving where we only have one dependency when we call a query, instead we flatten that query's dependency too)

The memory regression is also already much less terryfing :)

@MichaReiser MichaReiser force-pushed the micha/cycle-validation-order branch from c9b6675 to 2bb6aa3 Compare January 20, 2026 08:16
@MichaReiser
Copy link
Member Author

MichaReiser commented Jan 20, 2026

The memo metadata increase for prefect is pretty substantial and mainly due to that we store metadata for infer_expression_types_impl and infer_definition_types. I suspect due to some larger cycles. Here's the full memory report diff.

However, in total, it's only a 1.5% increase. There are other impactful changes that we can make in Salsa to compensate for this increase (within the same revision LRU, immortal durability)

Perf looks pretty good now. The simplified deep_verify_memo pays for most of the extra overhead incurred by cyclic queries.

@MichaReiser MichaReiser force-pushed the micha/cycle-validation-order branch from 2bb6aa3 to d873685 Compare January 21, 2026 15:54
@MichaReiser MichaReiser force-pushed the micha/cycle-validation-order branch from d873685 to f403785 Compare January 22, 2026 16:26
@MichaReiser MichaReiser marked this pull request as ready for review January 22, 2026 17:29
@MichaReiser
Copy link
Member Author

I go ahead and merge this. If there are any regression while I'm out, I suggest reverting this bump

@MichaReiser MichaReiser merged commit e7fb612 into main Jan 23, 2026
49 checks passed
@MichaReiser MichaReiser deleted the micha/cycle-validation-order branch January 23, 2026 07:56
carljm added a commit that referenced this pull request Jan 30, 2026
* main: (62 commits)
  [`refurb`] Do not add `abc.ABC` if already present (`FURB180`) (#22234)
  [ty] Add a new `assert-type-unspellable-subtype` diagnostic (#22815)
  [ty] Avoid duplicate syntax errors for `await` outside functions (#22826)
  [ty] Fix unary operator false-positive for constrained TypeVars (#22783)
  [ty] Fix binary operator false-positive for constrained TypeVars (#22782)
  [ty] Fix false-positive `unsupported-operator` for "symmetric" TypeVars (#22756)
  [`pydocstyle`] Clarify which quote styles are allowed (`D300`) (#22825)
  [ty] Use distributed versions of AND and OR on constraint sets (#22614)
  [ty] Add support for dict literals and dict() calls as default values for parameters with TypedDict types (#22161)
  Document `-` stdin convention in CLI help text (#22817)
  [ty] Make `infer_subscript_expression_types` a method on `Type` (#22731)
  [ty] Simplify `OverloadLiteral::spans` and `OverloadLiteral::parameter_span` (#22823)
  [ty] Require both `*args` and `**kwargs` when calling a `ParamSpec` callable (#22820)
  [ty] Handle tagged errors in conformance (#22746)
  Add `--color` cli option to force colored output (#22806)
  Identify notebooks by LSP didOpen instead of `.ipynb` file extension (#22810)
  [ty] Fix docstring rendering for literal blocks after doctests (#22676)
  [ty] Update salsa to fix out-of-order query validation (#22498)
  [ty] Inline cycle initial and recovery functions (#22814)
  [ty] Pass the generic context through the decorator (#22544)
  ...
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

2 participants