Skip to content

total_ordering generated methods should derive their signature from the user-provided comparison method #2435

@behrmann

Description

@behrmann

Summary

Thanks for adding @total_ordering support with ruff#22181!

Adapting the motivating example from #1202, mixing this with literals does not yet work:

import functools


@functools.total_ordering
class Comparable:
    def __init__(self, value: int):
        self.value = value

    def __eq__(self, other: object) -> bool:
        if isinstance(other, Comparable):
            return self.value == other.value
        if isinstance(other, int):
            return self == Comparable(other)
        return False

    def __lt__(self, other: object) -> bool:
        if isinstance(other, Comparable):
            return self.value < other.value
        if isinstance(other, int):
            return self < Comparable(other)
        return False

    # # Uncommenting this implementation satisfies ty
    # def __le__(self, other) -> bool:
    #     if isinstance(other, Comparable):
    #         return self.value <= other.value
    #     if isinstance(other, int):
    #         return self <= Comparable(other)
    #     return False



a = Comparable(1)
b = 2

print(a <= b)

Both mypy and pyright accept this code. In mkosi code similar to this is used for version checking, where the underlying algorithm works on strings, but version objects, strings and integers need to be covered.

Version

ty 0.0.11 (830cb9c 2026-01-09)

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingruntime semanticsAccurate modeling of how Python's semantics work at runtime

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions