astral-sh
ruff
BlogDocsChangelog

[ty] Support calls to intersection types

#22469
Comparing
claude/fix-issue-1858-UjARA
(
7926fb1
) with
main
(
99beabd
)
CodSpeed Performance Gauge
0%
Untouched
53

Benchmarks

Passed

DateType
crates/ruff_benchmark/benches/ty.rs::project::datetype::project
CodSpeed Performance Gauge
+2%
236.7 ms233 ms
ty_micro[complex_constrained_attributes_1]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_complex_constrained_attributes_1
CodSpeed Performance Gauge
+1%
68.6 ms67.8 ms
ty_micro[many_string_assignments]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_many_string_assignments
CodSpeed Performance Gauge
+1%
78.2 ms77.4 ms
ty_micro[complex_constrained_attributes_2]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_complex_constrained_attributes_2
CodSpeed Performance Gauge
+1%
68.3 ms67.6 ms
ty_micro[many_tuple_assignments]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_tuple_implicit_instance_attributes
CodSpeed Performance Gauge
+1%
68.4 ms67.7 ms
ty_micro[complex_constrained_attributes_3]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_complex_constrained_attributes_3
CodSpeed Performance Gauge
+1%
71.7 ms71 ms
freqtrade
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
+1%
8 s8 s
tanjun
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
+1%
2.5 s2.5 s
anyio
crates/ruff_benchmark/benches/ty.rs::project::anyio::project
CodSpeed Performance Gauge
+1%
1.2 s1.2 s
attrs
crates/ruff_benchmark/benches/ty.rs::project::attrs::project
CodSpeed Performance Gauge
+1%
434.5 ms431.1 ms
colour_science
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
+1%
90.8 s90.1 s
ty_micro[many_tuple_assignments]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_many_tuple_assignments
CodSpeed Performance Gauge
+1%
66.2 ms65.8 ms
ty_micro[many_enum_members]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_many_enum_members
CodSpeed Performance Gauge
+1%
123.3 ms122.6 ms
ty_check_file[cold]
crates/ruff_benchmark/benches/ty.rs::check_file::benchmark_cold
CodSpeed Performance Gauge
+1%
131.4 ms130.6 ms
static_frame
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
0%
21.8 s21.8 s
ty_micro[many_enum_members_2]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_many_enum_members_2
CodSpeed Performance Gauge
0%
153.4 ms153.1 ms
pandas
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
0%
64.5 s64.4 s
lexer[numpy/globals.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer
CodSpeed Performance Gauge
0%
30.2 µs30.2 µs
parser[numpy/globals.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser
CodSpeed Performance Gauge
0%
109 µs109 µs
linter/default-rules[numpy/globals.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules
CodSpeed Performance Gauge
0%
209.4 µs209.3 µs
hydra-zen
crates/ruff_benchmark/benches/ty.rs::project::hydra::project
CodSpeed Performance Gauge
0%
1.2 s1.2 s
linter/default-rules[unicode/pypinyin.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules
CodSpeed Performance Gauge
0%
406.3 µs406.2 µs
linter/all-rules[numpy/globals.py]
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules
CodSpeed Performance Gauge
0%
724.6 µs724.4 µs
linter/all-with-preview-rules[numpy/globals.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules
CodSpeed Performance Gauge
0%
827.6 µs827.5 µs
linter/all-rules[large/dataset.py]
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules
CodSpeed Performance Gauge
0%
18.3 ms18.3 ms
parser[unicode/pypinyin.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser
CodSpeed Performance Gauge
0%
329.3 µs329.2 µs
parser[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser
CodSpeed Performance Gauge
0%
958.8 µs958.7 µs
linter/all-rules[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules
CodSpeed Performance Gauge
0%
4.3 ms4.3 ms
linter/all-with-preview-rules[large/dataset.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules
CodSpeed Performance Gauge
0%
22.3 ms22.3 ms
formatter[unicode/pypinyin.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter
CodSpeed Performance Gauge
0%
688 µs688 µs
parser[large/dataset.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser
CodSpeed Performance Gauge
0%
5.2 ms5.2 ms
linter/all-rules[pydantic/types.py]
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules
CodSpeed Performance Gauge
0%
8.4 ms8.4 ms
linter/all-with-preview-rules[unicode/pypinyin.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules
CodSpeed Performance Gauge
0%
2.2 ms2.2 ms
lexer[large/dataset.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer
CodSpeed Performance Gauge
0%
1.2 ms1.2 ms
linter/all-rules[unicode/pypinyin.py]
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules
CodSpeed Performance Gauge
0%
2 ms2 ms
linter/all-with-preview-rules[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules
CodSpeed Performance Gauge
0%
5.2 ms5.2 ms
linter/all-with-preview-rules[pydantic/types.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules
CodSpeed Performance Gauge
0%
10.1 ms10.1 ms
formatter[numpy/globals.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter
CodSpeed Performance Gauge
0%
248.5 µs248.5 µs
lexer[unicode/pypinyin.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer
CodSpeed Performance Gauge
0%
79 µs79 µs
linter/default-rules[pydantic/types.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules
CodSpeed Performance Gauge
0%
2.2 ms2.2 ms
linter/default-rules[large/dataset.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules
CodSpeed Performance Gauge
0%
4.3 ms4.3 ms
parser[pydantic/types.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser
CodSpeed Performance Gauge
0%
2 ms2 ms
linter/default-rules[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules
CodSpeed Performance Gauge
0%
1 ms1 ms
formatter[pydantic/types.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter
CodSpeed Performance Gauge
0%
3.6 ms3.6 ms
formatter[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter
CodSpeed Performance Gauge
0%
1.9 ms1.9 ms
formatter[large/dataset.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter
CodSpeed Performance Gauge
0%
9.4 ms9.4 ms
lexer[pydantic/types.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer
CodSpeed Performance Gauge
0%
510 µs510 µs
lexer[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer
CodSpeed Performance Gauge
0%
227.9 µs227.9 µs
altair
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
0%
4.6 s4.6 s
sympy
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
0%
51.3 s51.4 s
ty_check_file[incremental]
crates/ruff_benchmark/benches/ty.rs::check_file::benchmark_incremental
CodSpeed Performance Gauge
0%
6.1 ms6.2 ms
multithreaded
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
-2%
1.1 s1.1 s
pydantic
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
-3%
10.4 s10.7 s

Commits

Click on a commit to change the comparison range
Base
main
99beabd
+0.02%
[ty] Support calls to intersection types Implement proper handling for calling intersection types. Previously, calling an intersection type would return a `@Todo` type that suppressed errors but provided no useful type information. Now, when calling an intersection type: - We try to call each positive element with the given arguments - Elements where the call fails (wrong arguments, not callable, etc.) are discarded - If at least one element succeeds, the call is valid - The return type is the intersection of return types from successful elements - If all elements fail, an appropriate error is reported This approach means that if an intersection contains both a callable with a known signature and a `Top[Callable[..., object]]` (from narrowing by `callable()`), the call will succeed using the element with the known signature, avoiding spurious `call-top-callable` errors. Fixes https://github.com/astral-sh/ty/issues/1858
f39370a
4 days ago
by claude
-0.06%
Fix markdown formatting in intersection_types.md
b3b1b7b
4 days ago
by claude
-0.02%
[ty] Show individual errors when all intersection elements fail a call When calling an intersection type where all callable elements reject the specific call arguments, we now show an error for each failing element (similar to how unions work) instead of a single generic "not callable" error. This is achieved by: - Not filtering out failed elements when ALL elements fail - Returning BindingError instead of NotCallable to trigger individual diagnostics - Adding IntersectionDiagnostic struct and CompoundDiagnostic trait - Modifying report_diagnostics to iterate over intersection elements
360f1e9
4 days ago
by claude
+0.06%
Bump sympy expected diagnostics to 13200 More diagnostics are now emitted due to showing individual errors when all intersection elements fail a call.
6b4a0b8
4 days ago
by claude
-0.15%
[ty] Add priority hierarchy for intersection call errors When all intersection elements fail a call, we now use a priority hierarchy to determine which errors to show: 1. NotCallable (lowest) - object has no __call__ method 2. TopCallable - object is a top callable with unknown signature 3. BindingError (highest) - specific errors like invalid-argument-type Only errors from the highest priority category are shown. This prevents noise from less-specific errors when more informative errors are available. For example, if an intersection has one element that fails with invalid-argument-type and another that's not callable, we only show the invalid-argument-type error since it's more specific and actionable.
4866f6e
4 days ago
by claude
-0.19%
[ty] Support unions containing intersection elements in call bindings Refactors the `Bindings` structure to use a two-level representation: - Outer level: union elements (each can be a single callable or an intersection) - Inner level: bindings within an intersection element This enables proper handling of types like `(A & B) | C` when calling, where `A & B` is an intersection that was narrowed by `callable()`. Key changes: - Add `BindingsElement` struct to represent a single union element (which may contain multiple bindings for intersections) - Update `from_union` to preserve intersection structure instead of flattening - Update `from_intersection` to create a single element with multiple bindings - Update `return_type`, `check_types_impl`, and `report_diagnostics` to handle the two-level structure - Add test for union-of-intersections case The priority hierarchy for intersection call errors is preserved: when all bindings in an intersection fail, only the highest-priority error type is reported (BindingError > TopCallable > NotCallable).
bc4798f
4 days ago
by claude
+0.85%
Merge main into claude/fix-issue-1858-UjARA Resolves conflicts between the two-level Bindings structure and main's new Type match cases for property descriptors, dataclass transformers, and other features.
cc1ddc5
3 days ago
by claude
-0.32%
Bump freqtrade expected diagnostics from 600 to 650
930f13d
3 days ago
by claude
+0.13%
Fix invalid-await for intersections containing dynamic types This PR fixes false `invalid-await` errors for patterns like: ```python if inspect.isawaitable(x): await x # x has type Unknown & Awaitable[object] ``` Changes: 1. Add intersection handling to `generator_return_type()` so that await operations on intersection types work correctly. When awaiting an intersection, we iterate over positive elements, collect return types from awaitable elements, and intersect them together. Non-awaitable elements are skipped; only if all elements fail to be awaitable do we report an error. 2. Add intersection handling to `try_call_dunder_with_policy()` to call dunder methods on each intersection element separately and combine the results. This avoids intersecting bound methods (which often collapses to Never) and instead intersects the return types. Added tests for: - Awaiting `Unknown & Awaitable[object]` returns `Unknown` - Awaiting intersection of two Coroutine types - Awaiting intersection with non-awaitable elements skips those elements - Awaiting intersection where all elements are non-awaitable produces error
01b1937
3 days ago
by claude
-0.37%
Refactor dataclass params to use with_dataclass_params helper Simplify the code by using the with_dataclass_params method instead of manually constructing a new ClassLiteral with all parameters.
c440f4b
3 hours ago
by claude
-0.01%
Remove unused ClassLiteral import The import is no longer needed after refactoring to use with_dataclass_params helper method.
48c3b5e
3 hours ago
by claude
+0.23%
Fix dataclass transform function handling after merge - Fix test expectations in dataclasses.md to match main's expected output - Restore full dataclass_transform decorated function handling logic that was lost during merge - this includes the heuristics to detect whether a decorated function is being used as a direct decorator or as a decorator factory based on positional arguments and return type Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7926fb1
19 minutes ago
by carljm
© 2026 CodSpeed Technology
Home Terms Privacy Docs