Skip to content

dataclass.__eq__ no longer errors on missing attributes in Python 3.13 #134488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
willhcr opened this issue May 22, 2025 · 5 comments
Closed

dataclass.__eq__ no longer errors on missing attributes in Python 3.13 #134488

willhcr opened this issue May 22, 2025 · 5 comments
Labels
3.13 bugs and security fixes 3.14 bugs and security fixes 3.15 new features, bugs and security fixes stdlib Python modules in the Lib dir topic-dataclasses type-bug An unexpected behavior, bug, or error

Comments

@willhcr
Copy link

willhcr commented May 22, 2025

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

@willhcr willhcr added the type-bug An unexpected behavior, bug, or error label May 22, 2025
@ZeroIntensity ZeroIntensity added topic-dataclasses stdlib Python modules in the Lib dir 3.13 bugs and security fixes 3.14 bugs and security fixes 3.15 new features, bugs and security fixes labels May 22, 2025
@ZeroIntensity
Copy link
Member

I'm not sure there's anything we can do at this point.

@willhcr
Copy link
Author

willhcr commented 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
Copy link

F18-Ray commented May 23, 2025

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

I watched your code and I think I fix your bug.
`import dataclasses
@dataclasses.dataclass
class Test:
#a: int # why use "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)
print(o1 == o2)`
You may try this, and I actually don't know why you use "a:int", It's use less.

@rhettinger
Copy link
Contributor

rhettinger commented May 24, 2025

This class is badly behaved, it should probably still raise an error.

FWIW no error is raised if o1 is stored in a list instead of dataclass:

>>> s = [o1]
>>> s == s
True

@rhettinger
Copy link
Contributor

I'm not sure there's anything we can do at this point.

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.

@rhettinger rhettinger closed this as not planned Won't fix, can't repro, duplicate, stale May 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.13 bugs and security fixes 3.14 bugs and security fixes 3.15 new features, bugs and security fixes stdlib Python modules in the Lib dir topic-dataclasses type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

4 participants