Skip to content

[ty] Infer typevars through a nominal type[…] formal - #27689

Merged
charliermarsh merged 2 commits into
astral-sh:mainfrom
augustelalande:ty-nominal-subclass-of-inference
Aug 12, 2026
Merged

[ty] Infer typevars through a nominal type[…] formal#27689
charliermarsh merged 2 commits into
astral-sh:mainfrom
augustelalande:ty-nominal-subclass-of-inference

Conversation

@augustelalande

Copy link
Copy Markdown
Contributor

Summary

This adds typevar inference through a nominal type[…] formal.

Closes astral-sh/ty#3576.

Test Plan

Added mdtests.

Given `def f(x: type[list[T]]) -> T`, calling `f(list[int])` inferred `Unknown`
rather than `int`. The same held for a subclass: with `class Sub(list[int])`,
`f(Sub)` was also `Unknown`, even though the specialization is written on `Sub`'s
bases.

`SpecializationBuilder::infer_map_impl` handles a `type[…]` formal only when its
inner type is a protocol; there was no arm for a nominal class, so neither
typevar was ever bound and both fell back to `Unknown`.

Add that arm, using constraint-set assignability as the method's own comment asks
of new heuristics, rather than extending the hash-map MRO walk below it that is
slated to be replaced.

Closes astral-sh/ty#3576, whose example is included as a test. Note that example
uses a subclass, which makes the gap look narrower than it is: a direct match with
no subclassing involved failed identically, so this is about nominal `type[…]`
formals in general rather than about reading a specialization off a base class.
The issue also notes that the resulting `Unknown` swallowed a downstream error;
that error is now reported.

The tests also cover the shape this takes in real stubs — a generic base declaring
the parameters, a concrete class fixing them, and a factory taking the class object
and returning a generic container. Every step of that chain was previously
`Unknown`:

    create_client(MyService)  Client[Unknown, Unknown] -> Client[MyRequest, MyResponse]
    .call_async(...)          Future[Unknown]          -> Future[MyResponse]
    .result()                 Unknown | None           -> MyResponse | None

pyright agrees on all of these.

## Test Plan

`cargo test -p ty_python_semantic` — 482 mdtests, 311 unit tests, no failures and
no snapshot changes. `cargo fmt --check` and
`cargo clippy -p ty_python_semantic --all-targets -- -D warnings` clean.
@augustelalande
augustelalande requested a review from a team as a code owner August 12, 2026 02:30
@astral-sh-bot
astral-sh-bot Bot requested a review from charliermarsh August 12, 2026 02:30
@astral-sh-bot astral-sh-bot Bot added the ty Multi-file analysis & type inference label Aug 12, 2026
@astral-sh-bot

astral-sh-bot Bot commented Aug 12, 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 96.98%. The percentage of expected errors that received a diagnostic held steady at 93.62%. The number of fully passing files held steady at 106/133.

@astral-sh-bot

astral-sh-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

Memory usage report

Summary

Project Old New Diff Outcome
prefect 449.04MB 449.12MB +0.02% (88.49kB)
sphinx 164.73MB 164.73MB +0.00% (1.36kB)
flake8 39.70MB 39.70MB -
trio 92.27MB 92.27MB -

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
when_constraint_set_assignable_to_owned_impl 5.29MB 5.32MB +0.56% (30.46kB)
TypePair 7.72MB 7.74MB +0.21% (16.78kB)
Type<'db>::class_member_with_policy_inner_ 8.70MB 8.70MB +0.08% (7.30kB)
StaticClassLiteral<'db>::try_mro_specialized_ 4.22MB 4.22MB +0.14% (5.94kB)
is_redundant_with_impl 3.30MB 3.30MB +0.12% (4.08kB)
Type<'db>::apply_specialization_inner_::interned_arguments 5.15MB 5.15MB +0.04% (2.27kB)
member_lookup_with_policy_inner 8.91MB 8.91MB +0.02% (2.21kB)
Type<'db>::apply_specialization_inner_ 3.42MB 3.43MB +0.06% (2.19kB)
infer_expression_types_impl 23.31MB 23.31MB +0.01% (1.70kB)
Specialization 4.57MB 4.58MB +0.04% (1.64kB)
MemberLookupKey 6.89MB 6.89MB +0.02% (1.50kB)
infer_definition_types 34.55MB 34.55MB +0.00% (1.45kB)
ClassType<'db>::nearest_disjoint_base_ 325.98kB 327.39kB +0.43% (1.41kB)
UnionType 1.36MB 1.36MB +0.09% (1.28kB)
IntersectionType 1.56MB 1.56MB +0.07% (1.18kB)
... 20 more

sphinx

Name Old New Diff Outcome
when_constraint_set_assignable_to_owned_impl 1.41MB 1.41MB +0.05% (776.00B)
TypePair 2.12MB 2.12MB +0.02% (384.00B)
Type<'db>::cached_materialization_::interned_arguments 375.00kB 375.08kB +0.02% (80.00B)
infer_expression_types_impl 11.53MB 11.53MB +0.00% (72.00B)
Type<'db>::cached_materialization_ 246.94kB 246.98kB +0.02% (48.00B)
infer_scope_types_impl 6.08MB 6.08MB +0.00% (32.00B)

@astral-sh-bot

astral-sh-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-argument-type 0 6 26
invalid-assignment 0 0 21
unsupported-operator 0 0 8
invalid-return-type 0 0 5
unsound-yield 0 5 0
unresolved-attribute 0 0 4
not-subscriptable 0 0 2
type-assertion-failure 0 2 0
unsound-return-statement 0 0 2
unused-type-ignore-comment 0 1 0
Total 0 14 68
Raw diff (82 changes)
bokeh (https://github.com/bokeh/bokeh)
- src/bokeh/model/model.py:348:30 error[unresolved-attribute] Object of type `Dict[Unknown, list[Unknown]]` has no attribute `get`
+ src/bokeh/model/model.py:348:30 error[unresolved-attribute] Object of type `Dict[str, list[Unknown]]` has no attribute `get`
- src/bokeh/model/model.py:354:9 error[invalid-assignment] Cannot assign to a subscript on an object of type `Dict[Unknown, list[Unknown]]`
+ src/bokeh/model/model.py:354:9 error[invalid-assignment] Cannot assign to a subscript on an object of type `Dict[str, list[Unknown]]`
- src/bokeh/model/model.py:475:52 error[unresolved-attribute] Object of type `Dict[Unknown, list[Unknown]]` has no attribute `items`
+ src/bokeh/model/model.py:475:52 error[unresolved-attribute] Object of type `Dict[str, list[Unknown]]` has no attribute `items`
- src/bokeh/model/model.py:476:12 error[unsupported-operator] Operator `not in` is not supported between objects of type `str` and `Dict[Unknown, list[Unknown]]`
+ src/bokeh/model/model.py:476:12 error[unsupported-operator] Operator `not in` is not supported between objects of type `str` and `Dict[str, list[Unknown]]`
- src/bokeh/model/model.py:477:13 error[invalid-assignment] Cannot assign to a subscript on an object of type `Dict[Unknown, list[Unknown]]`
+ src/bokeh/model/model.py:477:13 error[invalid-assignment] Cannot assign to a subscript on an object of type `Dict[str, list[Unknown]]`
- src/bokeh/model/model.py:479:28 error[not-subscriptable] Cannot subscript object of type `Dict[Unknown, list[Unknown]]` with no `__getitem__` method
+ src/bokeh/model/model.py:479:28 error[not-subscriptable] Cannot subscript object of type `Dict[str, list[Unknown]]` with no `__getitem__` method
- src/bokeh/model/model.py:481:13 error[not-subscriptable] Cannot subscript object of type `Dict[Unknown, list[Unknown]]` with no `__getitem__` method
+ src/bokeh/model/model.py:481:13 error[not-subscriptable] Cannot subscript object of type `Dict[str, list[Unknown]]` with no `__getitem__` method
- src/bokeh/models/annotations/dimensional.py:106:16 error[unsupported-operator] Operator `in` is not supported between objects of type `str` and `Required[dict[Unknown, Any]]`
+ src/bokeh/models/annotations/dimensional.py:106:16 error[unsupported-operator] Operator `in` is not supported between objects of type `str` and `Required[dict[str, Any]]`
- src/bokeh/models/annotations/geometry.py:224:29 error[invalid-argument-type] Argument to `NonNegative.__init__` is incorrect: Expected `TypeOrInst[Property[int]]`, found `<class 'Float'>`
- src/bokeh/models/annotations/geometry.py:231:30 error[invalid-argument-type] Argument to `NonNegative.__init__` is incorrect: Expected `TypeOrInst[Property[int]]`, found `<class 'Float'>`
- src/bokeh/models/callbacks.py:257:17 error[invalid-assignment] Object of type `Required[Unknown]` is not assignable to `str`
+ src/bokeh/models/callbacks.py:257:17 error[invalid-assignment] Object of type `Required[str]` is not assignable to `str`
- src/bokeh/models/glyphs.py:1593:30 error[invalid-argument-type] Argument to `NonNegative.__init__` is incorrect: Expected `TypeOrInst[Property[int]]`, found `<class 'Float'>`
- src/bokeh/models/glyphs.py:1597:29 error[invalid-argument-type] Argument to `NonNegative.__init__` is incorrect: Expected `TypeOrInst[Property[int]]`, found `<class 'Float'>`
- src/bokeh/models/layouts.py:321:17 error[unsupported-operator] Operator `<=` is not supported between two objects of type `Nullable[Unknown]`
+ src/bokeh/models/layouts.py:321:17 error[unsupported-operator] Operator `<=` is not supported between two objects of type `Nullable[int]`
- src/bokeh/models/layouts.py:321:30 error[unsupported-operator] Operator `<=` is not supported between two objects of type `Nullable[Unknown]`
+ src/bokeh/models/layouts.py:321:30 error[unsupported-operator] Operator `<=` is not supported between two objects of type `Nullable[int]`
- src/bokeh/models/layouts.py:330:17 error[unsupported-operator] Operator `<=` is not supported between two objects of type `Nullable[Unknown]`
+ src/bokeh/models/layouts.py:330:17 error[unsupported-operator] Operator `<=` is not supported between two objects of type `Nullable[int]`
- src/bokeh/models/layouts.py:330:31 error[unsupported-operator] Operator `<=` is not supported between two objects of type `Nullable[Unknown]`
+ src/bokeh/models/layouts.py:330:31 error[unsupported-operator] Operator `<=` is not supported between two objects of type `Nullable[int]`
- src/bokeh/models/layouts.py:335:20 error[invalid-return-type] Return type does not match returned value: expected `int | None`, found `Nullable[Unknown]`
+ src/bokeh/models/layouts.py:335:20 error[invalid-return-type] Return type does not match returned value: expected `int | None`, found `Nullable[int]`
- src/bokeh/models/plots.py:483:25 error[unresolved-attribute] Object of type `Dict[Unknown, Range]` has no attribute `values`
+ src/bokeh/models/plots.py:483:25 error[unresolved-attribute] Object of type `Dict[str, Range]` has no attribute `values`
- src/bokeh/models/plots.py:485:25 error[unresolved-attribute] Object of type `Dict[Unknown, Range]` has no attribute `values`
+ src/bokeh/models/plots.py:485:25 error[unresolved-attribute] Object of type `Dict[str, Range]` has no attribute `values`
- src/bokeh/models/ranges.py:405:22 error[invalid-argument-type] Argument to `Readonly.__init__` is incorrect: Expected `TypeOrInst[Property[int]]`, found `<class 'Float'>`
- src/bokeh/models/ranges.py:415:20 error[invalid-argument-type] Argument to `Readonly.__init__` is incorrect: Expected `TypeOrInst[Property[int]]`, found `<class 'Float'>`
- src/bokeh/models/renderers/contour_renderer.py:116:13 error[invalid-argument-type] Argument to `ContourColorBar.__init__` is incorrect: Expected `Sequence[float]`, found `Seq[Unknown, list[Unknown]]`
+ src/bokeh/models/renderers/contour_renderer.py:116:13 error[invalid-argument-type] Argument to `ContourColorBar.__init__` is incorrect: Expected `Sequence[float]`, found `Seq[float, list[Unknown]]`
- src/bokeh/models/renderers/contour_renderer.py:117:32 error[invalid-argument-type] Argument to `FixedTicker.__init__` is incorrect: Expected `Sequence[float]`, found `Seq[Unknown, list[Unknown]]`
+ src/bokeh/models/renderers/contour_renderer.py:117:32 error[invalid-argument-type] Argument to `FixedTicker.__init__` is incorrect: Expected `Sequence[float]`, found `Seq[float, list[Unknown]]`
- src/bokeh/models/tools.py:1597:93 error[invalid-argument-type] Argument to `Dict.__init__` is incorrect: Expected `Init[dict[Unknown, Any]]`, found `() -> dict[Unknown, Unknown]`
+ src/bokeh/models/tools.py:1597:93 error[invalid-argument-type] Argument to `Dict.__init__` is incorrect: Expected `Init[dict[str, Any]]`, found `() -> dict[Unknown, Unknown]`
- src/bokeh/models/widgets/sliders.py:239:43 error[unsupported-operator] Operator `/` is not supported between objects of type `Required[Unknown] & Number` and `Literal[1000]`
+ src/bokeh/models/widgets/sliders.py:239:43 error[unsupported-operator] Operator `/` is not supported between objects of type `Required[str | date] & Number` and `Literal[1000]`
- src/bokeh/models/widgets/sliders.py:241:16 error[invalid-return-type] Return type does not match returned value: expected `datetime | None`, found `Required[Unknown] & ~Number`
+ src/bokeh/models/widgets/sliders.py:241:16 error[invalid-return-type] Return type does not match returned value: expected `datetime | None`, found `Required[str | date] & ~Number`
- src/bokeh/models/widgets/sliders.py:253:41 error[unsupported-operator] Operator `/` is not supported between objects of type `Required[Unknown] & Number` and `Literal[1000]`
+ src/bokeh/models/widgets/sliders.py:253:41 error[unsupported-operator] Operator `/` is not supported between objects of type `Required[str | date] & Number` and `Literal[1000]`
- src/bokeh/models/widgets/sliders.py:256:16 error[invalid-return-type] Return type does not match returned value: expected `date | None`, found `Required[Unknown] & ~Number`
+ src/bokeh/models/widgets/sliders.py:256:16 error[invalid-return-type] Return type does not match returned value: expected `date | None`, found `Required[str | date] & ~Number`
- src/bokeh/server/server.py:683:28 error[invalid-assignment] Object of type `Nullable[Unknown]` is not assignable to `str | None`
+ src/bokeh/server/server.py:683:28 error[invalid-assignment] Object of type `Nullable[str]` is not assignable to `str | None`
- src/bokeh/server/server.py:691:32 error[invalid-assignment] Object of type `Nullable[Unknown]` is not assignable to `str | None`
+ src/bokeh/server/server.py:691:32 error[invalid-assignment] Object of type `Nullable[str]` is not assignable to `str | None`
- src/bokeh/server/server.py:701:25 error[invalid-assignment] Object of type `Nullable[Unknown]` is not assignable to `str | None`
+ src/bokeh/server/server.py:701:25 error[invalid-assignment] Object of type `Nullable[str]` is not assignable to `str | None`
- src/bokeh/server/server.py:705:48 error[invalid-assignment] Object of type `Nullable[list[Unknown]]` is not assignable to `list[str] | None`
+ src/bokeh/server/server.py:705:48 error[invalid-assignment] Object of type `Nullable[list[str]]` is not assignable to `list[str] | None`
- src/bokeh/server/server.py:720:32 error[invalid-assignment] Object of type `Nullable[Unknown]` is not assignable to `str | None`
+ src/bokeh/server/server.py:720:32 error[invalid-assignment] Object of type `Nullable[str]` is not assignable to `str | None`
- src/bokeh/server/server.py:724:31 error[invalid-assignment] Object of type `Nullable[Unknown]` is not assignable to `str | None`
+ src/bokeh/server/server.py:724:31 error[invalid-assignment] Object of type `Nullable[str]` is not assignable to `str | None`
- src/bokeh/server/server.py:728:32 error[invalid-assignment] Object of type `Nullable[Unknown]` is not assignable to `str | None`
+ src/bokeh/server/server.py:728:32 error[invalid-assignment] Object of type `Nullable[str]` is not assignable to `str | None`

hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
- tests/annotations/declarations.py:1402:5 error[type-assertion-failure] Type `PBuilds[Unknown]` does not match asserted type `PBuilds[int]`
- tests/annotations/declarations.py:1406:25 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- tests/annotations/declarations.py:1409:5 error[type-assertion-failure] Type `FullBuilds[Unknown]` does not match asserted type `FullBuilds[int]`

optuna (https://github.com/optuna/optuna)
- optuna/storages/_rdb/models.py:206:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `_datetime_start_utc` on type `Self@datetime_start`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
+ optuna/storages/_rdb/models.py:206:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `_datetime_start_utc` on type `Self@datetime_start`: Argument type `MappedColumn[Any] | Column[datetime]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
- optuna/storages/_rdb/models.py:208:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `_datetime_start_utc` on type `Self@datetime_start`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
+ optuna/storages/_rdb/models.py:208:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `_datetime_start_utc` on type `Self@datetime_start`: Argument type `MappedColumn[Any] | Column[datetime]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
- optuna/storages/_rdb/models.py:223:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `_datetime_complete_utc` on type `Self@datetime_complete`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
+ optuna/storages/_rdb/models.py:223:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `_datetime_complete_utc` on type `Self@datetime_complete`: Argument type `MappedColumn[Any] | Column[datetime]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
- optuna/storages/_rdb/models.py:225:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `_datetime_complete_utc` on type `Self@datetime_complete`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
+ optuna/storages/_rdb/models.py:225:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `_datetime_complete_utc` on type `Self@datetime_complete`: Argument type `MappedColumn[Any] | Column[datetime]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
- optuna/storages/_rdb/models.py:266:16 warning[unsound-return-statement] Unsound return statement: `Unknown` is not a subtype of `int`
+ optuna/storages/_rdb/models.py:266:16 warning[unsound-return-statement] Unsound return statement: `Any` is not a subtype of `int`
- optuna/storages/_rdb/models.py:301:16 warning[unsound-return-statement] Unsound return statement: `Unknown` is not a subtype of `int`
+ optuna/storages/_rdb/models.py:301:16 warning[unsound-return-statement] Unsound return statement: `Any` is not a subtype of `int`
- optuna/storages/_rdb/storage.py:361:16 error[invalid-return-type] Return type does not match returned value: expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:361:16 error[invalid-return-type] Return type does not match returned value: expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:480:17 error[invalid-assignment] Object of type `Any | Column[Unknown]` is not assignable to attribute `number` on type `FrozenTrial & ~AlwaysFalsy`
+ optuna/storages/_rdb/storage.py:480:17 error[invalid-assignment] Object of type `Any | Column[int]` is not assignable to attribute `number` on type `FrozenTrial & ~AlwaysFalsy`
- optuna/storages/_rdb/storage.py:482:17 error[invalid-assignment] Object of type `Any | Column[Unknown]` is not assignable to attribute `_trial_id` on type `FrozenTrial & ~AlwaysFalsy`
+ optuna/storages/_rdb/storage.py:482:17 error[invalid-assignment] Object of type `Any | Column[int]` is not assignable to attribute `_trial_id` on type `FrozenTrial & ~AlwaysFalsy`
- optuna/storages/_rdb/storage.py:485:17 error[invalid-argument-type] Argument to `FrozenTrial.__init__` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:485:17 error[invalid-argument-type] Argument to `FrozenTrial.__init__` is incorrect: Expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:496:17 error[invalid-argument-type] Argument to `FrozenTrial.__init__` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:496:17 error[invalid-argument-type] Argument to `FrozenTrial.__init__` is incorrect: Expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:571:30 error[invalid-argument-type] Argument to bound method `RDBStorage._set_trial_param_without_commit` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:571:30 error[invalid-argument-type] Argument to bound method `RDBStorage._set_trial_param_without_commit` is incorrect: Expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:576:62 error[invalid-argument-type] Argument to bound method `RDBStorage._set_trial_attr_without_commit` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:576:62 error[invalid-argument-type] Argument to bound method `RDBStorage._set_trial_attr_without_commit` is incorrect: Expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:581:64 error[invalid-argument-type] Argument to bound method `RDBStorage._set_trial_attr_without_commit` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:581:64 error[invalid-argument-type] Argument to bound method `RDBStorage._set_trial_attr_without_commit` is incorrect: Expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:586:30 error[invalid-argument-type] Argument to bound method `RDBStorage._set_trial_intermediate_value_without_commit` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:586:30 error[invalid-argument-type] Argument to bound method `RDBStorage._set_trial_intermediate_value_without_commit` is incorrect: Expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:591:9 error[invalid-assignment] Invalid assignment to data descriptor attribute `number` on type `TrialModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
+ optuna/storages/_rdb/storage.py:591:9 error[invalid-assignment] Invalid assignment to data descriptor attribute `number` on type `TrialModel`: Argument type `MappedColumn[Any] | Column[int]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
- optuna/storages/_rdb/storage.py:703:39 error[invalid-argument-type] Argument to bound method `BaseStorage.check_trial_is_updatable` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:703:39 error[invalid-argument-type] Argument to bound method `BaseStorage.check_trial_is_updatable` is incorrect: Expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:939:13 error[invalid-argument-type] Argument to `FrozenTrial.__init__` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:939:13 error[invalid-argument-type] Argument to `FrozenTrial.__init__` is incorrect: Expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:965:13 error[invalid-argument-type] Argument to `FrozenTrial.__init__` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ optuna/storages/_rdb/storage.py:965:13 error[invalid-argument-type] Argument to `FrozenTrial.__init__` is incorrect: Expected `int`, found `Any | Column[int]`
- optuna/storages/_rdb/storage.py:1052:17 error[invalid-assignment] Invalid assignment to data descriptor attribute `heartbeat` on type `TrialHeartbeatModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
+ optuna/storages/_rdb/storage.py:1052:17 error[invalid-assignment] Invalid assignment to data descriptor attribute `heartbeat` on type `TrialHeartbeatModel`: Argument type `MappedColumn[Any] | Column[datetime]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
- optuna/storages/_rdb/storage.py:1085:16 error[invalid-return-type] Return type does not match returned value: expected `list[int]`, found `list[Any | Column[Unknown] | int]`
+ optuna/storages/_rdb/storage.py:1085:16 error[invalid-return-type] Return type does not match returned value: expected `list[int]`, found `list[Any | Column[int] | int]`
- optuna/storages/_rdb/storage.py:1210:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `schema_version` on type `VersionInfoModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
+ optuna/storages/_rdb/storage.py:1210:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `schema_version` on type `VersionInfoModel`: Argument type `MappedColumn[Any] | Column[int]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
- tests/storages_tests/rdb_tests/test_models.py:53:60 error[invalid-argument-type] Argument to bound method `StudyDirectionModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:53:60 error[invalid-argument-type] Argument to bound method `StudyDirectionModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:66:60 error[invalid-argument-type] Argument to bound method `StudyDirectionModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:66:60 error[invalid-argument-type] Argument to bound method `StudyDirectionModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:71:60 error[invalid-argument-type] Argument to bound method `StudyDirectionModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:71:60 error[invalid-argument-type] Argument to bound method `StudyDirectionModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:99:66 error[invalid-argument-type] Argument to bound method `StudySystemAttributeModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:99:66 error[invalid-argument-type] Argument to bound method `StudySystemAttributeModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:100:66 error[invalid-argument-type] Argument to bound method `StudySystemAttributeModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:100:66 error[invalid-argument-type] Argument to bound method `StudySystemAttributeModel.where_study_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:301:55 error[invalid-argument-type] Argument to bound method `TrialValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:301:55 error[invalid-argument-type] Argument to bound method `TrialValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:316:56 error[invalid-argument-type] Argument to bound method `TrialValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:316:56 error[invalid-argument-type] Argument to bound method `TrialValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:321:56 error[invalid-argument-type] Argument to bound method `TrialValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:321:56 error[invalid-argument-type] Argument to bound method `TrialValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:357:13 error[invalid-argument-type] Argument to bound method `TrialIntermediateValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:357:13 error[invalid-argument-type] Argument to bound method `TrialIntermediateValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:376:68 error[invalid-argument-type] Argument to bound method `TrialIntermediateValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:376:68 error[invalid-argument-type] Argument to bound method `TrialIntermediateValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:381:68 error[invalid-argument-type] Argument to bound method `TrialIntermediateValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:381:68 error[invalid-argument-type] Argument to bound method `TrialIntermediateValueModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:399:62 error[invalid-argument-type] Argument to bound method `TrialHeartbeatModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:399:62 error[invalid-argument-type] Argument to bound method `TrialHeartbeatModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:408:51 error[invalid-argument-type] Argument to bound method `TrialHeartbeatModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:408:51 error[invalid-argument-type] Argument to bound method `TrialHeartbeatModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_models.py:413:51 error[invalid-argument-type] Argument to bound method `TrialHeartbeatModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[Unknown]`
+ tests/storages_tests/rdb_tests/test_models.py:413:51 error[invalid-argument-type] Argument to bound method `TrialHeartbeatModel.where_trial_id` is incorrect: Expected `int`, found `Any | Column[int]`
- tests/storages_tests/rdb_tests/test_storage.py:160:9 error[invalid-assignment] Invalid assignment to data descriptor attribute `schema_version` on type `VersionInfoModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
+ tests/storages_tests/rdb_tests/test_storage.py:160:9 error[invalid-assignment] Invalid assignment to data descriptor attribute `schema_version` on type `VersionInfoModel`: Argument type `MappedColumn[Any] | Column[int]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
- tests/storages_tests/rdb_tests/test_storage.py:361:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `number` on type `TrialModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`
+ tests/storages_tests/rdb_tests/test_storage.py:361:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `number` on type `TrialModel`: Argument type `MappedColumn[Any] | Column[int]` does not satisfy upper bound `Mapped[_T_co@Mapped]` of type variable `Self`

pytest (https://github.com/pytest-dev/pytest)
- src/_pytest/capture.py:1029:11 warning[unsound-yield] Unsound `yield`: `CaptureFixture[Unknown]` is not a subtype of `CaptureFixture[str]`
- src/_pytest/capture.py:1064:11 warning[unsound-yield] Unsound `yield`: `CaptureFixture[Unknown]` is not a subtype of `CaptureFixture[str]`
- src/_pytest/capture.py:1092:11 warning[unsound-yield] Unsound `yield`: `CaptureFixture[Unknown]` is not a subtype of `CaptureFixture[bytes]`
- src/_pytest/capture.py:1120:11 warning[unsound-yield] Unsound `yield`: `CaptureFixture[Unknown]` is not a subtype of `CaptureFixture[str]`
- src/_pytest/capture.py:1149:11 warning[unsound-yield] Unsound `yield`: `CaptureFixture[Unknown]` is not a subtype of `CaptureFixture[bytes]`

Full report with detailed diff (timing results)

@charliermarsh
charliermarsh merged commit 409be9c into astral-sh:main Aug 12, 2026
64 checks passed
@augustelalande
augustelalande deleted the ty-nominal-subclass-of-inference branch August 12, 2026 17:23
George-Ogden pushed a commit to George-Ogden/ruff that referenced this pull request Aug 16, 2026
## Summary
This adds typevar inference through a nominal `type[…]` formal.

Closes astral-sh/ty#3576.

## Test Plan
Added mdtests.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
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.

Imprecise type inference with complex generic + type[]

2 participants