microsoft / microsoft/pyright

When a data-class with `order=True` is being subclassed, the comparator methods get re-synthesized, and therefore have argument types narrowed

Open
#10,667 1 comment 0 reactions 0 assignees View on GitHub
bug needs decision
Dominant language
Python
Stars
15.6k
Forks
1.8k
Avg merge
12h 13m
Merged PRs (30d)
52

Description

**Describe the bug**

When a data-class, for example with the name `DataClass`, is declared with `order=True`, it will have several comparator methods like `__lt__` synthesized as `def __lt__(self, other: DataClass) -> bool: ...`.

And when I have some plain subclasses(without a `dataclass` decorator) of this data-class, I expect the subclasses inherit those comparator methods as-is. But it seems that those comparator methods get re-synthesized and the argument types get narrowed to the subclasses respectively. As a result, instances of different subclasses are not comparable with each other.

It may be rare that a data-class be subclassed without a `dataclass` decorator, but this behavior also affects `NewType` which I'm using in my project.

**Code or Screenshots**

```python
from __future__ import annotations

from dataclasses import dataclass
from typing import NewType

@dataclass(order=True)
class DataClass:
pass

_ = DataClass() < DataClass() # OK

class DataClassA(DataClass): ...
class DataClassB(DataClass): ...

_ = DataClassA() < DataClassB() # Reported.

NewDataClassA = NewType("NewDataClassA", DataClass)
NewDataClassB = NewType("NewDataClassB", DataClass)

_ = NewDataClassA(DataClass()) < NewDataClassB(DataClass()) # Reported.
```

**VS Code extension or command-line**

This behavior is found on Pyright 1.1.402 and can be observed on much old versions.

Contributor guide

Open the contributing guide

Research direction

Start by tracing Pyright's handling of dataclass(order=True) synthesized comparator methods and how those methods are inherited by plain subclasses and NewType aliases. Add regression coverage for cross-subclass comparisons and NewType-wrapped instances, ensuring inherited comparator parameter types are not narrowed. Done when these examples no longer report errors while direct DataClass comparisons retain their existing checking.

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.