I have a TypedDict which I am using to represent a query. This query is recursive, so one of the keys can contain the same type as the parent. If I use the Self type, it looks like this:
from typing import TypedDict, Self, Iterable
class Query(TypedDict):
and_: Iterable[Self]
or_: Iterable[Self]
However, I don't want to have this underscore after and_: the real key should just be and. So then I have to represent this using the function call syntax, since and is not a valid identifier in Python:
from typing import TypedDict, Self, Iterable
Query = TypedDict("Query", {
"and": Iterable[Self]
"or": Iterable[Self]
}
Except that Self is not valid outside of a class context, so now mypy gives me:
test.py:4: error: Variable "typing_extensions.Self" is not valid as a type
Now, I could also try the old fashioned way of writing Self, as described here. However this method relies on being able to annotate the type of self with a TypeVar:
TShape = TypeVar("TShape", bound="Shape")
class Shape:
def set_scale(self: TShape, scale: float) -> TShape:
self.scale = scale
return self
Unfortunately I can't do this here either, since I'm not using a class.
Lastly, it might seem like I could make my TypedDict generic, like this:
from typing_extensions import TypeAlias, TypedDict, Self
from typing import TypeVar
T = TypeVar("T", bound="Query")
Query = TypedDict("Query", {
"and": T,
"or": T
})
But again, because I'm not using a class, mypy complains:
test.py:7: error: Type variable "test.T" is unbound
test.py:7: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
test.py:7: note: (Hint: Use "T" in function signature to bind "T" inside a function)
Is there any way to refer to the Self type when using the non-class syntax for TypedDict?