Annotating custom constructor methods for generic types. #2025
Answered
by
erictraut
randolf-scholz
asked this question in
Q&A
-
How to annotate # fmt: off
from collections.abc import Mapping
from typing import overload
dict(bar=3) # SHOULD PASS (pyright: ✅, mypy: ✅)
dict[str, int](bar=3) # SHOULD PASS (pyright: ✅, mypy: ✅)
dict[int, int](bar=3) # SHOULD ERROR (pyright: ✅, mypy: ❌)
class Foo[K, V](Mapping[K, V]):
@overload
@classmethod
def new(cls, items: Mapping[K, V], /) -> "Foo[K, V]": ...
@overload
@classmethod
def new(cls, items: Mapping[str, V] = ..., /, **kwargs: V) -> "Foo[str, V]": ...
Foo.new(bar=3) # SHOULD PASS (pyright: ✅, mypy: ✅)
Foo[str, int].new(bar=3) # SHOULD PASS (pyright: ✅, mypy: ✅)
Foo[int, int].new(bar=3) # SHOULD ERROR (pyright: ❌, mypy: ❌) My analysis:
|
Beta Was this translation helpful? Give feedback.
Answered by
erictraut
Jun 16, 2025
Replies: 1 comment 5 replies
-
I think option 1 is the right approach, but you need to use |
Beta Was this translation helpful? Give feedback.
5 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes,
Foo.new
bindsFoo[Any, Any]
to thenew
method. The types of class-scoped type variables are inferred from argument types only when you call a constructor. This doesn't work for other methods. In other cases, the specialization comes from the bound class — in this case,Foo
orFoo[Any, Any]
since you haven't specified any default values for the type variables.