Skip to content

Commit 19fa2dc

Browse files
committed
[Python] Deprecate C++ nullptr comparison with None
This comparison might give confusing results because they are contradicting with None being a singleton type, so it's better to deprecate this type of comparison. Closes #20283.
1 parent 34271b3 commit 19fa2dc

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

README/ReleaseNotes/v638/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ The following people have contributed to this new version:
4949
Relative RPATHs to the main ROOT libraries are unconditionally appended to all ROOT executables and libraries if the operating system supports it.
5050
If you want a ROOT build without RPATHs, use the canonical CMake variable `CMAKE_SKIP_INSTALL_RPATH=TRUE`.
5151
* The `TH1K` class is deprecated and will be removed in 6.40. It did not implement the `TH1` interface consistently, and limited the usability of the k-neighbors method it implemented by closely coupling the algorithm with the histogram class. Please use the new `TMath::KNNDensity` function that implements the same mathematical logic.
52+
* Comparing C++ `nullptr` objects with `None` in Python now results in a `FutureWarning`, and will result in a `TypeError` starting from ROOT 6.40. This is to prevent confusing results where `x == None` and `x is None` are not identical. Use truth-value checks like `if not x` or `x is None` instead.
5253

5354
## Build System
5455
* Improve building ROOT when ROOT is already installed in the system. ROOT now correctly handles system-include folders that both contain a package that ROOT depends on and a ROOT installation. Dependent packages are included with `-isystem` instead of `-I`, so installed ROOT headers will not interfere with a ROOT build. See [#8708](https://github.com/root-project/root/issues/8708) for details.

bindings/pyroot/cppyy/CPyCppyy/src/CPPInstance.cxx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,19 @@ static PyObject* op_richcompare(CPPInstance* self, PyObject* other, int op)
573573
if (op == Py_EQ || op == Py_NE) {
574574
// special case for None to compare True to a null-pointer
575575
if ((PyObject*)other == Py_None && !self->fObject) {
576+
const char *msg =
577+
"\nComparison of C++ nullptr objects with `None` is deprecated and will raise a TypeError starting from ROOT 6.40."
578+
"\n\nThis currently treats `None` as equivalent to a null C++ pointer, which may lead to confusing results."
579+
"\nFor example, `x == None` may return True even though `x is None` is False."
580+
"\n\nTo test whether a C++ object is null or not, check its truth value instead:"
581+
"\n if not x: ..."
582+
"\nor use `x is None` to explicitly check for Python None."
583+
"\n";
584+
585+
// Equivalent to: warnings.warn(msg, FutureWarning, stacklevel=0)
586+
if (PyErr_WarnEx(PyExc_FutureWarning, msg, 0) < 0) {
587+
return NULL; // Propagate the error if warning turned into an exception
588+
}
576589
if (op == Py_EQ) { Py_RETURN_TRUE; }
577590
Py_RETURN_FALSE;
578591
}

0 commit comments

Comments
 (0)