From 79548a4211f82767a48445ed6b086c5450543b01 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Fri, 8 Nov 2024 14:03:57 +0100 Subject: [PATCH] [PyROOT] Don't add gROOT and other globals manually to PyROOT via C++ This is not necessary if we consider that `gROOT` is actually a preprocessor macro that aliases to `ROOT::GetROOT()`, which we can use directly in Python via cppyy. Same with the `gInterpreter`. --- .../pythonizations/python/ROOT/__init__.py | 5 ++-- .../pythonizations/python/ROOT/_facade.py | 8 +++--- .../pythonizations/src/PyROOTWrapper.cxx | 25 ------------------- 3 files changed, 6 insertions(+), 32 deletions(-) diff --git a/bindings/pyroot/pythonizations/python/ROOT/__init__.py b/bindings/pyroot/pythonizations/python/ROOT/__init__.py index c723ca190f7a8..a7663ae12e01d 100644 --- a/bindings/pyroot/pythonizations/python/ROOT/__init__.py +++ b/bindings/pyroot/pythonizations/python/ROOT/__init__.py @@ -176,6 +176,8 @@ def find_spec(self, fullname: str, path, target=None) -> ModuleSpec: # Register cleanup import atexit +# Private handle to gROOT for later cleanup +_gROOTForCleanup = cppyy.gbl.ROOT.GetROOT() def cleanup(): # If spawned, stop thread which processes ROOT events @@ -185,7 +187,6 @@ def cleanup(): facade.__dict__["app"].process_root_events.join() if "libROOTPythonizations" in sys.modules: - backend = sys.modules["libROOTPythonizations"] from ROOT import PyConfig @@ -193,7 +194,7 @@ def cleanup(): # Hard teardown: run part of the gROOT shutdown sequence. # Running it here ensures that it is done before any ROOT libraries # are off-loaded, with unspecified order of static object destruction. - backend.gROOT.EndOfProcessCleanups() + _gROOTForCleanup.EndOfProcessCleanups() atexit.register(cleanup) diff --git a/bindings/pyroot/pythonizations/python/ROOT/_facade.py b/bindings/pyroot/pythonizations/python/ROOT/_facade.py index 8bb5ff2aa92d9..cb56bab885ac7 100644 --- a/bindings/pyroot/pythonizations/python/ROOT/_facade.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_facade.py @@ -8,8 +8,6 @@ import cppyy.ll -from libROOTPythonizations import gROOT - from ._application import PyROOTApplication from ._numbadeclare import _NumbaDeclareDecorator @@ -36,7 +34,7 @@ class _gROOTWrapper(object): def __init__(self, facade): self.__dict__["_facade"] = facade - self.__dict__["_gROOT"] = gROOT + self.__dict__["_gROOT"] = cppyy.gbl.ROOT.GetROOT() def __getattr__(self, name): if name != "SetBatch" and self._facade.__dict__["gROOT"] != self._gROOT: @@ -158,7 +156,7 @@ def _fallback_getattr(self, name): elif hasattr(cppyy.gbl.ROOT, name): return getattr(cppyy.gbl.ROOT, name) else: - res = gROOT.FindObject(name) + res = self.gROOT.FindObject(name) if res: return res raise AttributeError("Failed to get attribute {} from ROOT".format(name)) @@ -204,7 +202,7 @@ def _register_converters_and_executors(self): def _finalSetup(self): # Prevent this method from being re-entered through the gROOT wrapper - self.__dict__["gROOT"] = gROOT + self.__dict__["gROOT"] = cppyy.gbl.ROOT.GetROOT() # Setup interactive usage from Python self.__dict__["app"] = PyROOTApplication(self.PyConfig, self._is_ipython) diff --git a/bindings/pyroot/pythonizations/src/PyROOTWrapper.cxx b/bindings/pyroot/pythonizations/src/PyROOTWrapper.cxx index 318f7f61a165c..26cd81d9d9ee3 100644 --- a/bindings/pyroot/pythonizations/src/PyROOTWrapper.cxx +++ b/bindings/pyroot/pythonizations/src/PyROOTWrapper.cxx @@ -13,33 +13,13 @@ #include "PyROOTWrapper.h" #include "TMemoryRegulator.h" -// Cppyy -#include "CPyCppyy/API.h" - // ROOT #include "TROOT.h" -#include "TSystem.h" -#include "TClass.h" -#include "TInterpreter.h" -#include "DllImport.h" namespace PyROOT { R__EXTERN PyObject *gRootModule; } -using namespace PyROOT; - -namespace { - -static void AddToGlobalScope(const char *label, TObject *obj, const char *classname) -{ - // Bind the given object with the given class in the global scope with the - // given label for its reference. - PyModule_AddObject(gRootModule, label, CPyCppyy::Instance_FromVoidPtr(obj, classname)); -} - -} // unnamed namespace - PyROOT::RegulatorCleanup &GetRegulatorCleanup() { // The object is thread-local because it can happen that we call into @@ -59,9 +39,4 @@ void PyROOT::Init() // Memory management gROOT->GetListOfCleanups()->Add(&GetRegulatorCleanup()); - - // Bind ROOT globals that will be needed in ROOT.py - AddToGlobalScope("gROOT", gROOT, gROOT->IsA()->GetName()); - AddToGlobalScope("gSystem", gSystem, gSystem->IsA()->GetName()); - AddToGlobalScope("gInterpreter", gInterpreter, gInterpreter->IsA()->GetName()); }