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

Narrowed down types sometimes not propagated to lambda #4297

Closed
JukkaL opened this issue Nov 30, 2017 · 2 comments · Fixed by #16407
Closed

Narrowed down types sometimes not propagated to lambda #4297

JukkaL opened this issue Nov 30, 2017 · 2 comments · Fixed by #16407
Labels
bug mypy got something wrong priority-1-normal topic-strict-optional topic-type-narrowing Conditional type narrowing / binder

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Nov 30, 2017

The errors generated for the following code are invalid (when using --strict-optional):

from typing import Optional, Callable

def f1(key: Callable[[], str]) -> None: ...
def f2(key: object) -> None: ...

def g(b: Optional[str]) -> None:
    if b:
        f1(lambda: b.upper())  # Item "None" of "Optional[str]" has no attribute "upper"
        z: Callable[[], str] = lambda: b.upper()  # Item "None" of "Optional[str]" has no attribute "upper"
        f2(lambda: b.upper())  # No error
        lambda: b.upper()  # No error

My hypothesis is that callable type context for lambda somehow affects how type narrowing behaves.

This was reported by @tueda on Gitter.

@ikonst
Copy link
Contributor

ikonst commented Dec 31, 2018

Workaround:

def g(b: Optional[str]) -> None:
    if b:
        _b = b  # https://github.com/python/mypy/issues/4297
        f1(lambda: _b.upper())

@calimeroteknik
Copy link

This also seems to happen with native collection types whose size is "runtime" (i.e. recursive types in lambda-calculus terms), but not tuples (whose size is "fixed").

Error / non-error cases added for reproduction, based on the original post:

from typing import Optional, Callable

def f1(key: Callable[[], str]) -> None: ...
def f2(key: object) -> None: ...

def g(b: Optional[str]) -> None:
    if b is not None:
        f1(lambda: b.upper())  # Item "None" of "Optional[str]" has no attribute "upper"
        z: Callable[[], str] = lambda: b.upper()  # Item "None" of "Optional[str]" has no attribute "upper"
        d = { "foo": lambda: b.upper() }  # Item "None" of "Optional[str]" has no attribute "upper"
        l = [ lambda: b.upper() ]  # Item "None" of "Optional[str]" has no attribute "upper"
        t = ( lambda: b.upper(), ) # No error
        f2(lambda: b.upper())  # No error
        lambda: b.upper()  # No error

@JelleZijlstra JelleZijlstra added the topic-type-narrowing Conditional type narrowing / binder label Mar 19, 2022
ilevkivskyi added a commit that referenced this issue Nov 4, 2023
Fixes #4297

Fix is straightforward: without properly pushing lambda expression on
the stack, the previous fix @JukkaL added for nested functions doesn't
work for lambdas (it thinks that we are at global scope).
JukkaL pushed a commit that referenced this issue Nov 10, 2023
Fixes #4297

Fix is straightforward: without properly pushing lambda expression on
the stack, the previous fix @JukkaL added for nested functions doesn't
work for lambdas (it thinks that we are at global scope).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong priority-1-normal topic-strict-optional topic-type-narrowing Conditional type narrowing / binder
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants