Subclassing ROOT classes

Is is possible to create a real subclass in Python?

I load my class from a compiled library; I use a group-specific ROOT framework and want to subclass one of my own classes, called FrFW.FastAnalysis. A short code example is below. The problem is of course, that the subclass is still reported as “
<ROOT.FrFW::FastAnalysis object (”") at 0x899a0a8>" (the print self statement), and when am.Execute() goes to its analyses, it doesn’t call the methods defined in python but the ones in the FastAnalysis base class. So none of the Init*/Execute/Finalize methods in the python script get called

from ROOT import *
gSystem.Load("libanalysis")

class Cutflow (FrFW.FastAnalysis):
    #FastAnalysis(TXAnalysisManager* am, TString name, TString opt) : TXAnalysis(am, name, opt) {};
    def __init__(self, amanager, name, opt):
        super(Cutflow, self).__init__(amanager, name, opt)
        print self

    def InitHistograms(self):
        print "init histo"
    def Initialize(self):
        print "Init"
    def Execute(self):
        print "exe"
    def Finalize(self):
        print "final"

class Manager (object):
    def __init__(self):
        am = FrFW.TXAnalysisManager("am.root")
        ana = Cutflow(am, "Cutflow", "cbnt=CBNTMERGE_tau.cfg");
        TPython.Prompt()
        ana.AddFileSource("~/recon/task/105012.e344_a68_tid039339_looselep_or_tighttau/105012.e344_a68_tid039339_looselep_or_tighttau-events1.0.root")
        ana.SetActive(True)
        am.AddAnalysis("Cutflow", ana)
        am.Execute()

if __name__ == "__main__":
    Manager()

Hi,

subclassing only works if a class is set in between that provides a new vtable that forwards the calls to python. I’ve worked on a prototype a while back based on using a metaclass that generates the “in between” code, but then decided with Axel we would take another route, which we never did in the end …

The subclass in between would have to look something like:[code]include "MyBase.h"
struct _object;
typedef _object PyObject;
extern “C” PyObject* PyObject_CallMethod( PyObject *o, char *method, char *format, … );

class MyDerived_PyProxy : public MyBase {
public:
MyDerived_PyProxy( PyObject* self ) : m_self( self ) {}

void CallMe() { PyObject_CallMethod( m_self, (char*)“CallMe”, (char*)"" ); }

private:
PyObject* m_self;
};[/code]
with ‘CallMe’ being the overridden method in MyBase (where it is virtual). The deriving from the proxy (inserted by the meta class) would do the trick.

Cheers,
Wim