Skip to content

gh-137658: Fix dataclass order method behaviors to align with the equality semantics - #137497

Open
gesslerpd wants to merge 12 commits into
python:mainfrom
gesslerpd:perf-dataclass-order
Open

gh-137658: Fix dataclass order method behaviors to align with the equality semantics#137497
gesslerpd wants to merge 12 commits into
python:mainfrom
gesslerpd:perf-dataclass-order

Conversation

@gesslerpd

@gesslerpdgesslerpd commented Aug 7, 2025

Copy link
Copy Markdown
Contributor

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.

@gesslerpdgesslerpd changed the title gh-*: Performance optimization for dataclass order methodsgh-137497: Performance optimization for dataclass order methodsAug 7, 2025
@AA-TurnerAA-Turner changed the title gh-137497: Performance optimization for dataclass order methodsPerformance optimization for dataclass order methodsAug 7, 2025
@AA-Turner

AA-Turner commented Aug 7, 2025

Copy link
Copy Markdown
Member

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 pyperformance benchmark, and update the PR with the benchmark code and results? Microbenchmark results should show a reasonably large performance improvement, which this PR hopefully will based on the preliminary numbers you've shown.

A

@ericvsmith

Copy link
Copy Markdown
Member

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

Copy link
Copy Markdown
ContributorAuthor

@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

Copy link
Copy Markdown
Member

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.

@gesslerpd

gesslerpd commented Aug 12, 2025

Copy link
Copy Markdown
ContributorAuthor

@ericvsmith Thanks for that info, I looked into the situation a bit and it seems that since the behavior of 3.13 for __eq__ is accepted as intended now that this may actually fix things to be consistent with that.

I will file an issue for this order=True discrepancy on 3.13 and link this PR.

@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))

@gesslerpdgesslerpd changed the title Performance optimization for dataclass order methodsgh-137658: Fix dataclass order method behaviors to align with the equality semanticsAug 12, 2025
@gesslerpd

Copy link
Copy Markdown
ContributorAuthor

@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 main branch as described in the linked issue.

CopilotAI review requested due to automatic review settings December 11, 2025 04:08

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

FileDescription
Lib/dataclasses.pyRewrote order method generation to use field-by-field comparison instead of tuple comparison, adding self-identity optimization
Lib/test/test_dataclasses/init.pyAdded 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.rstAdded release note documenting the fix

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@gesslerpd

Copy link
Copy Markdown
ContributorAuthor

@ericvsmith I added comments to the test (marked gh-137658#137658) that describe how this now aligns the order methods with the Python 3.13+ __eq__ semantic changes.

Hopefully the added tests/comments makes the changes easier to review.

@github-actions

Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

@github-actionsgithub-actionsBot added the stale Stale PR or inactive for long period of time. label Apr 27, 2026
@gesslerpd

Copy link
Copy Markdown
ContributorAuthor

ping

@github-actionsgithub-actionsBot removed the stale Stale PR or inactive for long period of time. label May 15, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@gesslerpd@AA-Turner@ericvsmith@nazeerali4325-commits