How do I read extended annotations from Annotated?
Question:
PEP 593 added extended annotations via Annotated
.
But neither the PEP nor the documentation for Annotated
describes how we’re supposed to access the underlying annotations. How are we supposed to read the extra annotations stored in the Annotated
object?
from typing import Annotated
class Foo:
bar: Annotated[int, "save"] = 5
hints = get_type_hints(Foo, include_extras=True)
# {'bar': typing.Annotated[int, 'save']}
# Get list of data in Annotated object ???
hints["bar"].get_list_of_annotations()
Answers:
you can use the args attribute of the Annotated object.
from typing import Annotated
class Foo:
bar: Annotated[int, "save"] = 5
hints = get_type_hints(Foo, include_extras=True)
annotations = hints["bar"].__args__[1]
print(annotations) # prints "save"
To avoid accessing dunder names, which are reserved by python (such access should be avoided whenever possible):
[…] Any use of __*__
names, in any context, that does not follow explicitly documented use, is subject to breakage without warning.
You should use typing.get_args
helper. It is actually smarter than getting __args__
attribute because of additional expansion step, see source code for details. It is a public API, so this should be preferred to manual dunder attribute examination.
from typing import Annotated, get_type_hints, get_args
class Foo:
bar: Annotated[int, "save"] = 5
hints = get_type_hints(Foo, include_extras=True)
annotations = get_args(hints['bar'])
print(annotations)
# (<class 'int'>, 'save')
PEP 593 added extended annotations via Annotated
.
But neither the PEP nor the documentation for Annotated
describes how we’re supposed to access the underlying annotations. How are we supposed to read the extra annotations stored in the Annotated
object?
from typing import Annotated
class Foo:
bar: Annotated[int, "save"] = 5
hints = get_type_hints(Foo, include_extras=True)
# {'bar': typing.Annotated[int, 'save']}
# Get list of data in Annotated object ???
hints["bar"].get_list_of_annotations()
you can use the args attribute of the Annotated object.
from typing import Annotated
class Foo:
bar: Annotated[int, "save"] = 5
hints = get_type_hints(Foo, include_extras=True)
annotations = hints["bar"].__args__[1]
print(annotations) # prints "save"
To avoid accessing dunder names, which are reserved by python (such access should be avoided whenever possible):
[…] Any use of
__*__
names, in any context, that does not follow explicitly documented use, is subject to breakage without warning.
You should use typing.get_args
helper. It is actually smarter than getting __args__
attribute because of additional expansion step, see source code for details. It is a public API, so this should be preferred to manual dunder attribute examination.
from typing import Annotated, get_type_hints, get_args
class Foo:
bar: Annotated[int, "save"] = 5
hints = get_type_hints(Foo, include_extras=True)
annotations = get_args(hints['bar'])
print(annotations)
# (<class 'int'>, 'save')