Skip to content
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

False positive for lambda within a function #10426

Open
michaelbrewer opened this issue May 6, 2021 · 2 comments
Open

False positive for lambda within a function #10426

michaelbrewer opened this issue May 6, 2021 · 2 comments
Labels
bug mypy got something wrong

Comments

@michaelbrewer
Copy link

michaelbrewer commented May 6, 2021

Related Bug

Could be a duplicate of:

Bug Report

When running mypy with a function returning an Optional the contains of a lambda expression is interpreted as optional and a type error is raised

To Reproduce

Run mypy against the following file:

from typing import Optional

animals = ["cow"]


def find1(name: str) -> Optional[str]:
    return next(
        filter(
            lambda animal: animal.upper() == name,
            animals,
        ),
        None,
    )

Expected Behavior

No type errors should be returned

Actual Behavior

$ mypy bug.py
bug.py:9: error: Item "None" of "Optional[str]" has no attribute "upper"

NOTE: Same error with returning "Union[str, None]"
NOTE: Removing the Optional[str] stops the error, but that defaults the point

def find1(name: str):
    return next(
        filter(
            lambda animal: animal.upper() == name,
            animals,
        ),
        None,
    )

Your Environment

  • Mypy version used: 0.812
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.9.4
  • Operating system and version: MacOS 10.15.7
@michaelbrewer michaelbrewer added the bug mypy got something wrong label May 6, 2021
@hauntsaninja
Copy link
Collaborator

From the title I thought it was going to be a dupe of #2608, but it's not!

The dumb workaround is:

from typing import Optional

animals = ["cow"]


def find1(name: str) -> Optional[str]:
    ret = next(
        filter(
            lambda animal: animal.upper() == name,
            animals,
        ),
        None,
    )
    return ret

I think this boils down to the fact that mypy does complicated things to infer types for lambdas. If there's an annotation, it takes into account what type the expression is expected to be to try and understand the lambda. E.g., if you were to change ret = next(...) to ret: Optional[str] = next(...) you'd also get an error.

@michaelbrewer
Copy link
Author

Thanks @hauntsaninja , my lint tools would have suggested to immediately return :). So i guess it is a coin flip.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

2 participants