Inference of typing.Annotated
Hey!
I've got a project where I'm looking at using the Annotated type annotation which was new in Python 3.9 (and backported through typing_extensions).
typing.Annotated
A type, introduced in PEP 593 (Flexible function and variable annotations), to decorate existing types with context-specific metadata (possibly multiple pieces of it, as Annotated is variadic). Specifically, a type
Tcan be annotated with metadataxvia the typehintAnnotated[T, x]. This metadata can be used for either static analysis or at runtime. If a library (or tool) encounters a typehintAnnotated[T, x]and has no special logic for metadatax, it should ignore it and simply treat the type asT.
I'd expect Jedi to take the naive route and go with "simply treat the type as T". However it's not something which Jedi handles at present as I've confirmed with a fresh clone of the repo today.
How might I go about adding support for this in Jedi? I'm new to this codebase so some pointers would be appreciated.
Or is this even a Jedi thing in the first place? is something else missing a definition about Annotated?
I was looking at how to implement it and ended up starting with a basic test which fails as expected. Does this look right as a starting point?
from typing import Annotated
# This is just a dummy and very meaningless thing to use with to the Annotated
# type hint
class Foo:
pass
class A:
pass
def annotated_function_params(
basic: Annotated[str, Foo()],
obj: A,
annotated_obj: Annotated[A, Foo()],
):
#? str
basic
#? A()
obj
#? A()
annotated_obj
The first and third tests there fail as expected with this sort of message:
E AssertionError:
E Test <IntegrationTestCase: /src/test/completion/pep0593_annotations.py:24 ' annotated_obj'> failed.
E actual =
E set()
E desired =
E {'completion.pep0593_annotations.A()'}
E
E assert set() == {'completion....otations.A()'}
E Extra items in the right set:
E 'completion.pep0593_annotations.A()'
E Full diff:
E - {'completion.pep0593_annotations.A()'}
E + set()
I'm pretty sure this is not handled yet. Want to try to fix it? I'm happy to assist.
The right place to work on this is definitely jedi/inference/gradual/typing.py. It's probably a really small fix (20 lines). The hard part is to understand what you need to do.
@davidhalter Any hints on where to start in jedi/inference/gradual/typing.py?
I think the intended behavior would be to just return the type of the first parameter to the Annotated generic. Would this be treated the sameway as ClassVar?
https://github.com/davidhalter/jedi/blob/dcea842ac237b51263c29a252dba9b650fc799ff/jedi/inference/gradual/typing.py#L116-L118
I think the intended behavior would be to just return the type of the first parameter to the Annotated generic. Would this be treated the sameway as ClassVar?
Oh yeah, good find! It's pretty much that I guess. Feel free to create a PR for it :)