python / python/mypy

Cannot determine type of "__gt__" error on decorated __lt__ method where decorator is an assigned alias of another decorator

Open
#10,943 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-type-alias
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Okay, this one has me stumped.

I am getting a Cannot determine type of "__gt__" error on my definition of __lt__. Yes. You read that right. The error complains of __gt__, but happens on def __lt__ …. If I swap the declaration order (such that def __gt__ … appears before def __lt__ …), then I get the error Cannot determine type of "__lt__" error on my definition of __gt__, so at least it's…symmetrical.

The problem only emerges when I use an alias for a decorator created by assignment.

To Reproduce

# test_cast.py
from operator import __gt__, __lt__
from typing import Callable, TypeVar, Union

_T = TypeVar("_T")

def identity(__: _T) -> _T:
    return __

maybe_not_available_decorator = identity  # <-- problematic decorator alias

# try:
#     from spicy import spicy_decorator as maybe_not_available_decorator
# except ImportError:
#     pass

class Spam:
    def __init__(self, value: int):
        super().__init__()
        self._value = value

    @identity  # <- function
    def __lt__(self, other: Union[int, "Spam"]) -> bool:  # <-- this is fine
        if isinstance(other, Spam):
            return __lt__(self._value, other._value)
        else:
            return NotImplemented

    @identity  # <- function
    def __gt__(self, other: Union[int, "Spam"]) -> bool:  # <-- so is this
        if isinstance(other, Spam):
            return __gt__(self._value, other._value)
        else:
            return NotImplemented

class Ham:
    def __init__(self, value: int):
        super().__init__()
        self._value = value

    @maybe_not_available_decorator  # <- alias
    def __lt__(self, other: Union[int, "Ham"]) -> bool:  # <-- Cannot determine type of "__gt__"
        if isinstance(other, Ham):
            return __lt__(self._value, other._value)
        else:
            return NotImplemented

    @maybe_not_available_decorator  # <- alias
    def __gt__(self, other: Union[int, "Ham"]) -> bool:  # <-- this is fine for some reason
        if isinstance(other, Ham):
            return __gt__(self._value, other._value)
        else:
            return NotImplemented

Your Environment

% mypy --config-file=/dev/null test_case.py
/dev/null: No [mypy] section in config file
test_case.py:42: error: Cannot determine type of "__gt__"
Found 1 error in 1 file (checked 1 source file)
% mypy --version
mypy 0.910

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproducer in test_case.py and run mypy --config-file=/dev/null to confirm the reported error for the decorated Ham methods. Compare the identity decorator with its assigned alias, then trace mypy's decorator and special-method analysis. Done means the alias form produces no spurious Cannot determine type error while the existing behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.