-
Notifications
You must be signed in to change notification settings - Fork 24
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
"Could not resolve the type hint of" warning, for TypeVar #101
Comments
Hey @giladbarnea! Thanks for opening an issue. :) Unfortunately type variables are currently not supported. :( It would be awesome to support them, but this is not a trivial undertaking. If you ignore the warnings, your code will run, but it will not behave as expected: from typing import TypeVar
from plum import dispatch
T = TypeVar("T")
@dispatch
def f(x: T) -> T:
return 1 >>> f(2) # OK so far...
1
>>> f("2") # Nope! T_T This should error.
1 |
Thanks for replying! This is a bit of a bummer, if possible can you tell me a few reasons why supporting TypeVars is difficult? Hopefully I'll find some time and maybe try to fix it. |
@giladbarnea in principle supporting |
Note to the unwise and the unwary: @beartype and thus Plum should superficially support a
In either case, @beartype and thus Plum should reduce that As @wesselb suggests, full-blown type variable support at runtime is non-trivial in the extreme and not something anyone wants to voluntarily tackle. You'll either need full-time grant funding for that and/or Asperger's. I have the latter but not the former. Therefore, I'll eventually tackle this – but only after having exhausted every other outstanding feature request and issue in @beartype. It is the highest of the high-hanging fruit. It cannot be plucked without back pain, kidney pain, a blown ACL, and a ruptured Achilles heel. Don't go down that road, @giladbarnea. |
@leycec Are warnings expected with bound variables? They seem to work, but just want to make sure the warnings are expected and not from misuse. from plum import dispatch
from typing import TypeVar
T = TypeVar("T", bound=str)
@dispatch
def f(x: T) -> T:
return x
f('foo') # works with warnings
f(2) # errors, no warning |
@ilan-gold The warnings here can be ignored. Your code will run, but may not behave as expected. Consider the following (very contrived) example: from plum import dispatch
from typing import TypeVar
class Str2(str):
pass
T = TypeVar("T", bound=str)
@dispatch
def f(x: T) -> T:
return Str2(x)
f("hey") # Works, but shouldn't, because the input is `str` and the output a `Str2`! |
Doesn't that work just because |
Right, I see what you're saying. I believe that the way Consider instead the following example: from plum import dispatch
from typing import TypeVar
class Str2(str):
pass
T = TypeVar("T", str, int)
@dispatch
def f(x: T) -> T:
return 1
f("1") # Works, but shouldn't, because the input is `str` and the output a `int`! |
Wait, this time, aren't the constraints functioning as a union of types now, though? |
That's what's currently happening, yes, but it's not the correct behaviour. The above code should be equal to @dispatch
def f(x: str) -> str:
...
@dispatch
def f(x: int) -> int:
... It would be great to properly support type parameters, but unfortunately that's not an easy feat. |
Why not get the type of the argument passed to the function, find the index of the type in the constraint, then check the index of the return type in the return constraint? With special consideration of exact types. Like: def check(func, arg, argvar, _return, returnvar):
argtype = type(arg)
returntype = type(_return)
for i, t in enumerate(returnvar.__constraints__):
if argtype is t and argvar.__contraints__[i] is t:
return True
for i, t in enumerate(returnvar.__constraints__):
if issubclass(argtype, t) and issubclass (argvar.__contraints__[i], t):
return True
return False Of course, this is just a short mock-up! |
@sylvorg, you're totally right that this would be a nice attempt at supporting type parameters. Currently, we don't do any of this. Should you want to have a go at trying to properly support type parameters, then that would be super exciting. I think the basic cases can be covered in a fairly straightforward way. Getting all the edge cases will likely be tedious and very difficult. |
I'll try my best, but it'll take me a while to understand the code base; which files would you recommend I look at, other than |
To be honest, this might be a pretty major undertaking that touches a large part of the codebase. It's currently not clear to me what the best way of going about it would be. I'm thinking that we could add a "type parameter resolution stage" in |
Is there any function in the codebase you can think of that gets the argument type, the argument annotation, the return type, and the return annotation? Or a series of functions? I could start working from there. Or would they all be in |
The actual types of the arguments are only considered at the very last stage of dispatch, in Thinking about it, I think all that might be required is a matching algorithm that attempts to determine the values of the type parameters (the first hit suffices) and which then replaces that type parameter by the matched value. |
Sorry, could you expand on this a little bit? What do you mean by "replaces that type parameter by the matched value"? |
@sylvorg, basically, if the signature is |
Oof; this is getting a little too confusing for me... 😅 Would we not also have to match the type of the return value as well as the arguments provided to the function? |
@sylvorg, yes, that's completely right, and it's one of the main challenges why this is so difficult. :( In general, signatures can depend on We could decide to take it step by step and only support type parameters in a limited manner. If we code things up in a robust and sound way and give appropriate warnings to the user, I would be fully on board with that. |
Indeed. @wesselb has the right of it. @wesselb always does. @beartype itself will (...probably) begin tackling type parameters in earnest sometime in 2025. The plan here is exactly as @wesselb briskly delineated: "take it step by step and only support type parameters in a limited manner." In order, @beartype will begin supporting callable signatures annotated by:
And so on and so forth. It's super-fun just to cogitate, ideate, and ruminate about this. We're deep into the Philosophy of Type Hints at this point. But it's also super-critical to have a coherent plan of where to begin. Start with the absolute simplest use case and cautiously build out support for increasingly less simplistic use cases from there – iteratively ratcheting up the stakes like a sweaty late-night game of spin-the-bottle that can only end in disaster for all parties. |
Hi, thanks for the awesome library! Super useful.
I've been getting this warning:
Reproduce:
The text was updated successfully, but these errors were encountered: