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
Error for lambda containing Any even when type can be inferred #5879
Comments
Unfortunately we received several complains about false positives with this flag recently. My guess is this bug is tightly related to #5843, not exactly a duplicate, but the underlying reason is most likely the same. |
This seems to be a regression between 0.630 and 0.641. I have a few scripts that make liberal use of Here is my best attempt to isolate an example from my codebase: import datetime as dt
import typing as t
class DeploymentResponse(t.NamedTuple):
uid: str
createdDate: dt.datetime
class DeploymentListResponse(t.NamedTuple):
items: t.List[DeploymentResponse]
def get_deployments() -> DeploymentListResponse: ...
def prune_deployments(IDs: t.Iterable[str]) -> None: ...
def prune_api_deployments(keep_latest: bool, keep_IDs: t.Iterable[str]) -> None:
response: DeploymentListResponse = get_deployments()
obsolete_IDs = { d.uid for d in response.items }.difference(keep_IDs)
# Works fine with mypy 0.630 but produces errors with 0.641 (see below).
if keep_latest:
obsolete_IDs.discard( max(response.items, key=lambda i: i.createdDate).uid )
# Works fine in both 0.630 and 0.641 because the lambda does not need to be
# inferred. This code is redundant, just for this example.
if keep_latest:
selector: t.Callable[[DeploymentResponse], dt.datetime] = lambda i: i.createdDate
obsolete_IDs.discard( max(response.items, key=selector).uid )
prune_deployments(IDs=obsolete_IDs)
return This code was tested on Python 3.6.1 using both mypy 0.630 and 0.641 with the
Of course, the workaround is obvious — don't make mypy infer the type of the |
what's interesting is that when using from typing import Callable, NoReturn, overload
@overload
def foo(value: str, predicate: Callable[[str], object]) -> None:
...
@overload
def foo(value: int, predicate: Callable[[int], object]) -> None:
...
def foo(value: int | str, predicate: Callable[[NoReturn], object]) -> None:
...
# error: Expression type contains "Any" (has type "Callable[[Any], Any]") [misc]
# note: Revealed type is "Any"
# note: Revealed type is "builtins.int"
foo(1, lambda value: reveal_type(value)) |
This is resolved in basedmypy |
Using mypy 0.641 with the --disallow-any-expr flag and this sample using
@overload
produces
However mypy seems to be able to infer the type of the lambda because if I modify the last line to read
mypy correctly identifies that
"int" has no attribute "bad"
, sprinkling some prints on the mypy source also reveals it figures out it's a(int, int) -> int
at some point.foo_not_overloaded checks without trouble and so does using a plain
def
instead of the lambda.The text was updated successfully, but these errors were encountered: