Skip to content

Order of clause in one-line if/else statement yields different mypy behaviors #8519

Description

@fgmehlin

I may have encountered a bug in Mypy's inference of types when using a one-line if/else statement:

The issue appears when returning a lambda function or a standard built-in (in that case print), depending on a bool.

import typing as t

def get_print_fn(quiet: bool) -> t.Callable[..., None]:
    """Return the standard print function if quiet is False, else an empty function."""
    return (lambda *args, **kwargs: None) if quiet else print

^^^ The above raises the following Mypy error:
Incompatible return value type (got "function", expected "Callable[..., None]")

However, reversing the condition like below does not show any error.

import typing as t

def get_print_fn(quiet: bool) -> t.Callable[..., None]:
    """Return the standard print function if quiet is False, else an empty function."""
    return print if not quiet else lambda *args, **kwargs: None

This somehow suggests that mypy is using the type of the if block to infer the return type? I'm not sure whether this is intended or indeed a bug.

Meta information

  • mypy version: 0.761
  • mypy.ini
[mypy]
python_version = 3.7
warn_return_any = True
warn_unused_ignores = True
warn_unreachable = True
namespace_packages = True
show_column_numbers = True
strict_equality = True
no_implicit_optional = True
disallow_untyped_defs = True
disallow_any_generics = True
disallow_untyped_calls = True

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions