-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
classmethod's in generic protocols with self-types #5872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think this is actually a duplicate of #2511. Here is a repro that doesn't include protocols and dataclasses: T = TypeVar('T', bound=B)
class B:
@classmethod
def m(cls: Type[T]) -> T: ...
class C(B):
@classmethod
def m(cls) -> C: ... |
(As for a workaround you can use |
@ilevkivskyi I see, thank you for the response. Just to clarify, the issue is generics in classmethods that return self-types? Is it the same issue here: #3645 ? I'm not sure silencing would be an option for me, because I would have to silence the error every time this generic container class is instantiated, because it never recognizes anything as fulfilling the protocol (unless I misunderstood your suggestion). I'll probably just refactor to work with an instance method. Thanks for the suggestion anyway. |
This is different from #3645, but a proper fix will likely fix both. Yes, using an instance method is a good option. |
Excuse me, but why the issue is closed? There is no solution how to use class methods in Protocols, i.e I have the following Protocol and implementation: from typing import Protocol, TypeVar, Dict, Type, Generic
from dataclasses import dataclass
ModelType = TypeVar("ModelType", bound="DictSerializable")
class DictSerializable(Protocol):
@classmethod
def from_dict(cls: Type[ModelType], data: Dict) -> ModelType:
...
def to_dict(self: ModelType) -> Dict:
...
@dataclass
class Item:
value: int
@classmethod
def from_dict(cls: Type[Item], data: Dict) -> Item:
return Item(value=data["value"])
def to_dict(self) -> Dict:
return {"value": self.value}
item: DictSerializable = Item(value=1) Error:
Playground https://mypy-play.net/?mypy=latest&python=3.9&gist=cd5f30078d13e2cac70376a0bdc2ff06 The main problem that the DictSerializable structures possibly are not controlled by the |
Hey @SergeyTsaplin,
I tried to reproduce the errors you mentioned in your comment with an upgraded version of your minimal example, incorporating the following changes:
The upgraded code: from typing import Protocol, TypeAlias, Type, TypeVar
from dataclasses import dataclass
ModelType = TypeVar("ModelType", bound="DictSerializable")
ItemDict: TypeAlias = dict[str, int]
class DictSerializable(Protocol):
@classmethod
def from_dict(cls: ModelType, data: dict) -> ModelType:
...
def to_dict(self: ModelType) -> dict:
...
@dataclass
class Item:
value: int
@classmethod
def from_dict(cls: Type['Item'], data: ItemDict) -> 'Item':
return Item(value=data["value"])
def to_dict(self) -> ItemDict:
return {"value": self.value}
item: DictSerializable = Item(value=1)
print(item) I can run this code without problems: $ mypy spam.py && python spam.py
Success: no issues found in 1 source file
Item(value=1) using |
A potential bug
So, I've posted a corresponding question on StackOverflow, but it hasn't gotten much traction.
Here is my basic situation: I'm trying to use a Protocol that would include a couple of classmethods.
The protocol is generic too, and the signatures involves self-types:
When I try to type-check this, I get the following errors:
Why are the return types registering as
<nothing>
? When omit the annotation for thecls
argument in the protocol, I get the following error:Which, quite frankly, makes even less sense to me.
If I make the classmethods instance methods, I receive no error. I would want to avoid this, since it would require a more hefty re-design.
If I try to use a staticmethod (which would be an easier workaround) it also fails:
error:
What is wrong with my Protocol / class definition? Am I missing something obvious?
I am using mypy version 0.620
The text was updated successfully, but these errors were encountered: