-
I have a class that is like a dataclass. It can either be initialized by calling the class with the name=value keyword arguments with all the defined fields, or it has an alternate constructor that receives some bytes data, parses it and initializes the object's field from the parsed data. The code sample to showcase the issue is below: from contextvars import copy_context
from typing import Self
class Structure:
def __init__(self, **kw: object) -> None:
# init instance from kw
@classmethod
def alt_create_1(cls, data: bytes) -> Self:
instance = super(Structure, cls).__new__(cls) # this call to super is not flagged
# alternative instance initialisation from data
return instance
@classmethod
def alt_create_2(cls, data: bytes) -> Self:
context = copy_context()
return context.run(_alt_create_2, cls, data)
def _alt_create_2[T: Structure](cls: type[T], data: bytes) -> T:
instance = super(Structure, cls).__new__(cls) # this is flagged with a error (see below)
# init instance from data
return instance
# typing-12.py
# typing-12.py:23:46 - error: Argument of type "type[T@_alt_create_2]" cannot be assigned to parameter "cls" of type "type[Self@Structure*]" in function "__new__"
# Type "type[T@_alt_create_2]" is incompatible with type "type[Self@Structure*]" (reportArgumentType) Calling However in the function, the same call to I can fix this and get rid of the error if in the function I use The question I have is why do I get that call to |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
In a class method, if you don't specify a type annotation for the In your function I'll need to think more about whether it's safe from a type perspective to support what you're doing here. At first glance, it seems like it should be. The question is then whether it's worth attempting to enhance the handling of |
Beta Was this translation helpful? Give feedback.
-
Is there anything that can be done right now other than adding a Also in light of your explanation, it looks to me that the error message is just wrong. When |
Beta Was this translation helpful? Give feedback.
In a class method, if you don't specify a type annotation for the
cls
parameter, it implicitly has the typetype[Self]
. This is analogous to theself
parameter in an instance method, which implicitly has the typeSelf
.In your function
_alt_creat_2
, the type ofcls
is annotated to betype[T]
whereT
is bound toStructure
. This is not the same astype[Self@Structure]
. That explains why you're seeing a difference in behavior.I'll need to think more about whether it's safe from a type perspective to support what you're doing here. At first glance, it seems like it should be. The question is then whether it's worth attempting to enhance the handling of
super
in pyright to support this. The l…