ATLAS Offline Software
Static Public Member Functions | List of all members
RootUtils::PyROOTTypePatch Class Reference

Work around pyroot problem with __pair_base. More...

#include <PyROOTTypePatch.h>

Collaboration diagram for RootUtils::PyROOTTypePatch:

Static Public Member Functions

static void initialize ()
 Initialize the workaround. More...
 
static void scan_one (TClass *cls)
 Scan a single class. More...
 

Detailed Description

Work around pyroot problem with __pair_base.

In gcc8, std::pair derives from the (empty) base class std::__pair_base. When ROOT makes dictionaries, it likes to strip std:: qualifiers. When it then tries to look up cling information for a TClass, if the lookup fails, it tries again with the std:: reinserted for all STL classes (with TClassEdit::InsertStd()). However, that doesn't work for __pair_base, because it's not a class that ROOT knows about. The upshot is that we see errors like:

Error in <TClass::LoadClassInfo>: no interpreter information for class __pair_base<unsigned int,string> is available even though it has a TClass initialization routine.

We work around this by hooking into ROOT's TClass creation. If we see a std::pair class, we erase the base class information from its TClass.

Definition at line 42 of file PyROOTTypePatch.h.

Member Function Documentation

◆ initialize()

void RootUtils::PyROOTTypePatch::initialize ( )
static

Initialize the workaround.

Scan all known classes, and also hook into class creation so that we'll scan all future classes.

Definition at line 134 of file PyROOTTypePatch.cxx.

135 {
136  // Return if we've already initialized.
137  static bool initialized = false;
138  if (initialized) return;
139  initialized = true;
140 
141  // Scan all classes.
142  scan_for_pair();
143 
144  // Register ourselves as a hook,
145  // to be called in the future on class creation.
146  TypePatchInitBehavior::oldBehaviorPtr = &TypePatchInitBehavior::oldBehavior;
147  TInitBehavior* ib =
148  const_cast<TInitBehavior*>(DefineBehavior(0,0));
149  assert (sizeof(TDefaultInitBehavior) == sizeof (TypePatchInitBehavior));
150  memcpy ((char*)&TypePatchInitBehavior::oldBehavior, (char*)ib,
151  sizeof(TDefaultInitBehavior));
152  static TypePatchInitBehavior sfaib;
153  memcpy ((char*)ib, (char*)&sfaib, sizeof(TDefaultInitBehavior));
154 
155  // Make sure the TClass's for these are built.
156  // Otherwise, CreateClass can get called while global dtors are running.
157  gROOT->GetClass("TObjString");
158  gROOT->GetClass("TTreeCache");
159 }

◆ scan_one()

void RootUtils::PyROOTTypePatch::scan_one ( TClass *  cls)
static

Scan a single class.

Parameters
clsThe class to scan.

Definition at line 166 of file PyROOTTypePatch.cxx.

167 {
168  if (name_is_pair (cls->GetName())) {
169  cls->GetListOfBases()->Clear();
170  }
171 }

The documentation for this class was generated from the following files:
PlotCalibFromCool.ib
ib
Definition: PlotCalibFromCool.py:419
CaloClusterListBadChannel.cls
cls
Definition: CaloClusterListBadChannel.py:8