Skip to content

Type inference for max() "tainted" by default #16267

Open
@jwodder

Description

@jwodder

Consider the following code:

from __future__ import annotations
from collections.abc import Iterable
from packaging.version import Version

def best_str(strs: Iterable[str]) -> str | None:
    return max(strs, key=keyfunc, default=None)


def keyfunc(s: str) -> str:
    return s[::-1]

I believe this should type-check without issue; in particular, by my reading of max()'s type annotations in typeshed, the key callable should be expected to take only those types contained in the iterable. However, mypy disagrees:

max-arg2.py:6: error: Argument "key" to "max" has incompatible type "Callable[[str], str]"; expected "Callable[[str | None], SupportsDunderLT[Any] | SupportsDunderGT[Any]]"  [arg-type]

Note that mypy expects the key callable to accept str | None even though strs is an Iterable[str]. Moreover, if the default argument is omitted and the return type of best_str() is changed to str, then mypy accepts the code.

Your Environment

  • Mypy version used: 1.6.0
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.11.6

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions