-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Cannot infer type of lambda when using default arguments #12557
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 agree that the error message is confusing, but mypy is correct in generating an error in these two cases. It is a type violation because both Here's a simplified example. # No type violation
v1: Callable[[], int] = lambda : 1
# Type violation because lambda has an input parameter
v2: Callable[[], int] = lambda name: len(name) If your intent is to accept a list of callables that accept an arbitrary number of arguments, you would need to use |
The OP's example has a default for the name argument. Here's a simple example: from typing import Callable
v2: Callable[[], int] = lambda name="x": len(name) Mypy produces |
Ah, that kinda makes sense. I would be fine with a better error message, too. But, even better, would it be possible to somehow match functions only on the required (non-default) parameters? E.g. for the case of |
Ah yes, I missed the fact that default arguments were provided in the sample code. Pyright does not generate an error in "basic" type checking mode, but in "strict" mode it produces effectively the same error as mypy. The type of the lambda parameter cannot be inferred from bidirectional type inference because there's insufficient information provided by the supplied type annotation. So this is arguably not a bug in mypy. I suppose a type checker could use the inferred type of the default argument to infer the type of the lambda parameter, but that would require a lot of special-case logic to handle what is arguably an extreme edge case. @mxmlnkn, out of curiosity, why are you defining a lambda that accepts extra parameters that are not required in the context in which it is used? Or is your actual use case more complicated that the above sample implies? |
The full example is here. As mentioned in the initial post, I'm using default arguments to effectively safe "freeze" the current loop variable. Note that in the minimal example in the initial post, the first and third assert will fail while the other two will be successful! The result for those failing asserts is 6. |
Here's a case that sent me Googling and brought me to this issue:
As a typing n00b, the third error feels much more informative than the first two. But I don't have the knowledge to explain why I didn't get a similar error on line 102. |
We use this trick to "freeze" loop variables too. We actually use this pattern quite a lot. |
We found that we can use |
|
Just ran into this issue, also using this trick to "freeze" loop variables. Whats weird is while def f(x: int):
pass
x: list[int] = []
# no error
a = lambda x=x: f(x)
# error: Argument 1 to "f" has incompatible type "list[int]"; expected "int" [arg-type]
b = (lambda x: lambda: f(x))(x) |
Is there a way to squelch this error automatically? The "freeze variables" pattern is really common in reactpy |
Bug Report
I get
error: Cannot infer type of lambda
even though the code seems fine to me.Currently, I don't see any other workaround other than using
# type: ignore
.To Reproduce
Checked with:
Expected Behavior
There should be no error. Especially because the other variants without default arguments are deemed fine.
Furthermore, using default arguments like this is the standard workaround to capture loop variables to lambdas.
Your Environment
The text was updated successfully, but these errors were encountered: