-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
dataclass(a=nan) == dataclass(a=nan) change in truthnes between 3.12 and 3.13 #120645
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
Comments
Bugfixes and internal changes are not listed in What's New except by reference to the changelob. I am pretty sure you found the right issue. Built-in collections intentionally compares elements by
These considerations do not normally apply to class instances, so I think that 'regression' versus 'bugfix' may be a decision (not by me) rather than a fact. NAN are nasty. But thank you for noticing and raising the issue. |
Roughly, this is the essential difference in the generated code:
I don't think the prior behavior of NaNs comparing equal on the basis of identity was an intended or desired behavior. That said, the change in behavior wasn't intended either. NaN identity comparisons weren't considered at all. Personally, I think the new behavior is the best behavior for dataclasses. The norm for pure python classes is for The old behavior is a bit weird. Think about it. Two distinct dataclass instances compare as equal but their components compare as unequal even though there are no special There is a case to be made either way. According to IEEE-741, NaNs aren't "supposed to" compare equal even when they are identical. Built-in types such as sets, dicts, lists, and tuples don't follow that rule but most user-defined classes do. |
Yes, you're probably correct that this is related to #104904. @rhettinger, any thoughts? |
If it were up to me, I would leave the code as-is and would add documention, "dataclass instances My rationale is 1) the expected behavior of NaNs is to never compare equal, 2) the typical use case for a NaN is as a placeholder for missing data so there is no basis for saying the values are equal, and 3) optimizing memory use with a singleton NaN ideally shouldn't change what an application does. Consider comparing two student budgets where neither student knows what their tuition bill is going to be:
Those budgets cannot be said to be equal because possibly differing data values are missing. Also the result of |
As said, the 3.13 behavior indeed makes sense. However, it's a breaking chnage that happened without a deprecation period. |
That is true of every bugfix. Eric can decide. |
What bugfix do you mean? This behavior change happened accidentally during an optimization change, didn't it? |
Unless my imagination is lacking, if we were to back out the optimization and make the change in the next release (or in a few releases from now), we couldn't generate a deprecation warning without drastically slowing down the code. The best we could do is document it. I don't know if anyone would read the deprecation documentation and realize this applies to them. I'm still mulling it over. |
I would describe it differently. It was a change in non-tested, non-guaranteed behavior. Effectively, the downstream test suite was relying on an implementation detail that was not well-known, discussed, documented, tested, or intended. Going forward, we can document, test and guarantee a definition of dataclass equality. Unlike what we have now, that would allow downstream users to make accurate predictions of what will happen with exotic objects like FWIW that will make dataclasses better specified than most other tools in Python (for example, we don't promise exactly what
We make changes in implementation details all the time without going through a deprecation period. That can break overspecified tests but is not considered a "breaking change" (like changing a function signature) . IMO nothing good would come from reverting, deprecating, and reimplementing. It would be unnecessarily disruptive and it would deprive two generations of users of the more reasonable behavior that we all seem to prefer. |
Mostly due to lack of time on m part, the new behavior will be in 3.13. If someone wants to propose a documentation change similar to what @rhettinger suggested above, and an improved What's New entry, I would accept those. |
Bug report
Bug description:
Python 3.12.3
Python 3.13.0b2
The new behavior kinda makes sense, but it is a behavior change nevertheless.
Was it intentional or accidental? I cannot find anything relevant in https://docs.python.org/3.13/whatsnew/3.13.html
Possibly related to #104904 but I have not yet bisected this.
This breaks expectations in the testsuite of cattrs: python-attrs/cattrs#547
CPython versions tested on:
3.13
Operating systems tested on:
Linux
The text was updated successfully, but these errors were encountered: