Hi All,
It’s possible this has been asked before, I am not really sure what to search for to look for it. The title of this post is also pretty vague.
Currently running ROOT 6.08.02, Python 3.4.
Ok, so here is the issue.
I have a ROOT class A that has methods that depend on a ROOT enum:
namespace MyNamespace {
enum MyType {
kThis,
kThat
};
struct Base {
Base(MyType thisOrThat);
};
};
LinkDef:
#pragma link C++ enum MyNamespace::MyType;
#pragma link C++ class MyNamespace::Base+;
Now, I have a python class that inherits from this one, and winds up trying to instantiate it with super().init. But, I can reproduce the problem simply by trying to return an instance of the class from a function.
import ROOT
def ThisClass():
return ROOT.MyNamespace.Base(ROOT.MyNamespace.kThis)
Now, the base class runs fine in ROOT. But in python I have the following behavior:
Instantiating ThisClass first does not work
>> import ROOT
>> from myModule import ThisClass
>> myObj = ThisClass()
TypeError: none of the 3 overloaded methods succeeded. Full details:
...
(Copy ctors dont work)
...
MyNamespace::Base::MyNamespace::Base(MyNamespace::MyType thisOrThat) =>
could not convert argument 1 (void/unknown arguments can't be set)
>> ROOT.MyNamespace.Base(ROOT.MyNamespace.kThis)
TypeError: none of the 3 overloaded methods succeeded. Full details:
...
(Copy ctors dont work)
...
MyNamespace::Base::MyNamespace::Base(MyNamespace::MyType thisOrThat) =>
could not convert argument 1 (void/unknown arguments can't be set)
But, if I do it the other way around, it does work:
>> import ROOT
>> from myModule import ThisClass
>> ROOT.MyNamespace.Base(ROOT.MyNamespace.kThis)
>> myObj = ThisClass()
In fact, simply executing
>> exec('ROOT.MyNamespace.Base')
before calling ThisClass fixes the problem. Calling
>> exec('ROOT.MyNamespace.kThis')
does NOT fix the problem. This seems to be a problem with the class, not the enums.
This was NOT an issue in ROOT5. So, it seems to me that this has to do with how python is looking up the class dictionary and deciding how to pass arguments to underlying ROOT class. Unless it is being instantiated in the global frame python is not properly figuring out the definitions?
On a different topic. Is there a way I can load the enums into the module frame without knowing their names? I am currently using
for k in vars(ROOT.MyNamespace):
if k.startswith('k'):
globals()[k]=ROOT.MyNamespace.__getattribute__(ROOT.MyNamespace,k)
But this seems pretty hackish. ROOT.MyNamespace.dict[‘kThis’] seems to point to a ROOT.PropertyProxy. Hence I have to use the getattribute method. Which is not a static class? Hence I need to pass the namespace in place of self? I don’t know, it seems like a hack to me. Should I open this one up into a different thread?
Anyway, hopefully I described the issue clearly. Thanks in advance.
Cheers,
–Jon