-
I have a class I've tried this: P = TypeVar('P')
class Foo:
@staticmethod
def __class_getitem__(item: P) -> Annotated[Type[Foo], P]:
return Annotated[Foo, item] But there's the obvious complaint from mypy that There's the related concept of an This is the closest I've gotten to having something work - seems like it's pretty obviously wrong direction, though, abusing # annotation.py
from __future__ import annotations
from typing import Annotated, Any, Type, TypeVar, get_type_hints, Generic
B = TypeVar('B')
T = TypeVar('T')
class Foo(Generic[T]):
@staticmethod
def __class_getitem__(item: B) -> Annotated[Type[Foo], B]:
result = Annotated[Foo, item]
return result
class C:
foo: Foo['asdf']
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
There's currently no way to use non-type annotations in a generic type alias. Type aliases are intended to be used with types, not other forms of annotation. When you use Could you describe in more detail what you are using the annotations for in this case? What does |
Beta Was this translation helpful? Give feedback.
-
I actually got this to work, though I've just traded from __future__ import annotations
from dataclasses import dataclass
from typing import Annotated, Generic, Literal, TYPE_CHECKING, TypeVar, cast, get_args, get_type_hints
_PT = TypeVar('_PT')
T = TypeVar('T')
class Foo(Generic[T]):
@staticmethod
def __class_getitem__(item: _PT) -> Annotated[Foo, _PT]:
"""
The `cast` is required. Doing `return Annotated[Foo, item]` directly causes mypy to error:
annotation_hack.py:14: error: Incompatible return value type (got "object", expected "Foo[Any]")
annotation_hack.py:37: note: Revealed type is "annotation_hack.Foo[Literal['zzz']]"
"""
return cast(Annotated[Foo, _PT], Annotated[Foo, item])
@dataclass
class Bar:
foo: Foo[Literal['zzz']]
bar = Bar(Foo())
type_hints = get_type_hints(Bar, include_extras=True)
annotated_type, annotated_value = get_args(type_hints['foo'])
print(f"Annotations: {Bar.__annotations__}")
print(f"Hints: {type_hints}")
print(f"Bar.foo: {annotated_type, annotated_value}")
"""
Annotations: {'foo': "Foo[Literal['zzz']]"}
Hints: {'foo': typing.Annotated[__main__.Foo, typing.Literal['zzz']]}
Bar.foo: (<class '__main__.Foo'>, typing.Literal['zzz'])
"""
if TYPE_CHECKING:
reveal_type(Bar.foo)
"""
annotation_hack.py:42: note: Revealed type is "annotation_hack.Foo[Literal['zzz']]"
""" |
Beta Was this translation helpful? Give feedback.
There's currently no way to use non-type annotations in a generic type alias. Type aliases are intended to be used with types, not other forms of annotation. When you use
Annotated
, you need to spell out the entire annotation.Could you describe in more detail what you are using the annotations for in this case? What does
'bar'
and'some_changing_value'
represent in your use case? I'm wondering if they could be modeled as types within the type system, which would allow you to use normal type annotations and type aliases rather than falling back onAnnotated
.