Description
Bug report
Bug description:
Description
Equality with self now returns True in 3.13 for dataclasses with deleted attributes. Previously, this would raise an exception.
This may be related to changes discussed in #128294. However, unlike
other reports (#120645, #116647) where something that was True in 3.12 is now False or an Exception,
this issue is the inverse. In 3.13, the equality test silently returns True when previously it would raise.
This class is badly behaved, it should probably still raise an error.
Test Case
import dataclasses
@dataclasses.dataclass
class Test:
a: int
def __init__(self):
self.a = 1
def del_a(self):
del self.a
o1 = Test()
o2 = Test()
o1.del_a()
o2.del_a()
print(o1 == o1) # True (3.13), raises AttributeError (3.12)
print(o1 == o2) # raises AttributeError (3.13, 3.12)
# AttributeError: 'Test' object has no attribute 'a'
CPython versions tested on:
3.13, 3.12
Operating systems tested on:
Linux
Activity
ZeroIntensity commentedon May 22, 2025
I'm not sure there's anything we can do at this point.
willhcr commentedon May 22, 2025
A note in the 3.13 What's New would be helpful.
For context, I discovered this when debugging behavior differences in async library internals between 3.12 and 3.13. A dataclass with deleted attributes was stored in a contextvar:
https://github.com/django/asgiref/blob/5eff04dce46b74172a1d6d1c5b02409f0afe33b6/asgiref/sync.py#L44-L53
F18-Ray commentedon May 23, 2025
I watched your code and I think I fix your bug.
`import dataclasses
@dataclasses.dataclass
class Test:
#a: int # why use "a:int"
o1 = Test()
o2 = Test()
o1.del_a()
o2.del_a()
print(o1 == o1)
print(o1 == o2)`
You may try this, and I actually don't know why you use "a:int", It's use less.
rhettinger commentedon May 24, 2025
FWIW no error is raised if
o1
is stored in a list instead of dataclass:rhettinger commentedon May 28, 2025
And given that other tools like
list
do not raise an exception, there's not anything we should do at the point.Closing for now. If this proves problematic in practice, we can reopen.