-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[ty] Add support for Optional and Annotated in implicit type aliases
#21321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Diagnostic diff on typing conformance testsChanges were detected when running ty on typing conformance tests--- old-output.txt 2025-11-10 09:08:35.361270274 +0000
+++ new-output.txt 2025-11-10 09:08:38.671305041 +0000
@@ -1,4 +1,4 @@
-fatal[panic] Panicked at /home/runner/.cargo/git/checkouts/salsa-e6f3bb7c2a062968/05a9af7/src/function/execute.rs:451:17 when checking `/home/runner/work/ruff/ruff/typing/conformance/tests/aliases_typealiastype.py`: `infer_definition_types(Id(18b71)): execute: too many cycle iterations`
+fatal[panic] Panicked at /home/runner/.cargo/git/checkouts/salsa-e6f3bb7c2a062968/05a9af7/src/function/execute.rs:451:17 when checking `/home/runner/work/ruff/ruff/typing/conformance/tests/aliases_typealiastype.py`: `infer_definition_types(Id(18f71)): execute: too many cycle iterations`
_directives_deprecated_library.py:15:31: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `int`
_directives_deprecated_library.py:30:26: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `str`
_directives_deprecated_library.py:36:41: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `Self@__add__`
@@ -856,7 +856,11 @@
qualifiers_annotated.py:48:18: error[invalid-type-form] Boolean operations are not allowed in type expressions
qualifiers_annotated.py:49:18: error[fstring-type-annotation] Type expressions cannot use f-strings
qualifiers_annotated.py:59:8: error[invalid-type-form] Special form `typing.Annotated` expected at least 2 arguments (one type and at least one metadata element)
+qualifiers_annotated.py:71:1: error[invalid-assignment] Object of type `<typing.Annotated special form>` is not assignable to `type[Any]`
+qualifiers_annotated.py:72:1: error[invalid-assignment] Object of type `<typing.Annotated special form>` is not assignable to `type[Any]`
qualifiers_annotated.py:86:1: error[call-non-callable] Object of type `typing.Annotated` is not callable
+qualifiers_annotated.py:87:1: error[call-non-callable] Object of type `GenericAlias` is not callable
+qualifiers_annotated.py:88:1: error[call-non-callable] Object of type `GenericAlias` is not callable
qualifiers_final_annotation.py:18:7: error[invalid-type-form] Type qualifier `typing.Final` expected exactly 1 argument, got 2
qualifiers_final_annotation.py:52:9: error[invalid-assignment] Cannot assign to final attribute `ID4` on type `Self@__init__`
qualifiers_final_annotation.py:54:9: error[invalid-assignment] Cannot assign to final attribute `ID5` on type `Self@__init__`
@@ -1001,5 +1005,5 @@
typeddicts_usage.py:28:17: error[missing-typed-dict-key] Missing required key 'name' in TypedDict `Movie` constructor
typeddicts_usage.py:28:18: error[invalid-key] Invalid key for TypedDict `Movie`: Unknown key "title"
typeddicts_usage.py:40:24: error[invalid-type-form] The special form `typing.TypedDict` is not allowed in type expressions. Did you mean to use a concrete TypedDict or `collections.abc.Mapping[str, object]` instead?
-Found 1003 diagnostics
+Found 1007 diagnostics
WARN A fatal error occurred while checking some files. Not all project files were analyzed. See the diagnostics list above for details.
|
|
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
invalid-argument-type |
31 | 0 | 27 |
invalid-return-type |
14 | 0 | 0 |
unused-ignore-comment |
0 | 8 | 0 |
invalid-type-form |
4 | 0 | 0 |
call-non-callable |
2 | 0 | 0 |
not-iterable |
2 | 0 | 0 |
invalid-assignment |
1 | 0 | 0 |
| Total | 54 | 8 | 27 |
730ecd3 to
f9e1bf2
Compare
AlexWaygood
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
| KnownInstanceType::Literal(_) => f.write_str("typing.Literal"), | ||
| KnownInstanceType::Annotated(_) => f.write_str("typing.Annotated"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not wild about the displays for these two, because int as a type display means "instance of int", and list[int] means "inhabitant of the type list[int]"... but KnownInstance types here that would be displayed as typing.Literal or typing.Annotated aren't actually instances/inhabitants of typing.Literal or typing.Annotated. Neither of those symbols are classes at runtime, so it would be impossible to create an "instance of typing.Literal".
What about something like <subscripted typing.Literal> or <typing.Literal special form>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typing.Never is also not an "instance of (a class) Never". I don't really see what's different for Literal and Annotated, when compared to some other special form / known instance types, but I changed it to your suggestion for now.
6d6eb5e to
b9179eb
Compare
Summary
Add support for
OptionalandAnnotatedin implicit type aliasespart of astral-sh/ty#221
Typing conformance changes
New expected diagnostics.
Ecosystem
A lot of true positives, some known limitations unrelated to this PR.
Test Plan
New Markdown tests