Uh oh!
There was an error while loading. Please reload this page.
gh-137658: Fix dataclass order method behaviors to align with the equality semantics - #137497
gh-137658: Fix dataclass order method behaviors to align with the equality semantics#137497gesslerpd wants to merge 12 commits into
Conversation
Don't use a PR number as the issue prefix, things get confused. Please can you create an issue for this PR, and add a NEWS entry? Please can you use a A |
ericvsmith
commented
Aug 7, 2025
We need to be very careful that we're not changing semantics with this. We've had that problem before with comparisons (although of course now I can't find the issue). I don't think we added tests for this, because we didn't find the problem until after we'd released the code. |
gesslerpd
commented
Aug 7, 2025
@ericvsmith so we need set of tests that pass prior to this change? Potentially relevant "semantics" you mention may be shown in the tests for this change in #582? |
ericvsmith
commented
Aug 9, 2025
I'm specifically thinking of #128294. We don't want to do something like that again. I haven't looked at this change closely, I just want to be extra careful. |
@ericvsmith Thanks for that info, I looked into the situation a bit and it seems that since the behavior of 3.13 for I will file an issue for this @dataclasses.dataclass(order=True, slots=True)classData:
a: floatclassObj:
__slots__="a",
def__init__(self, a: float):
self.a=adef__eq__(self, other):
ifselfisother:
returnTrueifself.__class__isother.__class__:
return (
self.a==other.a
)
returnNotImplementeddef__lt__(self, other):
ifself.__class__isother.__class__:
returnself.a<other.areturnNotImplementeddef__le__(self, other):
ifself.__class__isother.__class__:
returnself.a<=other.areturnNotImplementeddef__gt__(self, other):
ifself.__class__isother.__class__:
returnself.a>other.areturnNotImplementeddef__ge__(self, other):
ifself.__class__isother.__class__:
returnself.a>=other.areturnNotImplementednan=float("nan")
assertnot (Data(nan) <Data(nan))
# assert not (Data(nan) <= Data(nan)), "fails on 3.13 even though {<, ==} are both False"assertnot (Data(nan) >Data(nan))
# assert not (Data(nan) >= Data(nan)), "fails on 3.13 even though {>, ==} are both False"assert (Data(nan) !=Data(nan))
assertnot (Data(nan) ==Data(nan))
assertnot (Obj(nan) <Obj(nan))
assertnot (Obj(nan) <=Obj(nan))
assertnot (Obj(nan) >Obj(nan))
assertnot (Obj(nan) >=Obj(nan))
assert (Obj(nan) !=Obj(nan))
assertnot (Obj(nan) ==Obj(nan)) |
gesslerpd
commented
Sep 2, 2025
@AA-Turner thanks, added those details except the performance part. Rebranded the PR as a fix now that the linked issue is related to aligning behavior semantics with #104904 @ericvsmith I added tests to show the behavior and how it aligns with the 3.13+ equality methods. Some of the assertions would fail on |
There was a problem hiding this comment.
Pull request overview
This PR fixes a semantic misalignment in dataclass order methods (__lt__, __le__, __gt__, __ge__) that occurred after the __eq__ method was optimized in Python 3.13+ (PR #104904). The order methods previously used tuple comparison semantics, which caused incorrect behavior with NaN values - specifically, <= and >= would return True even when both </> and == returned False.
Key changes:
- Order methods now use field-by-field comparison with early exit, matching the
__eq__semantics - Added identity check (
self is other) optimization for all comparison operators - Improved performance by avoiding tuple allocation and enabling early termination
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| Lib/dataclasses.py | Rewrote order method generation to use field-by-field comparison instead of tuple comparison, adding self-identity optimization |
| Lib/test/test_dataclasses/init.py | Added comprehensive tests for self-comparison and NaN handling with both single and multi-field dataclasses |
| Misc/NEWS.d/next/Core_and_Builtins/2025-08-11-19-26-46.gh-issue-137658.VaIFLO.rst | Added release note documenting the fix |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
gesslerpd
commented
Dec 11, 2025
@ericvsmith I added comments to the test (marked Hopefully the added tests/comments makes the changes easier to review. |
This PR is stale because it has been open for 30 days with no activity. |
gesslerpd
commented
May 7, 2026
ping |
This change writes the order methods in a way more consistent with the current accepted semantics of
__eq__after it was optimized in #104904 .Ever since semantics of
__eq__changed in 3.13+ the order methods have still been using the direct tuple semantics causing a slight misalignment shown in the linked issue.Additional benefit, this can speed up ordering/comparison operations making the comparison similar to existing
__eq__performance.