Skip to content

[ty] Avoid inferring intersection types for call arguments#23933

Merged
ibraheemdev merged 5 commits intomainfrom
ibraheem/call-argument-inference
Mar 17, 2026
Merged

[ty] Avoid inferring intersection types for call arguments#23933
ibraheemdev merged 5 commits intomainfrom
ibraheem/call-argument-inference

Conversation

@ibraheemdev
Copy link
Member

We currently infer intersection types when call arguments have multiple applicable type contexts across call bindings. However, this can lead to incorrect and confusing types being inferred (see astral-sh/ty#3001 for details). Instead, we should store all inferred types separately, and access them based on the type context for the given binding being matched against.

Resolves the remaining part of astral-sh/ty#3001.

@ibraheemdev ibraheemdev added ty Multi-file analysis & type inference ecosystem-analyzer labels Mar 13, 2026

# TODO: We should not error here.
# error: [no-matching-overload]
x8 = f6(reveal_type(list_or_set2(1, 1))) # revealed: list[int] | set[int]
Copy link
Member Author

@ibraheemdev ibraheemdev Mar 13, 2026

Choose a reason for hiding this comment

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

Note that pyright does not handle this case correctly either, and it seems very tricky to implement correctly (and also very unlikely to occur in practice). pyright is also not able to resolve f5 above, which we are able to.

@ibraheemdev ibraheemdev force-pushed the ibraheem/call-argument-inference branch from f8eb408 to e6120a6 Compare March 13, 2026 13:34
raise NotImplementedError

# TODO: We should reveal `list[int]` here.
x1 = f1(reveal_type([1]), 1) # revealed: list[int]
Copy link
Member Author

Choose a reason for hiding this comment

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

The main remaining limitation of this PR is that we do not "choose" the inference of the matching overload after overload evaluation, so hover types will show types inferred without type context. This is also the behavior on main -- I'll try to address it in a follow up (but it doesn't seem very high priority).

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 13, 2026

Typing conformance results

No changes detected ✅

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

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 13, 2026

Memory usage report

Summary

Project Old New Diff Outcome
flake8 48.22MB 48.15MB -0.15% (75.46kB) ⬇️
trio 116.53MB 116.27MB -0.22% (264.32kB) ⬇️
sphinx 264.31MB 263.36MB -0.36% (981.54kB) ⬇️
prefect 700.49MB 698.70MB -0.25% (1.78MB) ⬇️

Significant changes

Click to expand detailed breakdown

flake8

Name Old New Diff Outcome
IntersectionType<'db>::from_two_elements_::interned_arguments 20.54kB 704.00B -96.65% (19.85kB) ⬇️
IntersectionType<'db>::from_two_elements_ 19.35kB 1.35kB -93.02% (18.00kB) ⬇️
infer_expression_types_impl 1.04MB 1.03MB -0.66% (7.01kB) ⬇️
infer_definition_types 1.95MB 1.95MB -0.30% (5.95kB) ⬇️
is_redundant_with_impl::interned_arguments 140.68kB 136.04kB -3.30% (4.64kB) ⬇️
IntersectionType 73.19kB 68.70kB -6.14% (4.49kB) ⬇️
is_redundant_with_impl 140.30kB 137.53kB -1.97% (2.77kB) ⬇️
infer_scope_types_impl 1002.02kB 999.73kB -0.23% (2.30kB) ⬇️
FunctionType 437.28kB 435.70kB -0.36% (1.58kB) ⬇️
CallableType 144.42kB 143.16kB -0.88% (1.27kB) ⬇️
enum_metadata 68.09kB 67.08kB -1.49% (1.02kB) ⬇️
cached_protocol_interface 44.60kB 43.71kB -2.00% (912.00B) ⬇️
FunctionType<'db>::signature_ 359.36kB 358.50kB -0.24% (872.00B) ⬇️
infer_expression_type_impl 213.58kB 212.76kB -0.38% (840.00B) ⬇️
StaticClassLiteral<'db>::try_mro_ 335.51kB 334.89kB -0.19% (636.00B) ⬇️
... 18 more

trio

Name Old New Diff Outcome
IntersectionType<'db>::from_two_elements_ 63.63kB 8.98kB -85.89% (54.65kB) ⬇️
IntersectionType<'db>::from_two_elements_::interned_arguments 57.23kB 4.55kB -92.04% (52.68kB) ⬇️
infer_expression_types_impl 6.10MB 6.08MB -0.28% (17.80kB) ⬇️
is_redundant_with_impl::interned_arguments 537.71kB 520.01kB -3.29% (17.70kB) ⬇️
infer_definition_types 7.54MB 7.52MB -0.23% (17.46kB) ⬇️
is_redundant_with_impl 477.20kB 464.16kB -2.73% (13.04kB) ⬇️
infer_scope_types_impl 4.77MB 4.76MB -0.26% (12.50kB) ⬇️
IntersectionType 231.25kB 219.60kB -5.04% (11.65kB) ⬇️
FunctionType 1.50MB 1.49MB -0.62% (9.58kB) ⬇️
infer_expression_type_impl 1.53MB 1.52MB -0.45% (6.96kB) ⬇️
CallableType 496.54kB 490.28kB -1.26% (6.26kB) ⬇️
FunctionType<'db>::signature_ 1.08MB 1.07MB -0.50% (5.52kB) ⬇️
Type<'db>::apply_specialization_ 738.33kB 733.91kB -0.60% (4.42kB) ⬇️
cached_protocol_interface 134.88kB 130.90kB -2.95% (3.98kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 864.36kB 860.70kB -0.42% (3.66kB) ⬇️
... 26 more

sphinx

Name Old New Diff Outcome
IntersectionType<'db>::from_two_elements_ 202.45kB 6.71kB -96.68% (195.73kB) ⬇️
IntersectionType<'db>::from_two_elements_::interned_arguments 172.13kB 4.12kB -97.60% (168.01kB) ⬇️
infer_definition_types 24.54MB 24.44MB -0.42% (105.11kB) ⬇️
is_redundant_with_impl::interned_arguments 2.09MB 1.99MB -4.68% (100.03kB) ⬇️
infer_expression_types_impl 19.93MB 19.85MB -0.43% (88.71kB) ⬇️
is_redundant_with_impl 1.82MB 1.76MB -3.38% (63.05kB) ⬇️
infer_scope_types_impl 15.58MB 15.54MB -0.25% (40.38kB) ⬇️
Type<'db>::apply_specialization_ 1.66MB 1.63MB -1.79% (30.50kB) ⬇️
IntersectionType 902.96kB 874.85kB -3.11% (28.11kB) ⬇️
FunctionType 3.12MB 3.10MB -0.69% (22.09kB) ⬇️
CallableType 952.40kB 932.22kB -2.12% (20.18kB) ⬇️
infer_expression_type_impl 3.86MB 3.84MB -0.42% (16.56kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 2.11MB 2.10MB -0.65% (14.11kB) ⬇️
FunctionType<'db>::signature_ 2.27MB 2.26MB -0.51% (11.92kB) ⬇️
cached_protocol_interface 196.37kB 184.80kB -5.89% (11.57kB) ⬇️
... 37 more

prefect

Name Old New Diff Outcome
IntersectionType<'db>::from_two_elements_::interned_arguments 339.88kB 5.33kB -98.43% (334.55kB) ⬇️
IntersectionType<'db>::from_two_elements_ 341.21kB 7.80kB -97.71% (333.41kB) ⬇️
infer_expression_types_impl 55.89MB 55.61MB -0.51% (291.68kB) ⬇️
infer_definition_types 90.13MB 89.87MB -0.29% (266.84kB) ⬇️
infer_scope_types_impl 52.98MB 52.89MB -0.19% (100.73kB) ⬇️
is_redundant_with_impl::interned_arguments 5.40MB 5.32MB -1.52% (84.13kB) ⬇️
is_redundant_with_impl 5.61MB 5.54MB -1.30% (74.58kB) ⬇️
infer_expression_type_impl 14.71MB 14.64MB -0.47% (71.02kB) ⬇️
IntersectionType 2.33MB 2.27MB -2.53% (60.36kB) ⬇️
Type<'db>::apply_specialization_ 3.62MB 3.60MB -0.60% (22.18kB) ⬇️
all_narrowing_constraints_for_expression 7.35MB 7.33MB -0.29% (21.70kB) ⬇️
StaticClassLiteral<'db>::implicit_attribute_inner_ 10.02MB 10.00MB -0.18% (18.28kB) ⬇️
FunctionType 8.50MB 8.49MB -0.20% (17.20kB) ⬇️
CallableType 1.69MB 1.68MB -0.97% (16.88kB) ⬇️
all_negative_narrowing_constraints_for_expression 2.81MB 2.79MB -0.43% (12.42kB) ⬇️
... 44 more

@ibraheemdev ibraheemdev force-pushed the ibraheem/call-argument-inference branch from e6120a6 to cec3504 Compare March 13, 2026 13:40
@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 13, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-await 40 0 0
invalid-assignment 0 4 32
invalid-argument-type 3 0 17
type-assertion-failure 0 1 2
unresolved-attribute 0 0 3
invalid-return-type 1 0 1
unsupported-operator 1 0 0
Total 45 5 55

Full report with detailed diff (timing results)

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 13, 2026

Merging this PR will improve performance by 4.82%

⚡ 3 improved benchmarks
✅ 24 untouched benchmarks
⏩ 30 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime static_frame 27.8 s 26.5 s +4.82%
Simulation anyio 1.2 s 1.2 s +4.05%
WallTime colour_science 81 s 77.7 s +4.21%

Comparing ibraheem/call-argument-inference (483c20d) with main (cca3435)

Open in CodSpeed

Footnotes

  1. 30 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Ignore,

/// Store the intersection of all types inferred for the expression.
Intersect,
Copy link
Member Author

Choose a reason for hiding this comment

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

We should be able to remove MultiInferenceState entirely now (see #23923 (comment)), but I'll save that for a follow up.

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 13, 2026

mypy_primer results

Changes were detected when running on open source projects
graphql-core (https://github.com/graphql-python/graphql-core)
- tests/type/test_definition.py:169:72: error[invalid-argument-type] Argument to function `parse_literal` is incorrect: Expected `ValueNode`, found `dict[str, Any] & dict[str, str]`
+ tests/type/test_definition.py:169:72: error[invalid-argument-type] Argument to function `parse_literal` is incorrect: Expected `ValueNode`, found `dict[str, str]`

scrapy (https://github.com/scrapy/scrapy)
- tests/test_downloadermiddleware_cookies.py:363:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, bytes]`
+ tests/test_downloadermiddleware_cookies.py:363:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, str | bytes]`
- tests/test_downloadermiddleware_cookies.py:368:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, bytes]`
+ tests/test_downloadermiddleware_cookies.py:368:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, str | bytes]`
- tests/test_downloadermiddleware_cookies.py:438:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, bool]`
+ tests/test_downloadermiddleware_cookies.py:438:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, str | bool]`
- tests/test_downloadermiddleware_cookies.py:443:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, int | float]`
+ tests/test_downloadermiddleware_cookies.py:443:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, str | int | float]`
- tests/test_downloadermiddleware_cookies.py:448:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, int]`
+ tests/test_downloadermiddleware_cookies.py:448:46: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `dict[str, str | int]`
- tests/test_http_request_form.py:281:58: error[invalid-argument-type] Argument to bound method `from_response` is incorrect: Expected `dict[str, Iterable[str]] | list[tuple[str, Iterable[str]]] | None`, found `dict[str, None | Unknown]`
+ tests/test_http_request_form.py:281:58: error[invalid-argument-type] Argument to bound method `from_response` is incorrect: Expected `dict[str, Iterable[str]] | list[tuple[str, Iterable[str]]] | None`, found `dict[str, Iterable[str] | None]`
- tests/test_http_response.py:270:35: error[invalid-argument-type] Argument to bound method `follow_all` is incorrect: Expected `Iterable[str | Link]`, found `list[None | Unknown]`
+ tests/test_http_response.py:270:35: error[invalid-argument-type] Argument to bound method `follow_all` is incorrect: Expected `Iterable[str | Link]`, found `list[None]`
- tests/test_http_response.py:279:35: error[invalid-argument-type] Argument to bound method `follow_all` is incorrect: Expected `Iterable[str | Link]`, found `list[None | Unknown]`
+ tests/test_http_response.py:279:35: error[invalid-argument-type] Argument to bound method `follow_all` is incorrect: Expected `Iterable[str | Link]`, found `list[None]`
- tests/test_utils_request.py:377:13: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `list[dict[str, str]]`
+ tests/test_utils_request.py:377:13: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str] | list[VerboseCookie] | None`, found `list[VerboseCookie | dict[str, str]]`

optuna (https://github.com/optuna/optuna)
- optuna/storages/_rdb/storage.py:651:16: error[invalid-return-type] Return type does not match returned value: expected `int | float`, found `Unknown | Column[int | float | Any]`
+ optuna/storages/_rdb/storage.py:651:16: error[invalid-return-type] Return type does not match returned value: expected `int | float`, found `Unknown | Column[int | float]`

discord.py (https://github.com/Rapptz/discord.py)
+ discord/app_commands/tree.py:1221:63: error[invalid-argument-type] Argument to bound method `_get_resolved_items` is incorrect: Expected `ResolvedData`, found `ResolvedData | dict[Unknown, Unknown]`
+ discord/app_commands/tree.py:1277:44: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `ResolvedData`, found `ResolvedData | dict[Unknown, Unknown]`
+ discord/interactions.py:353:32: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `ResolvedData`, found `ResolvedData | dict[Unknown, Unknown]`
- Found 558 diagnostics
+ Found 561 diagnostics

cloud-init (https://github.com/canonical/cloud-init)
- tests/unittests/sources/test_ec2.py:665:31: error[unresolved-attribute] Attribute `get` is not defined on `str`, `list[str]` in union `str | dict[str, dict[str, dict[str, str | dict[str, str]]]] | list[str]`
+ tests/unittests/sources/test_ec2.py:665:31: error[unresolved-attribute] Attribute `get` is not defined on `str`, `list[str]` in union `str | dict[Unknown, Unknown] | dict[str, dict[str, dict[str, str | dict[str, str]]]] | list[str]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[str, str]]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | dict[str, str]]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[str, str] | list[str]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[str, str] | list[str]]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[str, str] | list[dict[str, str | int]] | list[str]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[str, str] | list[dict[str, str | int]] | list[str]]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | list[str]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | list[str]]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]] | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]] | dict[str, str]]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[LiteralString, str]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[LiteralString, str]]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int | Unknown]]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int | Unknown]]]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]]]`
- tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int]]]`
+ tests/unittests/test_ds_identify.py:956:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int]]]`
- tests/unittests/test_ds_identify.py:988:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int | Unknown] & dict[str, str | int]`
+ tests/unittests/test_ds_identify.py:988:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int]]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int]]]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[str, str] | list[str]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[str, str] | list[str]]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[str, str] | list[dict[str, str | int]] | list[str]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[str, str] | list[dict[str, str | int]] | list[str]]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | list[str]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | list[str]]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]] | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]] | dict[str, str]]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[LiteralString, str]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[LiteralString, str]]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int | Unknown]]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int | Unknown]]]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]]]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[str, str]]`
- tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:1027:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:1028:9: error[no-matching-overload] No overload of bound method `update` matches arguments
- tests/unittests/test_ds_identify.py:1028:9: error[unresolved-attribute] Attribute `update` is not defined on `str`, `list[dict[str, str | int]]`, `list[str]`, `list[dict[str, str | int] | dict[str, str | int | Unknown]]`, `list[dict[str, str | int | Unknown]]` in union `str | list[dict[str, str | int]] | dict[str, str] | ... omitted 4 union elements`
+ tests/unittests/test_ds_identify.py:1028:9: error[unresolved-attribute] Attribute `update` is not defined on `str`, `list[dict[str, str | int]]`, `list[str]`, `list[dict[str, str | int] | dict[str, str | int | Unknown]]`, `list[dict[str, str | int | Unknown]]` in union `str | list[dict[str, str | int]] | dict[Unknown, Unknown] | ... omitted 5 union elements`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int]]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int]]]`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[str, str]]`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | dict[str, str]]`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[str, str] | list[str]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[str, str] | list[str]]`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[str, str] | list[dict[str, str | int]] | list[str]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[str, str] | list[dict[str, str | int]] | list[str]]`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | list[str]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int]] | list[str]]`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]] | dict[str, str]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]] | dict[str, str]]`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | dict[LiteralString, str]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | dict[LiteralString, str]]`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int | Unknown]]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int | Unknown]]]`
- tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[str, str] & ~AlwaysTruthy) | ... omitted 4 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]]]`
+ tests/unittests/test_ds_identify.py:1043:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["files"]` and value of type `(str & ~AlwaysTruthy) | (list[dict[str, str | int]] & ~AlwaysTruthy) | (dict[Unknown, Unknown] & ~AlwaysTruthy) | ... omitted 5 union elements` on object of type `dict[str, str | list[dict[str, str | int] | dict[str, str | int | Unknown]]]`
+ tests/unittests/test_ds_identify.py:1044:9: error[no-matching-overload] No overload of bound method `update` matches arguments
- tests/unittests/test_ds_identify.py:1044:9: error[unresolved-attribute] Attribute `update` is not defined on `str`, `list[dict[str, str | int]]`, `list[str]`, `list[dict[str, str | int] | dict[str, str | int | Unknown]]`, `list[dict[str, str | int | Unknown]]` in union `str | list[dict[str, str | int]] | dict[str, str] | ... omitted 4 union elements`
+ tests/unittests/test_ds_identify.py:1044:9: error[unresolved-attribute] Attribute `update` is not defined on `str`, `list[dict[str, str | int]]`, `list[str]`, `list[dict[str, str | int] | dict[str, str | int | Unknown]]`, `list[dict[str, str | int | Unknown]]` in union `str | list[dict[str, str | int]] | dict[Unknown, Unknown] | ... omitted 5 union elements`
- tests/unittests/test_ds_identify.py:1449:30: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int | Unknown] & dict[str, str | int]`
+ tests/unittests/test_ds_identify.py:1449:30: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int]`
- tests/unittests/test_ds_identify.py:1457:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int | Unknown] & dict[str, str | int]`
+ tests/unittests/test_ds_identify.py:1457:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int]`
- tests/unittests/test_ds_identify.py:1466:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int | Unknown] & dict[str, str | int]`
+ tests/unittests/test_ds_identify.py:1466:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int]`
- tests/unittests/test_ds_identify.py:1479:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int | Unknown] & dict[str, str | int]`
+ tests/unittests/test_ds_identify.py:1479:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int]`
- tests/unittests/test_ds_identify.py:1500:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int | Unknown] & dict[str, str | int]`
+ tests/unittests/test_ds_identify.py:1500:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int]`
- tests/unittests/test_ds_identify.py:1518:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int | Unknown] & dict[str, str | int]`
+ tests/unittests/test_ds_identify.py:1518:13: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `str`, found `dict[str, str | int]`
- Found 1318 diagnostics
+ Found 1320 diagnostics

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/cli/deploy/_actions.py:192:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["push"]` and value of type `list[dict[str, Any]] & list[dict[str, dict[str, str | None]]]` on object of type `list[dict[str, Any]]`
+ src/prefect/cli/deploy/_actions.py:192:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["push"]` and value of type `list[dict[str, dict[str, str | None]]]` on object of type `list[dict[str, Any]]`
- src/prefect/cli/deploy/_actions.py:200:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["pull"]` and value of type `list[dict[str, Any]] & list[dict[str, dict[str, str | None]]]` on object of type `list[dict[str, Any]]`
+ src/prefect/cli/deploy/_actions.py:200:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["pull"]` and value of type `list[dict[str, dict[str, str | None]]]` on object of type `list[dict[str, Any]]`

egglog-python (https://github.com/egraphs-good/egglog-python)
- python/egglog/declarations.py:666:83: error[invalid-assignment] Object of type `WeakValueDictionary[str | tuple[object, ...] | Unknown, Unknown]` is not assignable to `WeakValueDictionary[tuple[object, ...], CallDecl]`
- Found 1475 diagnostics
+ Found 1474 diagnostics

core (https://github.com/home-assistant/core)
- homeassistant/components/bayesian/binary_sensor.py:340:69: error[invalid-assignment] Object of type `OrderedDict[UUID | Unknown | str, Observation]` is not assignable to `OrderedDict[UUID, Observation]`: Incompatible value of type `OrderedDict[UUID | Unknown | str, Observation]`
- homeassistant/components/bayesian/binary_sensor.py:464:62: error[invalid-assignment] Object of type `OrderedDict[UUID | Unknown | str, Observation]` is not assignable to `OrderedDict[UUID, Observation]`
- homeassistant/components/bayesian/binary_sensor.py:472:62: error[invalid-assignment] Object of type `OrderedDict[UUID | Unknown | str, Observation]` is not assignable to `OrderedDict[UUID, Observation]`
+ homeassistant/components/tado/climate.py:812:20: error[unsupported-operator] Operator `in` is not supported between objects of type `str | None` and `Unknown | str | list[Unknown]`
- homeassistant/util/hass_dict.pyi:149:5: error[type-assertion-failure] Type `dict[int, bool] | (dict[Unknown, Unknown] & dict[str, Unknown])` does not match asserted type `dict[int, bool]`
+ homeassistant/util/hass_dict.pyi:149:5: error[type-assertion-failure] Type `dict[int, bool] | dict[Unknown, Unknown]` does not match asserted type `dict[int, bool]`
- homeassistant/util/hass_dict.pyi:176:5: error[type-assertion-failure] Type `dict[int, bool] | (dict[Unknown, Unknown] & dict[str, Unknown])` does not match asserted type `dict[int, bool]`
+ homeassistant/util/hass_dict.pyi:176:5: error[type-assertion-failure] Type `dict[int, bool] | dict[Unknown, Unknown]` does not match asserted type `dict[int, bool]`
- Found 12114 diagnostics
+ Found 12112 diagnostics

pandas-stubs (https://github.com/pandas-dev/pandas-stubs)
- tests/indexes/test_indexes.py:1337:9: error[type-assertion-failure] Type `Index[Any | str]` does not match asserted type `Index[str]`
- Found 4651 diagnostics
+ Found 4650 diagnostics

@carljm carljm removed their request for review March 13, 2026 14:07
@ibraheemdev ibraheemdev marked this pull request as draft March 13, 2026 14:56
@ibraheemdev ibraheemdev force-pushed the ibraheem/call-argument-inference branch from 19ed6c3 to 31afd45 Compare March 13, 2026 18:55
@ibraheemdev ibraheemdev marked this pull request as ready for review March 13, 2026 19:18
@ibraheemdev
Copy link
Member Author

The ecosystem report looks all positive except for a regression with get on nested typed dicts:

from typing import TypedDict, NotRequired

class Inner(TypedDict):
    x: int

class Outer(TypedDict):
    x: NotRequired[Inner]

def g(x: Outer):
    # error[invalid-assignment]: Object of type `Inner | dict[str, int]` is not assignable to `Inner`
    _: Inner = x.get("x", {"x": 1})
    
    def f[T](x: Outer, y: T) -> Inner | T:
        raise NotImplementedError

    # error[invalid-assignment]: Object of type `Inner | dict[str, int]` is not assignable to `Inner`
    _: Inner = f("x", {"x": 1})

This one is arguably a limitation of the constraint solver. I added a failing test, I don't think it should block this PR. Interestingly, pyright errors on the second but the first, so it might be special casing typed dicts here.

@carljm
Copy link
Contributor

carljm commented Mar 14, 2026

I can take this one in exchange for the one I just reassigned to you, @dcreager :)

@carljm carljm assigned carljm and unassigned dcreager Mar 14, 2026
@carljm carljm self-requested a review March 14, 2026 02:36
@ibraheemdev ibraheemdev force-pushed the ibraheem/call-argument-inference branch from f6cf193 to 1b31b23 Compare March 17, 2026 05:46
@ibraheemdev ibraheemdev force-pushed the ibraheem/call-argument-inference branch from 1b31b23 to 483c20d Compare March 17, 2026 07:04
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

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

Nice!

x1 = f1(reveal_type([1]), 1) # revealed: list[int]
reveal_type(x1) # revealed: int

x2 = f1(reveal_type([1]), int_or_str()) # revealed: list[int]
Copy link
Contributor

Choose a reason for hiding this comment

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

I notice you don't have a TODO comment here -- but list[int] seems just as wrong here as above. I think it should be list[int | None] | list[int | str]?

Copy link
Member Author

Choose a reason for hiding this comment

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

In the case that there is a single applicable type context (after overload resolution), we should reveal the type inferred with that type context. When there are multiple and we actually infer the type multiple times for each matching overload, it's less clear what to reveal here. It's closer to list[int | None] & list[int | str] than list[int | None] | list[int | str] (but this PR is about removing the intersection types after all). If we actually did infer a union, overload resolution would fail here, so I'm not sure revealing the union makes sense. pyright also reveals the type-contextless inference. We could maybe reveal a ty internal Both[list[int | None], list[int | str]], but that also seems confusing?

x4 = f3(reveal_type({"x": [1]}), "1") # revealed: dict[str, list[int]]
reveal_type(x4) # revealed: str

x5 = f3(reveal_type({"x": [1]}), int_or_str()) # revealed: dict[str, list[int]]
Copy link
Contributor

Choose a reason for hiding this comment

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

Here again it seems like a TODO comment is warranted, as much as it is in the previous case?

@ibraheemdev ibraheemdev merged commit 1616095 into main Mar 17, 2026
51 checks passed
@ibraheemdev ibraheemdev deleted the ibraheem/call-argument-inference branch March 17, 2026 20:30
carljm added a commit that referenced this pull request Mar 17, 2026
* main:
  [ty] Filter out unsatisfiable inference attempts during generic call narrowing (#24025)
  [ty] Avoid inferring intersection types for call arguments (#23933)
  [ty] Pin mypy_primer in `setup_primer_project.py` (#24020)
  [`pycodestyle`] Recognize `pyrefly:` as a pragma comment (`E501`) (#24019)
  Add company AI policy to contributing guide (#24021)
  [ty] Remove the mypy_primer CI workflow (#24016)
  Update prek dependencies (#23980)
  [ty] Smarter semantic token classification for attribute access on union type (#23841)
  [ty] ecosystem-analyzer: Inline diffs and panic messages (#24015)
  [ty] Improve `.toml` support in the ty playground (#23476)
  PEP 639 license information (#19661)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ecosystem-analyzer ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants