-
Notifications
You must be signed in to change notification settings - Fork 234
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
How to add hint to factory method? #58
Comments
I suppose the logical way to write these would be |
FYI, this issue was originally posted on PyCharm. |
We're not going to support this. The issue seems fairly academic. |
FYI, this issue is very programatic, as commented at https://youtrack.jetbrains.com/issue/PY-11615 |
I agree that this issue is not just academic, it comes up for me daily. This has practical implications whenever one wants to use class factory methods. Python's first-class treatment of classes enables an elegant implementation of factories via class methods. Because I can pass a class and call class methods on it, I don't need to create an independent factory class and pass an instance of it. Yet I can't have a type hint that indicates a class is expected, not an instance of the class. This is a typical pattern I utilize (sadly, I'm still stuck in Python 2 using PyCharm type hinting; please forgive the antiquated syntax):
Instead of creating a BaseFactory class and instantiating an implementation of BaseFactory to pass, Python allows me to pass the class instead:
The type hint I want to provide for |
You should be able to hint the
|
Thank you @gvanrossum . Although I knew to use Callable for functions, it didn't occur to me that one could use it for classes as well. I suspect this is not correctly supported in PyCharm, at least in Python 2 (the syntax in PyCharm for Python 2 docstrings for |
See also #107. |
For anyone who might find this now, a way to do this is:
|
@gvanrossum Any chance you might reconsider the "academic" brush-off of this request? Factory methods are a fairly common pattern, and having a natural way to express them in type hints seems more than an academic corner case thing, no? The bounded |
The current way to write this is fine IMO. |
@gvanrossum a'ight. I've been reminded that there's a better option without the class TrivialClass:
def from_int(cls, int_arg: int) -> 'TrivialClass':
return cls(...) Still looking for a "non-academic" endorsement of the use case, but the current mechanisms worked out for the best. :-) |
To all your academicians out there, that example is less powerful than the one using TypeVar, because it doesn't show that if you subclass TrivialClass the from_int method returns an instance of the subclass. |
Also, forward references have been supported far longer than the |
Thanks for the clarification. Just piping up for the academy. :-) |
It would be helpful if the |
It is intentionally not mentioned there. There is more to the docs than the cheat sheets, and showing |
Default files are unimplemented currently.
I would like to add another example I just encountered -- implementing any binary operation on an immutable instance, for instance, this doesn't compile: class Vector(tuple):
def __add__(self, other: Vector) -> Vector:
return tuple(sum(vals) for vals in zip(self, other)) |
@kwikwag why should that pass? It currently returns a tuple, not a Vector as annotated. You could make some progress on that function using self types, though you might need integer variadics (a feature that's in development in some type checkers) to catch some categories of errors. |
@kwikwag is right, you cannot use the type hints to write a method that consumes an instance of itself
With mypy you get:
This would be useful for many classes with operations defined between members of the class |
It seems this code still doesn't warn when trying to return an incorrect type from the subclass, am I missing something? Example. Can give system info on request. |
I recommend using the new from typing import Type
from typing_extensions import Self
class Base:
@classmethod
def create(cls: Type[Self]) -> Self:
...
class Child1(Base):
pass
class Child2(Base):
@classmethod
def create(cls: Type[Self]) -> Self:
return Child1() # Type error I don't think mypy has support for |
How to hint to method receiving class object and returns instance of the class?
Case 1:
Case 2:
The text was updated successfully, but these errors were encountered: