Skip to content

False "Invalid index type" for min derived from return type #14664

New issue

Have a question about this project? No Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “No 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? No Sign in to your account

Open
ods opened this issue Feb 9, 2023 · 2 comments · May be fixed by #18976
Open

False "Invalid index type" for min derived from return type #14664

ods opened this issue Feb 9, 2023 · 2 comments · May be fixed by #18976
Labels
bug mypy got something wrong topic-type-context Type context / bidirectional inference

Comments

@ods
Copy link

ods commented Feb 9, 2023

Bug Report

Mypy gives [index] error for key when calling min from function that is declared to return Optional.

To Reproduce

This pretty valid

def func() -> Optional[int]:
    d = {1: 2, 3: 4}
    return min([1, 2], key=lambda k: d[k], default=None)

returns error

Invalid index type "Optional[int]" for "Dict[int, int]"; expected type "int"  [index]

Changing default to 0 doesn't fix the problem, but changing return type of func to int does. So, the following works fine:

def func() -> int:
    d = {1: 2, 3: 4}
    return min([1, 2], key=lambda k: d[k], default=0)

Expected Behavior

No error for the first example, as default is never compared to objects in collection.

Actual Behavior

Invalid index type "Optional[int]" for "Dict[int, int]"; expected type "int"  [index]

Your Environment

  • Mypy version used: 1.0.0
  • Mypy command-line flags: no
  • Mypy configuration options from mypy.ini (and other config files): no
  • Python version used: 3.10
@ods ods added the bug mypy got something wrong label Feb 9, 2023
@JelleZijlstra JelleZijlstra added the topic-type-context Type context / bidirectional inference label Feb 9, 2023
@EdwardEisenhauer
Copy link

I experienced a similar issue with the following code:

from typing import Optional


class MyObject:
    def __init__(self, attribute: int) -> None:
        self.attribute = attribute


def find_biggest_attribute(objects: list[MyObject]) -> Optional[MyObject]:
    return max(objects, default=None, key=lambda object: object.attribute)


print(find_biggest_attribute([MyObject(42), MyObject(41)]))

print(find_biggest_attribute([]))

Running mypy raises:

mypy_bug.py:10: error: Item "None" of "Optional[MyObject]" has no attribute "attribute"  [union-attr]
        return max(objects, default=None, key=lambda object: object.attribute)
                                                             ^~~~~~~~~~~~~~~~
Found 1 error in 1 file (checked 1 source file)

As per Python built-in max() documentation:

The default argument specifies an object to return if the provided iterable is empty. If the iterable is empty and default is not provided, a ValueError is raised.

@EugeneYushin
Copy link

Know what:

def func() -> Optional[int]:
    d = {1: 2, 3: 4}
    x = min([1, 2], key=lambda k: d[k], default=None)
    return x

# mypy.....................................................................Passed

This is odd

No Sign up for free to join this conversation on GitHub. Already have an account? No Sign in to comment
Labels
bug mypy got something wrong topic-type-context Type context / bidirectional inference
Projects
None yet
4 participants