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

error: Right operand of "or" is never evaluated - although it is evaluated at some point #14120

Open
pcustic opened this issue Nov 17, 2022 · 3 comments
Labels
bug mypy got something wrong topic-inference When to infer types or require explicit annotations topic-reachability Detecting unreachable code topic-strict-optional

Comments

@pcustic
Copy link

pcustic commented Nov 17, 2022

Bug Report

Mypy is giving out error: Right operand of "or" is never evaluated on a statement that is evaluated. It is part of a for loop and it is not evaluated on the first pass of the loop, however it is evaluated on each consecutive pass of the for loop.

I understand why the right side is not evaluated on the first pass, but I feel that it should not error out on this code as it is evaluated at some point. Or at least the error message should be different.

To Reproduce

Playground link

This is simplified example of the code I'm seeing this error in.

from __future__ import annotations

from typing import Optional


class Role:
    def __init__(self, rank: int):
        self.rank = rank

    def __str__(self):
        return f'Role with rank {self.rank}'

    def is_more_important_than(self, other_role: Role) -> bool:
        return self.rank > other_role.rank


def find_highest_role(some_roles: list[Role]) -> Optional[Role]:
    highest_role = None

    for role in some_roles:
        if not highest_role or role.is_more_important_than(highest_role):  # error is here
            highest_role = role

    return highest_role


some_roles = [
    Role(10),
    Role(1),
    Role(6),
    Role(7),
    Role(11),
    Role(25),
]

print(find_highest_role(some_roles))

Expected Behavior

Success.

Actual Behavior

Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: mypy 0.982 (compiled: yes)
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files):
warn_redundant_casts = true
warn_unreachable = true
warn_unused_configs = true
warn_unused_ignores = true
  • Python version used: Python 3.9
@pcustic pcustic added the bug mypy got something wrong label Nov 17, 2022
@pcustic pcustic changed the title error: Right operand of "or" is never evaluated - although it is error: Right operand of "or" is never evaluated - although it is evaluated at some point Nov 17, 2022
@tmke8
Copy link
Contributor

tmke8 commented Nov 17, 2022

It works if you define the variable like this:

highest_role: Optional[Role] = None

because otherwise mypy thinks the variable has the type None. But it's still weird that mypy didn't complain about the assignment within the loop if it thought that the type is None...

highest_role = role

@AlexWaygood AlexWaygood added topic-inference When to infer types or require explicit annotations topic-reachability Detecting unreachable code topic-strict-optional labels Nov 17, 2022
@pcustic
Copy link
Author

pcustic commented Nov 17, 2022

It works if you define the variable like this:

highest_role: Optional[Role] = None

Yes, you are correct, that works, thanks! I was sure I tried that but.. 🤔

But it's still weird that mypy didn't complain about the assignment within the loop if it thought that the type is None...

Yeah, I would also say it should complain about that.

@DevilXD
Copy link

DevilXD commented Nov 24, 2022

It seems like MyPy just doesn't want to warn about the inferred type being None at first, and then silently changing it to Union[Role, None] after the assignment, no matter which options I try to use on the playground. There should be at least a possibility of generating a "need type annotation" warning on the untyped local variable. From the documentation, it seems like --local-partial-types should cause a warning like this to be generated, but it doesn't do so in this case, for some reason.

@pcustic As a general tip for the future, if you want to avoid getting "weird" errors like this, always check if the variable involved in the error you're getting is properly typed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-inference When to infer types or require explicit annotations topic-reachability Detecting unreachable code topic-strict-optional
Projects
None yet
Development

No branches or pull requests

4 participants