Skip to content

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

Closed

Description

@pcustic

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

Activity

  1. 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[/+] on Nov 17, 2022
  2. tmke8 commented on Nov 17, 2022

    @tmke8
    Contributor

    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
  3. pcustic commented on Nov 17, 2022

    @pcustic
    Author

    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.

  4. DevilXD commented on Nov 24, 2022

    @DevilXD

    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.

  5. A5rocks commented on Jan 22, 2025

    @A5rocks
    Collaborator

    Fixed by #18433

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions