[CPyCppyy] Remove pointer-based fallback in CPPInstance equality check - #21572
[CPyCppyy] Remove pointer-based fallback in CPPInstance equality check#21572guitargeek wants to merge 1 commit into
Conversation
vepadulano
left a comment
There was a problem hiding this comment.
Not against the change per se, but this needs a very explicit mention in the release notes as well as a paragraph or two in the Pythonization section of the docs.
| "\n\nThe Python proxy no longer falls back to comparing by type and held C++ pointer " | ||
| "address, because that can be misleading: using `%s` may look like a value comparison " | ||
| "even though no corresponding C++ operator is available." |
There was a problem hiding this comment.
This wording will age very quickly, I would rephrase in such a way to just indicate the reason for the failure and provide the user with suggestions on what to do (e.g. implent a custom __eq__ for their own classes where it makes sense).
|
Thanks for the early review! Good to know that you are not opposed to this change. But before writing the release notes, I still have some test failures to figure out, so I'll mark this PR as draft for now |
Test Results 23 files 23 suites 5d 3h 39m 15s ⏱️ For more details on these failures, see this check. Results for commit 8a75fcb. ♻️ This comment has been updated with latest results. |
45d2c6c to
037ae4a
Compare
a20c50d to
64295ff
Compare
The Python proxy for C++ objects previously implemented a fallback equality comparison based on proxy type and the held C++ pointer address when no C++ `operator==` / `operator!=` was available. This behavior was misleading, because it made expressions like `a == b` appear to perform a value comparison even though no corresponding C++ operator was defined. This patch removes the implicit pointer-based fallback and instead raises a TypeError when equality is requested between two CPPInstance proxies for which no C++ equality operator can be resolved. This avoids silently changing semantics and makes unsupported comparisons explicit. The error message states why the comparison is not supported and what to do instead: define a C++ `operator==` for the operands, implement `__eq__` and `__ne__` from Python, or compare the addresses of the wrapped C++ objects explicitly with `cppyy.addressof()`. The only case where the pointer-based fallback is kept is for proxies of the exact same type when at least one wraps a `nullptr`: in this case, comparison continues to be performed on the pointer value, because comparing by value would not be possible. This preserves existing cppyy behavior in a case that is not semantically ambiguous. Although C++ would also allow comparisons between nullptr pointers of types related by inheritance, broadening the rule would silently change previous cppyy behavior, where such comparisons returned `False`. To summarize: this change prevents ambiguous equality semantics while avoiding silent behavior changes for existing code by raising a type error in cases that are ambiguous or where previous behavior was different from C++ semantics. Since this is a change in behavior that user code can rely on, it is announced in the ROOT 6.42 release notes, and the new semantics are explained in the "Equality comparisons" section of the pythonizations documentation. Closes root-project#21347.
64295ff to
8a75fcb
Compare
The Python proxy for C++ objects previously implemented a fallback equality comparison based on proxy type and the held C++ pointer address when no C++
operator==/operator!=was available. This behavior was misleading, because it made expressions likea == bappear to perform a value comparison even though no corresponding C++ operator was defined.This patch removes the implicit pointer-based fallback and instead raises a TypeError when equality is requested between two CPPInstance proxies for which no C++ equality operator can be resolved. This avoids silently changing semantics and makes unsupported comparisons explicit.
The only case where the pointer-based fallback is kept is for proxies of the exact same type when at least one wraps a
nullptr: in this case, comparison continues to be performed on the pointer value, because comparing by value would not be possible. This preserves existing cppyy behavior in a case that is not semantically ambiguous. Although C++ would also allow comparisons between nullptr pointers of types related by inheritance, broadening the rule would silently change previous cppyy behavior, where such comparisons returnedFalse.To summarize: this change prevents ambiguous equality semantics while avoiding silent behavior changes for existing code by raising a type error in cases that are ambiguous or where previous behavior was different from C++ semantics.
Closes #21347.