mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-20 04:29:47 +00:00
[ty] Support stringified annotations in value-position Annotated instances (#21447)
## Summary Infer the first argument `type` inside `Annotated[type, …]` as a type expression. This allows us to support stringified annotations inside `Annotated`. ## Ecosystem * The removed diagnostic on `prefect` shows that we now understand the `State.data` type annotation in `src/prefect/client/schemas/objects.py:230`, which uses a stringified annotation in `Annoated`. The other diagnostics are downstream changes that result from this, it seems to be a commonly used data type. * `artigraph` does something like `Annotated[cast(Any, field_info.annotation), *field_info.metadata]` which I'm not sure we need to allow? It's unfortunate since this is probably supported at runtime, but it seems reasonable that they need to add a `# type: ignore` for that. * `pydantic` uses something like `Annotated[(self.annotation, *self.metadata)]` but adds a `# type: ignore` ## Test Plan New Markdown test
This commit is contained in:
parent
05cf53aae8
commit
e9a5337136
5 changed files with 28 additions and 9 deletions
|
|
@ -76,7 +76,18 @@ from ty_extensions import reveal_mro
|
|||
|
||||
class C(Annotated[int, "foo"]): ...
|
||||
|
||||
reveal_mro(C) # revealed: (<class 'C'>, <class 'int'>, <class 'object'>)
|
||||
# revealed: (<class 'C'>, <class 'int'>, <class 'object'>)
|
||||
reveal_mro(C)
|
||||
|
||||
class D(Annotated[list[str], "foo"]): ...
|
||||
|
||||
# revealed: (<class 'D'>, <class 'list[str]'>, <class 'MutableSequence[str]'>, <class 'Sequence[str]'>, <class 'Reversible[str]'>, <class 'Collection[str]'>, <class 'Iterable[str]'>, <class 'Container[str]'>, typing.Protocol, typing.Generic, <class 'object'>)
|
||||
reveal_mro(D)
|
||||
|
||||
class E(Annotated[list["E"], "metadata"]): ...
|
||||
|
||||
# error: [revealed-type] "Revealed MRO: (<class 'E'>, <class 'list[E]'>, <class 'MutableSequence[E]'>, <class 'Sequence[E]'>, <class 'Reversible[E]'>, <class 'Collection[E]'>, <class 'Iterable[E]'>, <class 'Container[E]'>, typing.Protocol, typing.Generic, <class 'object'>)"
|
||||
reveal_mro(E)
|
||||
```
|
||||
|
||||
### Not parameterized
|
||||
|
|
|
|||
|
|
@ -974,13 +974,14 @@ We *do* support stringified annotations if they appear in a position where a typ
|
|||
syntactically expected:
|
||||
|
||||
```py
|
||||
from typing import Union, List, Dict
|
||||
from typing import Union, List, Dict, Annotated
|
||||
|
||||
ListOfInts1 = list["int"]
|
||||
ListOfInts2 = List["int"]
|
||||
StrOrStyle = Union[str, "Style"]
|
||||
SubclassOfStyle = type["Style"]
|
||||
DictStrToStyle = Dict[str, "Style"]
|
||||
AnnotatedStyle = Annotated["Style", "metadata"]
|
||||
|
||||
class Style: ...
|
||||
|
||||
|
|
@ -990,12 +991,14 @@ def _(
|
|||
str_or_style: StrOrStyle,
|
||||
subclass_of_style: SubclassOfStyle,
|
||||
dict_str_to_style: DictStrToStyle,
|
||||
annotated_style: AnnotatedStyle,
|
||||
):
|
||||
reveal_type(list_of_ints1) # revealed: list[int]
|
||||
reveal_type(list_of_ints2) # revealed: list[int]
|
||||
reveal_type(str_or_style) # revealed: str | Style
|
||||
reveal_type(subclass_of_style) # revealed: type[Style]
|
||||
reveal_type(dict_str_to_style) # revealed: dict[str, Style]
|
||||
reveal_type(annotated_style) # revealed: Style
|
||||
```
|
||||
|
||||
## Recursive
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue