-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Need a way to refer to the type parameter of a generic class inside a generic function #3151
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
If I understand your example correctly, then this could be expressed by higher kinds (e.g. you want your Why exactly do you need variable class X(Generic[T]):
def f(self) -> T: ...
class Y(X[T]): ...
def g(cls: Callable[[], X[T]]) -> T:
x: List[T] = []
x.append(cls().f())
return x[0]
reveal_type(g(Y[str])) # Revealed type is 'builtins.str*' |
The reason I need
I can't use
because if As to higher kinds, I never heard about them until now, but from what I could understand at first glance, you're right, this is one way to achieve this. But, consistent with your comments, it is slightly more advanced (it's in Scala/Haskell AFAIU, but not in C#/Java). I can see that due to complexity (conceptual and implementation) it may not be relistic to add it to python type hints, at least not soon. Maybe there's a simpler solution for my immediate use case? |
I don't understand what you're trying to do here. The I'd also like to see more of your implementation of Also, honestly, this is beginning to look like you may be so in love with generics you want to use them everywhere, and the code you're writing is like "writing Scala/Haskell in Python" (like there used to be a saying "you can write FORTRAN in any language" :-). I recommend taking a step back -- maybe you don't need everything to be so generic/general? Remember that we're trying to keep the type system so that it is easily taught to Python programmers, not to satisfy people with a Ph.D in functional programming. :-) |
@gvanrossum Sorry, my example had a typo. I edited my previous comment to fix it and also to include a better reproduction of the context. Regarding
won't work because |
OK, now I see. You have a generic function over a type variable G that represents some Graph[T] and you need to reference Node[T] in the function. Pragmatically you should just use Node[Any] and move on. The redesign of PEP 484 needed to support this in a more type-safe way doesn't sound like an easy thing, and we really have a lot of more important things to do first (e.g. we've had to delay work on the Protocols PR because the Dropboxers that can review it all have too much else on their TODO list already). |
Yes, I just didn't realize how easy it is to end up with more complex types. I'm perfectly ok with the type system that has some limitations, but can be easily overridden with |
This entire issue disappears (in a sense) once I realized that type variables cannot be bound by generic types with free type parameters as confirmed in #2756. Once #3153 is fixed, mypy will correctly interpret
as
and with that, it will be obvious that the only way to annotate FWIW, in some cases, there's a workaround: make
If this is not enough (e.g., because |
I don't think there's a way to write this code in a type-safe way:
There is no precise type I can use in place of
???
.reveal_type(cls().f())
tells meRevealed type is 'T`1'
, but that's not much help because I can't sayx: T
(type arguments of a generic function are determined only by the signature, soT
would be invalid in that context).Nor can I change
C
to becomeTypeVar('C', bound=X[T])
(can't use type arguments in that context either).Nor can I use
def g(cls: Callable[[], C[T]]) -> None
(type variables cannot be used with arguments).So
???
is a type that mypy understands, but there's no way to actually refer to it.Of course, the toy example above works without annotation (mypy simply infers type of
x
) but if I need to make a list of those things, I'm out of luck:The text was updated successfully, but these errors were encountered: