How to set typehint for default type

61 views Asked by At

I'm trying to set correct typehint for default type in this situation

from typing import TypeVar


class Foo:
    pass


class FooBar(Foo):
    pass


T = ...


def baz(type_: type[T] = Foo) -> T:
    return type_()

Already tried to use

T = TypeVar("T", bound=Foo)

But mypy said:

Incompatible default for argument "type_" (default has type "type[Foo]", argument has type "type[T]")  [assignment]
    def baz(type_: type[T] = Foo) -> T:
                             ^~~

1

There are 1 answers

0
STerliakov On

Just not to leave this question unanswered: to make mypy happy with typevar-typed argument with default value, you need overloaded definition due to this open issue.

Implementation signature is used only for body typechecking in such case, so it can use the upper bound of type variable everywhere. External callers will see what you expect them to see

from typing import TypeVar, overload

class Foo:
    pass

class FooBar(Foo):
    pass


T = TypeVar('T', bound=Foo)

@overload
def baz() -> Foo: ...
@overload
def baz(type_: type[T]) -> T: ...
def baz(type_: type[Foo] = Foo) -> Foo:
    return type_()
    
reveal_type(baz(Foo))  # N: Revealed type is "__main__.Foo"
reveal_type(baz())  # N: Revealed type is "__main__.Foo"
reveal_type(baz(FooBar))  # N: Revealed type is "__main__.FooBar"

Here's a playground link with this implementation.