""" PyCintex compatibility module. This module allows transferring away from PyCintex from ROOT v5 to v6. It provides both the original PyCintex.py (most code here is copied over from PyCintex.py) as well as the newer cppyy (from PyPy) APIs. In ROOT6, these codes are consolidated. """ import sys, string ### helper to get the version number from root-config def get_version(): try: import commands stat, output = commands.getstatusoutput("root-config --version") if stat == 0: return output except Exception: pass # semi-sensible default in case of failure ... return "5.34/XY" ### PyPy has 'cppyy' builtin (if enabled, that is) if 'cppyy' in sys.builtin_module_names: _builtin_cppyy = True import imp sys.modules[ __name__ ] = \ imp.load_module( 'cppyy', *(None, 'cppyy', ('', '', imp.C_BUILTIN) ) ) del imp _thismodule = sys.modules[ __name__ ] _backend = _thismodule.gbl # custom behavior that is not yet part of PyPy's cppyy def _MakeRootClass( self, name ): return getattr( self, name ) type(_backend).MakeRootClass = _MakeRootClass def _LookupRootEntity( self, name ): return getattr( self, name ) type(_backend).LookupRootEntity = _LookupRootEntity class _Double(float): pass type(_backend).Double = _Double def _AddressOf( self, obj ): import array return array.array('L', [_thismodule.addressof( obj )] ) type(_backend).AddressOf = _AddressOf del _AddressOf, _Double, _LookupRootEntity, _MakeRootClass else: _builtin_cppyy = False # load PyROOT C++ extension module, special case for linux and Sun needsGlobal = ( 0 <= string.find( sys.platform, 'linux' ) ) or\ ( 0 <= string.find( sys.platform, 'sunos' ) ) if needsGlobal: # change dl flags to load dictionaries from pre-linked .so's dlflags = sys.getdlopenflags() sys.setdlopenflags( 0x100 | 0x2 ) # RTLD_GLOBAL | RTLD_NOW import libPyROOT as _backend # reset dl flags if needed if needsGlobal: sys.setdlopenflags( dlflags ) del needsGlobal # PyCintex tests rely on this, but they should not: sys.modules[ __name__ ].libPyROOT = _backend if not _builtin_cppyy: _backend.SetMemoryPolicy( _backend.kMemoryStrict ) _backend.MakeRootClass( 'PyROOT::TPyROOTApplication' ).InitCINTMessageCallback() #--- Enable Autoloading ignoring possible error for the time being try: _backend.gInterpreter.EnableAutoLoading() except: pass ### template support ------------------------------------------------------------ if not _builtin_cppyy: class Template: def __init__( self, name ): self.__name__ = name def __call__( self, *args ): newargs = [ self.__name__[ 0 <= self.__name__.find( 'std::' ) and 5 or 0:] ] for arg in args: if type(arg) == str: arg = ','.join( map( lambda x: x.strip(), arg.split(',') ) ) newargs.append( arg ) result = _backend.MakeRootTemplateClass( *newargs ) # special case pythonization (builtin_map is not available from the C-API) if hasattr( result, 'push_back' ): def iadd( self, ll ): [ self.push_back(x) for x in ll ] return self result.__iadd__ = iadd return result _backend.Template = Template #--- LoadDictionary function and aliases ----------------------------- def loadDictionary(name) : # prepend "lib" if sys.platform != 'win32' and name[:3] != 'lib': name = 'lib' + name if not _builtin_cppyy: sc = _backend.gSystem.Load(name) if sc == -1 : raise RuntimeError("Error Loading dictionary") else: if sys.platform != 'win32' and name[-3:] != '.so': name = name + '.so' elif name[-4:] != '.dll': name = name + '.dll' _thismodule.load_reflection_info(name) loadDict = loadDictionary #--- Load Cintex module and enable conversions Reflex->CINT----------- # TSystem::Load() already knows that cintex depends on reflex. # _backend.gSystem.Load('libReflex') loadDictionary( 'libCintex' ) Cintex = _backend.MakeRootClass( 'Cintex' ) Cintex.SetDebug(0) Cintex.Enable() #--- Other functions needed ------------------------------------------- if not _builtin_cppyy: class _stdmeta( type ): def __getattr__( cls, attr ): # for non-templated classes in std klass = _backend.MakeRootClass( attr, cls ) setattr( cls, attr, klass ) return klass class _global_cpp: class std( object ): __metaclass__ = _stdmeta stlclasses = ( 'complex', 'pair', \ 'deque', 'list', 'queue', 'stack', 'vector', 'map', 'multimap', 'set', 'multiset' ) for name in stlclasses: locals()[ name ] = Template( 'std::%s' % name ) _backend.gROOT.ProcessLine( "#include " ) string = _backend.MakeRootClass( 'string' ) _backend.SetRootLazyLookup( _global_cpp.__dict__ ) else: _global_cpp = _backend def Namespace( name ) : if name == '' : return _global_cpp else : return _backend.LookupRootEntity( name ) makeNamespace = Namespace def makeClass( name ) : return _backend.MakeRootClass( name ) def addressOf( obj ) : return _backend.AddressOf( obj )[0] def getAllClasses() : TClassTable = makeClass( 'TClassTable' ) TClassTable.Init() classes = [] while True : c = TClassTable.Next() if c : classes.append( c ) else : break return classes #--- Global namespace and global objects ------------------------------- gbl = _global_cpp NULL = 0 # _backend.GetRootGlobal returns a descriptor, which needs a class class double(float): pass class short(int): pass class long_int(int): pass class unsigned_short(int): pass class unsigned_int(int): pass class unsigned_long(long): pass #--- Copy over locally defined names ------------------------------------ if _builtin_cppyy: for name in dir(): if name[0] != '_': setattr( _thismodule, name, eval(name) ) #--- For test purposes -------------------------------------------------- if __name__ == '__main__' : loadDict( 'test_CintexDict' )