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

Variable inside returned lambda loses conditional type information #14997

Closed
gwax opened this issue Apr 2, 2023 · 3 comments
Closed

Variable inside returned lambda loses conditional type information #14997

gwax opened this issue Apr 2, 2023 · 3 comments
Labels
bug mypy got something wrong

Comments

@gwax
Copy link

gwax commented Apr 2, 2023

Bug Report

When returning a lambda containing an uncaptured variable, mypy losing conditional information about the type of that variable.

To Reproduce

https://mypy-play.net/?mypy=latest&python=3.11&gist=634d85b9f00175d6b4a1f4929d3ba848

from typing import Callable

def foo(i: int) -> int:
    return i
    
def bar(j: int | None) -> Callable[[], int]:
    if j is not None:
        return lambda: foo(j) # <- error
    return lambda: -1
    
def baz(j: int | None) -> Callable[[], int]:
    if j is not None:
        def inner():
            return foo(j)
        return inner
    return lambda: -1

Expected Behavior

no error for lambda or inner function

Actual Behavior

the returned lambda results in an error

main.py:8: error: Argument 1 to "foo" has incompatible type "Optional[int]"; expected "int"  [arg-type]

Your Environment

  • Mypy version used: 1.1.1 (mypy-play)
  • Python version used: 3.11 (mypy-play)
@gwax gwax added the bug mypy got something wrong label Apr 2, 2023
@rhithesh
Copy link

rhithesh commented Apr 2, 2023

hey we can use cast(int,j) INSTEAD OF foo(j) I looked it up online.

@erictraut
Copy link

This is a duplicate of #2608.

You can work around this limitation by assigning the narrowed value to a temporary variable.

def bar(j: int | None) -> Callable[[], int]:
    if j is not None:
        j2 = j
        return lambda: foo(j2)
    return lambda: -1

@AlexWaygood AlexWaygood closed this as not planned Won't fix, can't repro, duplicate, stale Apr 2, 2023
@eltoder
Copy link

eltoder commented Aug 7, 2023

@erictraut @AlexWaygood #2608 is closed as done, but this examples still fails. Also note that using a nested def works, only lambdas are affected. Maybe there's a separate bug with lambdas?

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

5 participants