Skip to content

Commit 49ca964

Browse files
committed
[Python] Deprecate TObject __eq__ pythonization
The TObject `__eq__` pythonization calls `TObject::Equals()`, which by default does a pointer comparison. That can be very confusing for Python users.
1 parent 0f34653 commit 49ca964

File tree

2 files changed

+33
-0
lines changed
  • README/ReleaseNotes/v638
  • bindings/pyroot/pythonizations/python/ROOT/_pythonization

2 files changed

+33
-0
lines changed

README/ReleaseNotes/v638/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,14 @@ If you want to keep using `TList*` return values, you can write a small adapter
144144

145145
ROOT dropped support for Python 3.8, meaning ROOT now requires at least Python 3.9.
146146

147+
### Deprecation of the `TObject` equalily pythonization
148+
149+
`TObject.__eq__` is deprecated and will be removed in ROOT 6.40.
150+
151+
It forwards to `TObject::Equals()`, which uses pointer comparison if not overridden in derived classes.
152+
This may be confusing, because people expect value comparisons.
153+
Use Pythons `is` for pointer comparison, or request an implementation of `operator==` on the C++ side if you need value-based equality checks for a given class.
154+
147155
### Deprecate the attribute pythonization of `TDirectory` in favor of item-getting syntax
148156

149157
Since ROOT 6.32, the recommended way to get objects from a `TFile` or any `TDirectory` in general is via `__getitem__`:

bindings/pyroot/pythonizations/python/ROOT/_pythonization/_tobject.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
# Searching
1515

16+
1617
def _contains(self, o):
1718
# Relies on TObject::FindObject
1819
# Parameters:
@@ -22,26 +23,47 @@ def _contains(self, o):
2223
# - True if self contains o
2324
return bool(self.FindObject(o))
2425

26+
2527
# Comparison operators
2628

29+
30+
def _eq(self, o):
31+
import warnings
32+
33+
warnings.warn(
34+
"\nTObject.__eq__ is deprecated and will be removed in ROOT 6.40."
35+
"\n\nIt forwards to TObject::Equals(), which uses pointer comparison if"
36+
" not overridden in derived classes."
37+
"\nThis may be confusing, because people expect value comparisons."
38+
"\nUse Pythons `is` for pointer comparison, or request/implement"
39+
" `operator==` on the C++ side if you need value-based equality checks.",
40+
FutureWarning,
41+
stacklevel=2,
42+
)
43+
return self._cpp_eq(o)
44+
45+
2746
def _lt(self, o):
2847
if isinstance(o, cppyy.gbl.TObject):
2948
return self.Compare(o) == -1
3049
else:
3150
return NotImplemented
3251

52+
3353
def _le(self, o):
3454
if isinstance(o, cppyy.gbl.TObject):
3555
return self.Compare(o) <= 0
3656
else:
3757
return NotImplemented
3858

59+
3960
def _gt(self, o):
4061
if isinstance(o, cppyy.gbl.TObject):
4162
return self.Compare(o) == 1
4263
else:
4364
return NotImplemented
4465

66+
4567
def _ge(self, o):
4668
if isinstance(o, cppyy.gbl.TObject):
4769
return self.Compare(o) >= 0
@@ -57,11 +79,14 @@ def pythonize_tobject():
5779

5880
# Inject comparison operators
5981
AddTObjectEqNePyz(klass)
82+
klass._cpp_eq = klass.__eq__
83+
klass.__eq__ = _eq
6084
klass.__lt__ = _lt
6185
klass.__le__ = _le
6286
klass.__gt__ = _gt
6387
klass.__ge__ = _ge
6488

89+
6590
# Instant pythonization (executed at `import ROOT` time), no need of a
6691
# decorator. This is a core class that is instantiated before cppyy's
6792
# pythonization machinery is in place.

0 commit comments

Comments
 (0)