You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Inconsistent dataclass order behavior on Python 3.13+ #137658
Semantics of dataclasses __eq__ have changed in Python 3.13+, the semantic is now inconsistent with the order=True generated set of dunder methods on the same Python 3.13+ versions.
@dataclasses.dataclass(order=True)classData:
a: floatnan=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))
Can you please show code where the values of comparisons change as a result of this PR? I presume they're all NaN related, or values with equally wacky comparison methods. But I'd like any actual change in semantics to be noted.
@ericvsmith Yes related to weird NaN-like objects, in the example code above the commented out lines will fail. Added similar tests to the PR that pass for this scenario, but generally the PR writes the order methods in a way more consistent with the current accepted semantics of __eq__ after it was optimized.
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 this issue.
@ericvsmith is there a decision on whether we want to change this?
It's not something that can be changed without also updating the documentation (as has been done for equality and which the current PR doesn't include) but is this something we want to do or should we close related issues?
There is also a separate issue #144191 and PR #144222 to do a similar thing but only for classes with one field. However I think if we're going to do this we should do so for all dataclasses rather than special casing single field classes.
I'm aware of 2 cases, both related to is not matching == whose behaviour would be modified by this change:
Classes with specific instances that compare unequal to themselves, such as float("nan")
Objects for which inst1 is inst2 is True but inst1 == inst2 or the subsequent conversion to boolean fails, like np.ndarray
The first case is an observable difference, but one that would now match the new equality behaviour.
For the second case, I don't think including fields that aren't orderable or comparable in a dataclass with order=True makes any sense but it is technically a change in behaviour.
False
True
ValueError('The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()')
PR Logic:
ValueError('The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()')
ValueError('The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()')
Activity
ericvsmith commentedon Sep 19, 2025
Can you please show code where the values of comparisons change as a result of this PR? I presume they're all NaN related, or values with equally wacky comparison methods. But I'd like any actual change in semantics to be noted.
gesslerpd commentedon Sep 24, 2025
@ericvsmith Yes related to weird NaN-like objects, in the example code above the commented out lines will fail. Added similar tests to the PR that pass for this scenario, but generally the PR writes the order methods in a way more consistent with the current accepted semantics of
__eq__after it was optimized.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 this issue.DavidCEllis commentedon Nov 10, 2026
@ericvsmith is there a decision on whether we want to change this?
It's not something that can be changed without also updating the documentation (as has been done for equality and which the current PR doesn't include) but is this something we want to do or should we close related issues?
There is also a separate issue #144191 and PR #144222 to do a similar thing but only for classes with one field. However I think if we're going to do this we should do so for all dataclasses rather than special casing single field classes.
I'm aware of 2 cases, both related to
isnot matching==whose behaviour would be modified by this change:float("nan")inst1 is inst2isTruebutinst1 == inst2or the subsequent conversion to boolean fails, likenp.ndarrayThe first case is an observable difference, but one that would now match the new equality behaviour.
For the second case, I don't think including fields that aren't orderable or comparable in a dataclass with
order=Truemakes any sense but it is technically a change in behaviour.Behaviour demonstrations
float("nan")Main:
PR:
np.ndarray3.15.2
PR Logic: