PyROOT dict setdefault

The following RuntimeWarning defeats the usefulness of dict.setdefault() with some ROOT objects. It seems to only happen when the name of the object is the same. Is it expected?

Python 3.9.6 (default, Jul 28 2021, 18:12:51) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ROOT
>>> d = {'key1': ROOT.TH1D('name', 'name', 5, 0, 10)}
>>> d
{'key1': <cppyy.gbl.TH1D object at 0x5b06e40>}
>>> d.setdefault('key2', ROOT.TH1D('name2', 'name2', 5, 0, 10))
<cppyy.gbl.TH1D object at 0x5b0caf0>
>>> d
{'key1': <cppyy.gbl.TH1D object at 0x5b06e40>, 'key2': <cppyy.gbl.TH1D object at 0x5b0caf0>}
>>> d.setdefault('key1', ROOT.TH1D('name3', 'name3', 5, 0, 10))
<cppyy.gbl.TH1D object at 0x5b06e40>
>>> d
{'key1': <cppyy.gbl.TH1D object at 0x5b06e40>, 'key2': <cppyy.gbl.TH1D object at 0x5b0caf0>}
>>> d['key1'].GetName()
'name'
>>> d.setdefault('key1', ROOT.TH1D('name', 'name', 5, 0, 10))
TROOT::Append:0: RuntimeWarning: Replacing existing TH1: name (Potential memory leak).
<cppyy.gbl.TH1D object at 0x5b06e40>

May be @etejedor has an idea about that.

Hello,

Yes, the warning is expected, since you are creating twice a TH1D object with the same name ( ROOT.TH1D('name', 'name', 5, 0, 10)). ROOT realizes that since it registered the histogram the first time you created it and throws the warning.

The whole point of setdefault is checking whether the element with the given key already exists, and ignore the passed value (ROOT.TH1D('name', 'name', 5, 0, 10) above) if it does. I do not understand how TH1D(...) is called, given that key1 already exists, but I suppose this is a feature of python and not of ROOT.
Still, it seems setdefault cannot be reliably used with ROOT, and one has to resort instead to the if key not in dict pattern.

Hello,

It is really nothing related with ROOT, it is how method calls work in Python.

d.setdefault('key1', ROOT.TH1D('name', 'name', 5, 0, 10)) is a method call with two arguments. The second argument needs to be constructed before the call is made. setdefault might ignore the second argument once inside the call, but it has already been constructed. That’s why you see the warning.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.