Let's say I have the following code:
from typing import Literal, TypeVar, Generic
T = TypeVar("T", bound=str)
class Foo(Generic[T]):
def foo(self, arg: T = "foo") -> T:
return arg
The idea is that I have a generic class with a concrete method that takes a string, but the child classes can define a more restrictive input than any string, for example this class will only accept "bar":
class Bar(Foo[Literal["bar"]]):
pass
However, the original code doesn't pass any type checker. Both mypy and pyright complain. The mypy error is:
test.py:6: error: Incompatible default for argument "arg" (default has type "str", argument has type "T")
I would have thought this would be okay, because T has an upper bound which is a string. However I think the issue is that the default argument "foo" no longer makes sense if the child class accepts only "bar". How then can I define T such that it must always allow the literal "foo", but the child class can also define additional strings it will accept?
ArgType = Union[T, Literal["foo"]]and thendef foo(self, arg: ArgType = "foo") -> ArgType.