Python 3.9 introduces the Annotated class which allows adding arbitrary metadata to type hints, e.g.,
class A:
x: Annotated[int, "this is x"]
The annotated type hint can be obtained by setting the new include_extras argument of get_type_hints:
>>> get_type_hints(A, include_extras=True)
{'x': typing.Annotated[int, 'this is x']}
And the metadata itself can be accessed through the __metadata__ attribute of the type hint.
>>> h = get_type_hints(A, include_extras=True)
>>> h["x"].__metadata__
('this is x',)
But, my question is, what is the right way to test if a type hint even is Annotated? That is, something akin to:
if IS_ANNOTATED(h["x"]):
# do something with the metadata
As far as I can tell, there is no documented method to do so, and there are a couple possible ways, none of which seem ideal.
Comparing the type to Annotated doesn't work because the type hint is not an instance of Annotated:
>>> type(h["x"])
typing._AnnotatedAlias
So we have to do:
if type(h["x"]) is _AnnotatedAlias:
...
But, given the leading underscore in _AnnotatedAlias, this requires using, presumably, an implementation detail.
The other option is to directly check for the __metadata__ attribute:
if hasattr(h["x"], "__metadata__"):
...
But this assumes that the __metadata__ attribute is unique to Annotated, which can't necessarily be assumed when dealing with user-defined type hints too.
So, is there perhaps a better way to do this test?