Skip to content

False positive and negative with lambda narrowing #16056

Closed
@md2468

Description

@md2468

Bug Report

Type narrowing does not work correctly in function bodies. Even if the type is narrowed down in the context in which a function or a lambda is defined, that narrowing seems to be 'forgotten' within the function body.

To Reproduce

x: int | None = 1

# Either of these two type checks produces identical results:
if isinstance(x, int):
# if x is not None:

    # Revealed type is "builtins.int"
    reveal_type(x)
    
    def f() -> int: 
         # Revealed type is "Union[builtins.int, None]"
        reveal_type(x)
        
        # error: Unsupported operand types for + ("None" and "int")  [operator]
        # note: Left operand is of type "int | None"
        # return x + 2 
        
        # No errors here:
        return 1 + 2
    
    # error: Unsupported operand types for + ("None" and "int")  [operator]
    # note: Left operand is of type "int | None"
    # (lambda: x + 2)()
    
    # No errors here:
    (lambda: 1 + 2)()
    
    # However, defining a lambda without calling it does not cause errors:
    l = lambda: x + 2

Gist URL: https://gist.github.com/mypy-play/41141b62a73edc56b6561088adea8ebf
Playground URL: https://mypy-play.net/?mypy=latest&python=3.11&flags=strict&gist=41141b62a73edc56b6561088adea8ebf

Expected Behavior

No errors in the lines where errors are actually reported. Type narrowing should make all of these expressions valid.

Actual Behavior

The errors given in the comments.

Your Environment

  • Mypy version used: 1.5.1.
  • Mypy command-line flags: tested with no flags and --strict.
  • Mypy configuration options from mypy.ini (and other config files): None.
  • Python version used: 3.11.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions