Closed callumforrester closed 2 months ago
Pyright is working as intended here. In a class method, the implied type for cls
(if you don't provide an explicit annotation) is type[Self]
. This means it must be assignable to the specialized type of its parent class. In your example, the specialized type of FooBar
is FooBar[T]
. When you call cls
as a constructor, it's like you're calling FooBar[T](a, b)
. That means the __init__
method gets specialized with the bound value of T
. In the call, you're attempting to assign the bound value U
to parameter a
which has the value of T
, and these types are not compatible.
Here's an alternative formulation that avoids the type error:
@classmethod
def alternative_constructor_2(cls: "type[FooBar[Any]]", a: U, b: int) -> "FooBar[U]":
return cls(a, b)
Or
@classmethod
def alternative_constructor_2(cls: "type[FooBar[U]]", a: U, b: int) -> "FooBar[U]":
return cls(a, b)
@erictraut makes sense to me, thanks. Just to check I haven't missed something: There is no way to have a single TypeVar
, right? I need both T
and U
?
Describe the bug Apologies if this is an intended feature. I need to define two
TypeVar
s to bind to a class and a classmethod separately in strict mode. I'm unsure if this is a bug or highlights an explicit difference between the two.Code or Screenshots
Code sample in pyright playground