Skip to content

Breaking change of dataclasses.dataclass comparison semantics in 3.13+ #128294

Description

@daskol

Bug report

Bug description:

Brief Description

Optimization done in #109870 changed semantic of dataclass comparison.

Description

The pseudo code below shows meaning of changes have been done in #109870. The semantic differs largely because of a shortcut in __eq__ implementation of sequence-like containers (see Objects/object.c). The shortcut essentially does self[i] is other[i]. Consequently, method __eq__ of self[i] is not evaluated for identical objects in 3.12 during dataclasses.dataclass comparison.

def__eq__312(self, other):
returnastuple(self) ==astuple(other)
def__eq__313(self, other):
forlhs, rhsinzip(astuple(self), astuple(other)):
ifnotlhs==rhs:
returnFalseelse:
returnTrue

According Python docs (citation below), v3.13 introduces breaking change since it does not consider fields as a tuples for dataclass comparison.

eq: If true (the default), an __eq__() method will be generated. This method compares the class as if it were a tuple of its fields, in order. Both instances in the comparison must be of the identical type.

Test Case

importnumpyasnpfromdataclassesimportdataclass@dataclassclassA:
xs: np.ndarraya=A(np.ones(3))
b=A(a.xs)
print(a==b) # FAIL (3.13); OK (3.12).# ValueError: Value The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

CPython versions tested on:

3.13 (3.12)

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

Labels

3.13bugs and security fixes3.14bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytopic-dataclassestype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions