Skip to content

[ty] Allow partially stringified type[…] annotations#24518

Merged
sharkdp merged 4 commits intomainfrom
david/fix-3244
Apr 9, 2026
Merged

[ty] Allow partially stringified type[…] annotations#24518
sharkdp merged 4 commits intomainfrom
david/fix-3244

Conversation

@sharkdp
Copy link
Copy Markdown
Contributor

@sharkdp sharkdp commented Apr 9, 2026

Summary

Allow partially stringified type["ForwardRef"] annotations, even if they are not explicitly allowed by the typing spec. The implementation here follows what we do in e.g. infer_string_type_expression.

closes astral-sh/ty#3244

Ecosystem

We apparently get rid of a prevalent @Todo type, so we see new diagnostics, but nothing that looks like new false positives, related to this change. A lot of ecosystem hits have an ignore-comment for another type checker, which is generally a good signal.

Test Plan

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

astral-sh-bot Bot commented Apr 9, 2026

Typing conformance results

No changes detected ✅

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

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented Apr 9, 2026

Memory usage report

Summary

Project Old New Diff Outcome
prefect 716.87MB 716.90MB +0.00% (33.36kB)
flake8 47.96MB 47.96MB -
sphinx 264.09MB 264.09MB -
trio 117.57MB 117.57MB -

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
infer_deferred_types 14.42MB 14.42MB +0.04% (6.34kB)
Type<'db>::class_member_with_policy_ 18.06MB 18.06MB +0.02% (4.18kB)
infer_scope_types_impl 54.23MB 54.23MB +0.00% (2.77kB)
infer_definition_types 89.93MB 89.94MB +0.00% (2.65kB)
Type<'db>::member_lookup_with_policy_ 16.40MB 16.41MB +0.01% (2.38kB)
Type<'db>::try_call_dunder_get_ 10.83MB 10.83MB +0.02% (2.32kB)
StaticClassLiteral<'db>::implicit_attribute_inner_ 10.01MB 10.02MB +0.02% (1.83kB)
infer_expression_types_impl 62.21MB 62.21MB +0.00% (1.56kB)
Type<'db>::class_member_with_policy_::interned_arguments 9.75MB 9.75MB +0.02% (1.52kB)
Type<'db>::apply_specialization_ 3.69MB 3.69MB +0.04% (1.43kB)
is_redundant_with_impl 5.52MB 5.52MB +0.03% (1.43kB)
StaticClassLiteral<'db>::implicit_attribute_inner_::interned_arguments 5.31MB 5.31MB +0.03% (1.41kB)
Type<'db>::try_call_dunder_get_::interned_arguments 3.09MB 3.09MB +0.02% (624.00B)
FunctionType<'db>::signature_ 4.02MB 4.02MB +0.01% (536.00B)
lookup_dunder_new_inner 278.61kB 279.01kB +0.14% (412.00B)
... 27 more

self.store_expression_type(slice, parameters_ty);
parameters_ty
}
// TODO: subscripts, etc.
Copy link
Copy Markdown
Contributor Author

@sharkdp sharkdp Apr 9, 2026

Choose a reason for hiding this comment

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

Not really sure what "subscripts, etc" means. What else needs to be supported to get rid of the todo type below?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the comment was outdated -- it dates from before we supported type[list[int]] etc.

We might be able to get rid of the Todo type entirely now -- not sure

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We might be able to get rid of the Todo type entirely now -- not sure

Will try that as a separate change.

Copy link
Copy Markdown
Contributor Author

@sharkdp sharkdp Apr 13, 2026

Choose a reason for hiding this comment

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

That actually still appears in our mdtests, and generally, there are too many TODOs still in that function, so this is not a simple change, I'm afraid (and not something I'll prioritize now).

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented Apr 9, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-argument-type 53 0 3
invalid-await 0 40 0
unused-type-ignore-comment 0 26 0
invalid-assignment 3 0 3
unknown-argument 5 0 0
unresolved-attribute 3 0 2
possibly-missing-submodule 4 0 0
unsupported-operator 4 0 0
invalid-type-form 3 0 0
call-top-callable 2 0 0
invalid-return-type 0 1 1
call-non-callable 1 0 0
invalid-parameter-default 0 0 1
missing-argument 1 0 0
not-iterable 1 0 0
redundant-cast 1 0 0
Total 81 67 10

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

Raw diff (115 changes)
comtypes (https://github.com/enthought/comtypes)
- comtypes/_meta.py:65:63 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- comtypes/_post_coinit/unknwn.py:228:63 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive

dulwich (https://github.com/dulwich/dulwich)
+ dulwich/object_store.py:3636:26 error[invalid-assignment] Object of type `Unknown | bytes` is not assignable to `ObjectID | RawObjectID`

hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
- src/hydra_zen/wrapper/_implementations.py:1480:9 error[invalid-parameter-default] Default value of type `def default_to_config(target: ((...) -> Any) | DataClass_ | list[Any] | ... omitted 3 union elements, CustomBuildsFn: @Todo = ..., **kw: Any) -> DataClass_ | type[@Todo] | ListConfig | DictConfig` is not assignable to annotated parameter type `(F@__call__, /) -> Any`
+ src/hydra_zen/wrapper/_implementations.py:1480:9 error[invalid-parameter-default] Default value of type `def default_to_config(target: ((...) -> Any) | DataClass_ | list[Any] | ... omitted 3 union elements, CustomBuildsFn: type[BuildsFn[Any]] = ..., **kw: Any) -> DataClass_ | type[@Todo] | ListConfig | DictConfig` is not assignable to annotated parameter type `(F@__call__, /) -> Any`

jinja (https://github.com/pallets/jinja)
- src/jinja2/compiler.py:120:45 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ tests/test_runtime.py:42:40 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `type[Undefined]`, found `None`
+ tests/test_runtime.py:48:40 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `type[Undefined]`, found `None`
+ tests/test_runtime.py:54:40 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `type[Undefined]`, found `None`

meson (https://github.com/mesonbuild/meson)
+ mesonbuild/interpreterbase/decorators.py:520:119 error[invalid-argument-type] Argument to bound method `single_use` is incorrect: Expected `str`, found `str | None`
+ mesonbuild/interpreterbase/decorators.py:520:119 error[invalid-argument-type] Argument to bound method `single_use` is incorrect: Expected `str`, found `str | None`
+ mesonbuild/linkers/detect.py:79:45 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:83:63 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:88:13 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:104:13 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:134:60 error[invalid-argument-type] Argument to bound method `_unix_args_to_native` is incorrect: Expected `MachineInfo`, found `Unknown | MachineInfo | None`
+ mesonbuild/linkers/detect.py:139:22 error[unsupported-operator] Operator `+` is not supported between objects of type `None | list[str]` and `list[str]`
+ mesonbuild/linkers/detect.py:159:19 error[unsupported-operator] Operator `+` is not supported between objects of type `list[str]` and `None | list[str]`
+ mesonbuild/linkers/detect.py:169:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:169:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:172:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:175:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:193:72 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:204:54 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:204:54 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:204:54 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:213:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:219:34 error[unsupported-operator] Operator `+` is not supported between objects of type `list[str]` and `None | list[str]`
+ mesonbuild/linkers/detect.py:221:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:225:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:231:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:243:19 error[unsupported-operator] Operator `+` is not supported between objects of type `list[str]` and `None | list[str]`
+ mesonbuild/linkers/detect.py:253:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:258:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
+ mesonbuild/linkers/detect.py:262:41 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`

paasta (https://github.com/yelp/paasta)
- paasta_tools/metrics/metrics_lib.py:91:12 error[invalid-argument-type] Method `__getitem__` of type `bound method dict[str, @Todo].__getitem__(key: str, /) -> @Todo` cannot be called with key of type `None` on object of type `dict[str, @Todo]`
+ paasta_tools/metrics/metrics_lib.py:91:12 error[invalid-argument-type] Method `__getitem__` of type `bound method dict[str, type[BaseMetrics]].__getitem__(key: str, /) -> type[BaseMetrics]` cannot be called with key of type `None` on object of type `dict[str, type[BaseMetrics]]`
- paasta_tools/metrics/metrics_lib.py:98:9 error[invalid-assignment] Invalid subscript assignment with key of type `str | None` and value of type `type[BaseMetrics]` on object of type `dict[str, @Todo]`
+ paasta_tools/metrics/metrics_lib.py:98:9 error[invalid-assignment] Invalid subscript assignment with key of type `str | None` and value of type `type[BaseMetrics]` on object of type `dict[str, type[BaseMetrics]]`

pydantic (https://github.com/pydantic/pydantic)
+ pydantic/v1/annotated_types.py:13:50 error[invalid-type-form] The special form `typing.TypedDict` is not allowed in parameter annotations
+ pydantic/v1/annotated_types.py:24:26 error[invalid-type-form] The special form `typing.TypedDict` is not allowed in parameter annotations
+ pydantic/v1/dataclasses.py:305:25 error[unresolved-attribute] Object of type `(...) -> None` has no attribute `__wrapped__`
+ pydantic/v1/dataclasses.py:500:32 error[invalid-argument-type] Argument to function `_get_validators` is incorrect: Expected `type[Dataclass] | DataclassProxy`, found `<decorator produced by dataclass-like function>`
+ pydantic/v1/main.py:600:68 error[invalid-argument-type] Argument to function `validate_model` is incorrect: Expected `dict[str, Any]`, found `dict[str, Any] | GetterDict`
+ pydantic/v1/schema.py:593:13 error[call-top-callable] Object of type `Top[(...) -> object]` is not safe to call; its signature is not known
+ pydantic/v1/schema.py:595:13 error[call-top-callable] Object of type `Top[(...) -> object]` is not safe to call; its signature is not known
- pydantic/v1/utils.py:305:45 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ pydantic/v1/validators.py:621:26 error[invalid-type-form] The special form `typing.TypedDict` is not allowed in parameter annotations

rotki (https://github.com/rotki/rotki)
- rotkehlchen/history/events/structures/evm_swap.py:96:65 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- rotkehlchen/history/events/structures/evm_swap.py:97:72 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- rotkehlchen/history/events/structures/eth2.py:186:43 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- rotkehlchen/history/events/structures/eth2.py:393:38 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- rotkehlchen/history/events/structures/eth2.py:531:34 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- rotkehlchen/history/events/structures/solana_swap.py:93:65 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- rotkehlchen/history/events/structures/solana_swap.py:94:72 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ rotkehlchen/history/events/structures/solana_swap.py:108:23 error[invalid-argument-type] Cannot pop required field 'location' from TypedDict `SwapEventEntryData`
+ rotkehlchen/history/events/structures/solana_swap.py:110:20 error[missing-argument] No argument provided for required parameter `sequence_index` of bound method `__init__`
+ rotkehlchen/history/events/structures/solana_swap.py:111:17 error[unknown-argument] Argument `location` does not match any known parameter of bound method `__init__`
+ rotkehlchen/history/events/structures/solana_swap.py:111:17 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `TimestampMS`, found `str | None`
+ rotkehlchen/history/events/structures/solana_swap.py:111:17 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `Location`
- rotkehlchen/history/events/structures/swap.py:131:72 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ rotkehlchen/history/events/structures/swap.py:186:20 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `SwapEventExtraData | None`, found `dict[str, Any] | None`
+ rotkehlchen/history/events/structures/swap.py:186:20 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `str | None`

spack (https://github.com/spack/spack)
+ lib/spack/spack/version/git_ref_lookup.py:79:17 error[unresolved-attribute] Object of type `type[PackageBase]` has no attribute `git`
+ lib/spack/spack/audit.py:692:22 error[not-iterable] Object of type `Collection[Unknown] | None` may not be iterable
- lib/spack/spack/builder.py:187:62 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ lib/spack/spack/detection/path.py:228:45 warning[possibly-missing-submodule] Submodule `package_base` might not have been imported
+ lib/spack/spack/detection/path.py:254:29 warning[possibly-missing-submodule] Submodule `package_base` might not have been imported
+ lib/spack/spack/detection/path.py:360:45 warning[possibly-missing-submodule] Submodule `package_base` might not have been imported
+ lib/spack/spack/detection/path.py:386:45 warning[possibly-missing-submodule] Submodule `package_base` might not have been imported
+ lib/spack/spack/fetch_strategy.py:1509:73 error[invalid-argument-type] Argument to function `hasattr` is incorrect: Expected `str`, found `str | None`
+ lib/spack/spack/fetch_strategy.py:1686:25 error[invalid-argument-type] Argument to function `hasattr` is incorrect: Expected `str`, found `str | None`
+ lib/spack/spack/fetch_strategy.py:1696:25 error[invalid-argument-type] Argument to function `hasattr` is incorrect: Expected `str`, found `str | None`
- lib/spack/spack/fetch_strategy.py:1517:42 error[invalid-argument-type] Argument to function `quote` is incorrect: Expected `list[str]`, found `set[@Todo]`
+ lib/spack/spack/fetch_strategy.py:1517:42 error[invalid-argument-type] Argument to function `quote` is incorrect: Expected `list[str]`, found `set[str | None]`
+ lib/spack/spack/solver/asp.py:3099:21 error[call-non-callable] Object of type `object` is not callable
+ lib/spack/spack/test/cmd/checksum.py:309:27 error[unresolved-attribute] Object of type `type[PackageBase]` has no attribute `url`
- lib/spack/spack/test/cmd/dev_build.py:322:72 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- lib/spack/spack/test/cmd/dev_build.py:323:52 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- lib/spack/spack/test/cmd/dev_build.py:332:72 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- lib/spack/spack/test/cmd/dev_build.py:333:52 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- lib/spack/spack/test/cmd/dev_build.py:387:71 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- lib/spack/spack/test/cmd/dev_build.py:388:51 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ lib/spack/spack/test/packages.py:326:50 error[invalid-argument-type] Argument to function `deprecated_version` is incorrect: Expected `PackageBase`, found `type[PackageBase]`
+ lib/spack/spack/test/packages.py:327:54 error[invalid-argument-type] Argument to function `deprecated_version` is incorrect: Expected `PackageBase`, found `type[PackageBase]`
+ lib/spack/spack/test/patch.py:488:31 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `PackageBase | type[PackageBase]`, found `FakePackage`
+ lib/spack/spack/test/patch.py:490:31 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `PackageBase | type[PackageBase]`, found `FakePackage`
+ lib/spack/spack/test/patch.py:503:30 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `PackageBase | type[PackageBase]`, found `FakePackage`
+ lib/spack/spack/test/patch.py:506:30 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `PackageBase | type[PackageBase]`, found `FakePackage`
+ lib/spack/spack/test/patch.py:515:27 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `PackageBase | type[PackageBase]`, found `FakePackage`
+ lib/spack/spack/test/patch.py:521:35 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `PackageBase | type[PackageBase]`, found `FakePackage`
+ lib/spack/spack/test/patch.py:522:35 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `PackageBase | type[PackageBase]`, found `FakePackage`
+ lib/spack/spack/test/util/package_hash.py:36:42 error[invalid-argument-type] Argument to bound method `content_hash` is incorrect: Expected `bytes | None`, found `str`
+ lib/spack/spack/test/util/package_hash.py:41:42 error[invalid-argument-type] Argument to bound method `content_hash` is incorrect: Expected `bytes | None`, found `str`
- lib/spack/spack/vendor/jinja2/compiler.py:120:45 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive

static-frame (https://github.com/static-frame/static-frame)
- static_frame/core/axis_map.py:163:66 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- static_frame/core/archive_npy.py:706:51 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- static_frame/core/container_util.py:506:45 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- static_frame/core/container_util.py:593:70 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ static_frame/core/container_util.py:576:36 error[invalid-assignment] Object of type `(((...) -> IndexBase) & ~AlwaysFalsy) | (type[Index[Any]] & ~AlwaysFalsy) | (Iterable[((...) -> IndexBase) | type[Index[Any]] | None] & Top[(...) -> object] & ~AlwaysFalsy) | (type[IndexAutoConstructorFactory] & ~AlwaysFalsy)` is not assignable to `((...) -> IndexBase) | type[Index[Any] | IndexConstructorFactoryBase] | None | IndexConstructorFactoryBase`
+ static_frame/core/container_util.py:597:13 error[unknown-argument] Argument `index_constructors` does not match any known parameter of bound method `__init__`
- static_frame/core/container_util.py:504:17 error[invalid-argument-type] Argument to function `to_index` is incorrect: Expected `type[IndexBase]`, found `((...) -> IndexBase) | @Todo | None`
+ static_frame/core/container_util.py:504:17 error[invalid-argument-type] Argument to function `to_index` is incorrect: Expected `type[IndexBase]`, found `((...) -> IndexBase) | type[Index[Any]] | None`
+ static_frame/core/container_util.py:1724:13 error[unknown-argument] Argument `index_constructors` does not match any known parameter of bound method `__init__`
+ static_frame/core/container_util.py:1725:13 error[unknown-argument] Argument `depth_reference` does not match any known parameter of bound method `__init__`
- static_frame/core/frame.py:786:24 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ static_frame/core/frame.py:4633:42 error[invalid-argument-type] Argument to bound method `extend` is incorrect: Expected `Iterable[((...) -> IndexBase) | type[Index[Any]] | None]`, found `GeneratorType[((...) -> IndexBase) | type[Index[Any] | IndexAutoConstructorFactory] | (Iterable[((...) -> IndexBase) | type[Index[Any]] | None] & Top[(...) -> object]), None, None]`
- static_frame/core/index_auto.py:147:26 error[unresolved-attribute] Attribute `STATIC` is not defined on `(...) -> IndexBase` in union `((...) -> IndexBase) | (@Todo & ~None)`
+ static_frame/core/index_auto.py:147:26 error[unresolved-attribute] Attribute `STATIC` is not defined on `(...) -> IndexBase` in union `((...) -> IndexBase) | type[Index[Any]]`
+ static_frame/core/index_hierarchy.py:312:17 error[invalid-argument-type] Argument to function `constructor_from_optional_constructor` is incorrect: Expected `((...) -> IndexBase) | type[Index[Any] | IndexConstructorFactoryBase] | None | IndexConstructorFactoryBase`, found `((...) -> IndexBase) | type[Index[Any] | IndexAutoConstructorFactory] | (Iterable[((...) -> IndexBase) | type[Index[Any]] | None] & Top[(...) -> object])`
- static_frame/core/index_hierarchy.py:527:43 error[invalid-assignment] Object of type `list[IndexBase | @Todo]` is not assignable to `list[Index[Any]]`
+ static_frame/core/index_hierarchy.py:527:43 error[invalid-assignment] Object of type `list[IndexBase]` is not assignable to `list[Index[Any]]`
- static_frame/core/index_hierarchy.py:710:43 error[invalid-assignment] Object of type `list[IndexBase | @Todo]` is not assignable to `list[Index[Any]]`
+ static_frame/core/index_hierarchy.py:710:43 error[invalid-assignment] Object of type `list[IndexBase]` is not assignable to `list[Index[Any]]`
- static_frame/core/quilt.py:1054:80 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ static_frame/core/yarn.py:211:39 error[invalid-assignment] Object of type `list[partial[Unknown] | <class 'IndexAutoConstructorFactory'>]` is not assignable to `((...) -> IndexBase) | type[Index[Any] | IndexAutoConstructorFactory] | None | Iterable[((...) -> IndexBase) | type[Index[Any]] | None]`
+ static_frame/test/unit/test_bus.py:2849:36 error[invalid-argument-type] Argument to bound method `from_zip_npz` is incorrect: Expected `((...) -> IndexBase) | type[Index[Any]] | None`, found `<class 'IndexAutoConstructorFactory'>`
- static_frame/test/unit/test_metadata.py:126:26 error[unresolved-attribute] Attribute `dtype` is not defined on `IndexBase` in union `IndexBase | @Todo`
+ static_frame/test/unit/test_metadata.py:126:26 error[unresolved-attribute] Object of type `IndexBase` has no attribute `dtype`
+ static_frame/test/unit/test_store.py:162:17 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `((...) -> IndexBase) | type[Index[Any] | IndexAutoConstructorFactory] | None | Iterable[((...) -> IndexBase) | type[Index[Any]] | None]`, found `int | ((x) -> Unknown)`
+ static_frame/test/unit/test_store.py:162:17 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `((...) -> IndexBase) | type[Index[Any] | IndexAutoConstructorFactory] | None | Iterable[((...) -> IndexBase) | type[Index[Any]] | None]`, found `int | ((x) -> Unknown)`
+ static_frame/test/unit/test_store.py:170:17 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `((...) -> IndexBase) | type[Index[Any] | IndexAutoConstructorFactory] | None | Iterable[((...) -> IndexBase) | type[Index[Any]] | None]`, found `int`
+ static_frame/test/unit/test_store.py:170:17 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `((...) -> IndexBase) | type[Index[Any] | IndexAutoConstructorFactory] | None | Iterable[((...) -> IndexBase) | type[Index[Any]] | None]`, found `int`

werkzeug (https://github.com/pallets/werkzeug)
+ src/werkzeug/test.py:823:33 warning[redundant-cast] Value is already of type `type[TestResponse]`

Full report with detailed diff (timing results)

Comment thread crates/ty_python_semantic/resources/mdtest/type_of/basic.md
Comment thread crates/ty_python_semantic/resources/mdtest/type_of/basic.md Outdated
Comment thread crates/ty_python_semantic/src/types/infer/builder/type_expression.rs Outdated
@sharkdp sharkdp marked this pull request as ready for review April 9, 2026 12:22
@astral-sh-bot astral-sh-bot Bot requested a review from oconnor663 April 9, 2026 12:22
Copy link
Copy Markdown
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

thank you!

Comment thread crates/ty_python_semantic/resources/mdtest/type_of/basic.md Outdated
self.store_expression_type(slice, parameters_ty);
parameters_ty
}
// TODO: subscripts, etc.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the comment was outdated -- it dates from before we supported type[list[int]] etc.

We might be able to get rid of the Todo type entirely now -- not sure

Comment thread crates/ty_python_semantic/src/types/infer/builder/type_expression.rs Outdated
Copy link
Copy Markdown
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

More features for less code?? Sign me up!

@sharkdp sharkdp enabled auto-merge (squash) April 9, 2026 13:08
@sharkdp sharkdp disabled auto-merge April 9, 2026 13:09
@AlexWaygood
Copy link
Copy Markdown
Member

the new diagnostic in issubclass.md looks like a true positive!

@sharkdp
Copy link
Copy Markdown
Contributor Author

sharkdp commented Apr 9, 2026

the new diagnostic in issubclass.md looks like a true positive!

Yes, I just fixed the assertion.

@sharkdp sharkdp enabled auto-merge (squash) April 9, 2026 13:12
@sharkdp sharkdp merged commit f518cc9 into main Apr 9, 2026
52 checks passed
@sharkdp sharkdp deleted the david/fix-3244 branch April 9, 2026 13:16
ibraheemdev pushed a commit that referenced this pull request Apr 15, 2026
## Summary

Allow partially stringified `type["ForwardRef"]` annotations, even if
they are not explicitly allowed by the typing spec. The implementation
here follows what we do in e.g. `infer_string_type_expression`.

closes astral-sh/ty#3244

## Ecosystem

We apparently get rid of a prevalent `@Todo` type, so we see new
diagnostics, but nothing that looks like *new* false positives, related
to this change. A lot of ecosystem hits have an ignore-comment for
another type checker, which is generally a good signal.

## Test Plan

* New Markdown tests
* Verified that it fixes the problem in
astral-sh/ty#3244
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.

Failing to infer correct return type from partially stringified type annotation

3 participants