diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index e370865c2c2c4..c6c76642fa61c 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -6,7 +6,6 @@ if(pyroot) add_subdirectory(pyroot) - add_subdirectory(jupyroot) if(dataframe) message(STATUS "Distributed RDataFrame enabled") diff --git a/bindings/jupyroot/CMakeLists.txt b/bindings/jupyroot/CMakeLists.txt deleted file mode 100644 index 554dd798f7307..0000000000000 --- a/bindings/jupyroot/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# For the JupyROOT Python package -add_subdirectory(python) diff --git a/bindings/jupyroot/python/CMakeLists.txt b/bindings/jupyroot/python/CMakeLists.txt deleted file mode 100644 index df031cfac73b0..0000000000000 --- a/bindings/jupyroot/python/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. -# All rights reserved. -# -# For the licensing terms see $ROOTSYS/LICENSE. -# For the list of contributors see $ROOTSYS/README/CREDITS. - -########################################################### -# CMakeLists.txt file for building JupyROOT -########################################################### - -ROOT_PYTHON_PACKAGE(JupyROOT - SOURCES - JupyROOT/__init__.py - JupyROOT/helpers/__init__.py - JupyROOT/helpers/cppcompleter.py - JupyROOT/helpers/handlers.py - JupyROOT/helpers/utils.py - JupyROOT/html/__init__.py - JupyROOT/html/cpphighlighter.py - JupyROOT/kernel/__init__.py - JupyROOT/kernel/rootkernel.py - JupyROOT/kernel/utils.py - JupyROOT/kernel/magics/__init__.py - JupyROOT/kernel/magics/cppmagic.py - JupyROOT/kernel/magics/jsrootmagic.py - JupyROOT/magics/__init__.py - JupyROOT/magics/cppmagic.py - JupyROOT/magics/jsrootmagic.py -) diff --git a/bindings/pyroot/pythonizations/python/CMakeLists.txt b/bindings/pyroot/pythonizations/python/CMakeLists.txt index 4c96c7556c7cf..09f8e81eacdc5 100644 --- a/bindings/pyroot/pythonizations/python/CMakeLists.txt +++ b/bindings/pyroot/pythonizations/python/CMakeLists.txt @@ -76,6 +76,22 @@ set(py_sources ROOT/_asan.py ROOT/_facade.py ROOT/__init__.py + ROOT/_jupyroot/__init__.py + ROOT/_jupyroot/helpers/__init__.py + ROOT/_jupyroot/helpers/cppcompleter.py + ROOT/_jupyroot/helpers/handlers.py + ROOT/_jupyroot/helpers/utils.py + ROOT/_jupyroot/html/__init__.py + ROOT/_jupyroot/html/cpphighlighter.py + ROOT/_jupyroot/kernel/__init__.py + ROOT/_jupyroot/kernel/rootkernel.py + ROOT/_jupyroot/kernel/utils.py + ROOT/_jupyroot/kernel/magics/__init__.py + ROOT/_jupyroot/kernel/magics/cppmagic.py + ROOT/_jupyroot/kernel/magics/jsrootmagic.py + ROOT/_jupyroot/magics/__init__.py + ROOT/_jupyroot/magics/cppmagic.py + ROOT/_jupyroot/magics/jsrootmagic.py ROOT/_numbadeclare.py ROOT/_pythonization/__init__.py ROOT/_pythonization/_cppinstance.py diff --git a/bindings/pyroot/pythonizations/python/ROOT/__init__.py b/bindings/pyroot/pythonizations/python/ROOT/__init__.py index 141a43b969777..0a5ae7bda7736 100644 --- a/bindings/pyroot/pythonizations/python/ROOT/__init__.py +++ b/bindings/pyroot/pythonizations/python/ROOT/__init__.py @@ -8,17 +8,14 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. # ################################################################################ +from __future__ import annotations + import builtins import os import sys import types from importlib.abc import Loader, MetaPathFinder from importlib.machinery import ModuleSpec -from typing import Optional, Union - -import cppyy -import cppyy.ll -import cppyy.types from . import _asan # noqa: F401 # imported for side effects for setup specific to AddressSanitizer environments from ._facade import ROOTFacade @@ -100,7 +97,7 @@ def _can_be_module(obj) -> bool: return False -def _lookup_root_module(fullname: str) -> Optional[Union[types.ModuleType, cppyy.types.Scope]]: +def _lookup_root_module(fullname: str) -> Optional[Union[types.ModuleType, cppyy.types.Scope]]: # noqa: F821 """ Recursively looks up attributes of the ROOT facade, using a full module name, and return it if it can be used as a ROOT submodule. This is the case @@ -168,6 +165,6 @@ def find_spec(self, fullname: str, path, target=None) -> ModuleSpec: ip = get_ipython() if hasattr(ip, "kernel"): - import JupyROOT # noqa: F401 # imported the side effect of setting up JupyROOT + from . import _jupyroot # noqa: F401 # imported the side effect of setting up JupyROOT # from . import JsMVA diff --git a/bindings/pyroot/pythonizations/python/ROOT/_facade.py b/bindings/pyroot/pythonizations/python/ROOT/_facade.py index 4695e2b74a972..c3e9f12e62e2d 100644 --- a/bindings/pyroot/pythonizations/python/ROOT/_facade.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_facade.py @@ -25,7 +25,14 @@ class _gROOTWrapper(object): def __init__(self, facade): self.__dict__["_facade"] = facade - self.__dict__["_gROOT"] = facade._cppyy.gbl.ROOT.GetROOT() + + @property + def _gROOT(self): + gROOT = self.__dict__.get("_gROOT") + if gROOT is None: + gROOT = self._facade._cppyy.gbl.ROOT.GetROOT() + self.__dict__["_gROOT"] = gROOT + return gROOT def __getattr__(self, name): if name != "SetBatch" and self._facade.__dict__["gROOT"] != self._gROOT: @@ -52,8 +59,6 @@ class ROOTFacade(types.ModuleType): def __init__(self, module, is_ipython): types.ModuleType.__init__(self, module.__name__) - self._cppyy = module.cppyy - self.__all__ = module.__all__ self.__name__ = module.__name__ self.__file__ = module.__file__ @@ -66,23 +71,6 @@ def __init__(self, module, is_ipython): # Inject gROOT global self.gROOT = _gROOTWrapper(self) - # Expose some functionality from CPyCppyy extension module - self._cppyy_exports = [ - "nullptr", - "bind_object", - "as_cobject", - "addressof", - "SetHeuristicMemoryPolicy", - "SetImplicitSmartPointerConversion", - "SetOwnership", - ] - for name in self._cppyy_exports: - setattr(self, name, getattr(self._cppyy._backend, name)) - # For backwards compatibility - self.MakeNullPointer = partial(self.bind_object, 0) - self.BindObject = self.bind_object - self.AsCObject = self.as_cobject - # Initialize configuration self.PyConfig = PyROOTConfiguration() @@ -157,9 +145,42 @@ def _register_converters_and_executors(self): CPyCppyyRegisterExecutorAlias(name, target) def _finalSetup(self): + """ + Perform the final ROOT initialization. + + This method is intentionally deferred and is the *only* place where + cppyy is imported and the C++ runtime is initialized. Delaying this + step avoids importing the heavy-weight cppyy machinery unless it is + actually required (for example, when accessing C++ ROOT symbols), + allowing Python-only ROOT submodules to be imported with minimal + overhead. + """ + import cppyy + import cppyy.ll + import cppyy.types + from ._application import PyROOTApplication from ._pythonization import _register_pythonizations, pythonization + self.__dict__["_cppyy"] = cppyy + + # Expose some functionality from CPyCppyy extension module + cppyy_exports = [ + "nullptr", + "bind_object", + "as_cobject", + "addressof", + "SetHeuristicMemoryPolicy", + "SetImplicitSmartPointerConversion", + "SetOwnership", + ] + for name in cppyy_exports: + self.__dict__[name] = getattr(cppyy._backend, name) + # For backwards compatibility + self.__dict__["MakeNullPointer"] = partial(cppyy._backend.bind_object, 0) + self.__dict__["BindObject"] = cppyy._backend.bind_object + self.__dict__["AsCObject"] = cppyy._backend.as_cobject + # Trigger the addition of the pythonizations _register_pythonizations() diff --git a/bindings/jupyroot/README.md b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/README.md similarity index 100% rename from bindings/jupyroot/README.md rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/README.md diff --git a/bindings/jupyroot/python/JupyROOT/__init__.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/__init__.py similarity index 69% rename from bindings/jupyroot/python/JupyROOT/__init__.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/__init__.py index 30a287a4b862e..f68d9fe8ecafc 100644 --- a/bindings/jupyroot/python/JupyROOT/__init__.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/__init__.py @@ -1,7 +1,7 @@ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Author: Danilo Piparo CERN # Author: Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -12,19 +12,22 @@ ################################################################################ import sys -from JupyROOT.helpers import utils -if not 'win32' in sys.platform: - from JupyROOT.helpers import cppcompleter + +from ROOT._jupyroot.helpers import utils + +if "win32" not in sys.platform: + from ROOT._jupyroot.helpers import cppcompleter # Check if we are in the IPython shell try: import builtins except ImportError: - import __builtin__ as builtins # Py2 -_is_ipython = hasattr(builtins, '__IPYTHON__') + import __builtin__ as builtins # Py2 +_is_ipython = hasattr(builtins, "__IPYTHON__") if _is_ipython: - if not 'win32' in sys.platform: + if "win32" not in sys.platform: from IPython import get_ipython + cppcompleter.load_ipython_extension(get_ipython()) utils.iPythonize() diff --git a/bindings/jupyroot/python/JupyROOT/html/__init__.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/__init__.py similarity index 81% rename from bindings/jupyroot/python/JupyROOT/html/__init__.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/__init__.py index 6e2e520ef9219..664a53fbeafbc 100644 --- a/bindings/jupyroot/python/JupyROOT/html/__init__.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/__init__.py @@ -1,7 +1,7 @@ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Author: Danilo Piparo CERN # Author: Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # diff --git a/bindings/jupyroot/python/JupyROOT/helpers/cppcompleter.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/cppcompleter.py similarity index 85% rename from bindings/jupyroot/python/JupyROOT/helpers/cppcompleter.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/cppcompleter.py index ef0e88d0529d4..bc311f630f634 100644 --- a/bindings/jupyroot/python/JupyROOT/helpers/cppcompleter.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/cppcompleter.py @@ -1,9 +1,9 @@ # -*- coding:utf-8 -*- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Author: Danilo Piparo CERN # Author: Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -13,9 +13,10 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. # ################################################################################ -from JupyROOT.helpers import utils import platform + import ROOT +from ROOT._jupyroot.helpers import utils # Jit a wrapper for the ttabcom _TTabComHookCode = """ @@ -46,8 +47,9 @@ } """ + class CppCompleter(object): - ''' + """ Completer which interfaces to the TTabCom of ROOT. It is activated (deactivated) upon the load(unload) of the load of the extension. @@ -95,7 +97,7 @@ class CppCompleter(object): >>> comp.deactivate() >>> for suggestion in comp._completeImpl("TG"): ... print(suggestion) - ''' + """ def __init__(self): self.hook = None @@ -106,7 +108,7 @@ def __init__(self): def activate(self): self.active = True if self.firstActivation: - if platform.system() == 'Windows': + if platform.system() == "Windows": dlOpenRint = 'gInterpreter->LoadFile("libRint.dll");' else: utils.declareCppCode('#include "dlfcn.h"') @@ -119,35 +121,36 @@ def activate(self): def deactivate(self): self.active = False - def _getSuggestions(self,line): + def _getSuggestions(self, line): if self.active: return self.hook(line) return [] - def _getLastAccessorPos(self,line): + def _getLastAccessorPos(self, line): accessorPos = -1 for accessor in self.accessors: tmpAccessorPos = line.rfind(accessor) if accessorPos < tmpAccessorPos: - accessorPos = tmpAccessorPos+len(accessor) + accessorPos = tmpAccessorPos + len(accessor) return accessorPos def _completeImpl(self, line): - line=line.split()[-1] - suggestions = [ str(s) for s in self._getSuggestions(line) ] + line = line.split()[-1] + suggestions = [str(s) for s in self._getSuggestions(line)] suggestions = filter(lambda s: len(s.strip()) != 0, suggestions) suggestions = sorted(suggestions) - if not suggestions: return [] + if not suggestions: + return [] # Remove combinations of opening and closing brackets and just opening # brackets at the end of a line. Jupyter seems to expect functions # without these brackets to work properly. The brackets of'operator()' # must not be removed - suggestions = [sugg[:-2] if sugg[-2:] == '()' and sugg != 'operator()' else sugg for sugg in suggestions] - suggestions = [sugg[:-1] if sugg[-1:] == '(' else sugg for sugg in suggestions] + suggestions = [sugg[:-2] if sugg[-2:] == "()" and sugg != "operator()" else sugg for sugg in suggestions] + suggestions = [sugg[:-1] if sugg[-1:] == "(" else sugg for sugg in suggestions] # If a function signature is encountered, add an empty item to the # suggestions. Try to guess a function signature by an opening bracket # ignoring 'operator()'. - are_signatures = "(" in "".join(filter(lambda s: s != 'operator()', suggestions)) + are_signatures = "(" in "".join(filter(lambda s: s != "operator()", suggestions)) accessorPos = self._getLastAccessorPos(line) if are_signatures: suggestions = [" "] + suggestions @@ -156,26 +159,27 @@ def _completeImpl(self, line): # suggestion already contains the variable name, this can happen if # e.g. there is only one valid completion if len(suggestions) > 1 or line[:accessorPos] != suggestions[0][:accessorPos]: - suggestions = [line[:accessorPos]+sugg for sugg in suggestions] + suggestions = [line[:accessorPos] + sugg for sugg in suggestions] return suggestions - def complete(self, ip, event) : - ''' + def complete(self, ip, event): + """ Autocomplete interfacing to TTabCom. If an accessor of a scope is present in the line, the suggestions are prepended with the line. That's how completers work. For example: myGraph.Set will return "myGraph.Set+suggestion in the list of suggestions. - ''' + """ return self._completeImpl(event.line) _cppCompleter = CppCompleter() + def load_ipython_extension(ipython): _cppCompleter.activate() - ipython.set_hook('complete_command', _cppCompleter.complete, re_key=r"[(.*)[\.,::,\->](.*)]|(.*)") + ipython.set_hook("complete_command", _cppCompleter.complete, re_key=r"[(.*)[\.,::,\->](.*)]|(.*)") + def unload_ipython_extension(ipython): _cppCompleter.deactivate() - diff --git a/bindings/jupyroot/python/JupyROOT/helpers/handlers.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/handlers.py similarity index 78% rename from bindings/jupyroot/python/JupyROOT/helpers/handlers.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/handlers.py index 433126fea3d95..1401695ca8c23 100644 --- a/bindings/jupyroot/python/JupyROOT/helpers/handlers.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/handlers.py @@ -1,8 +1,8 @@ # -*- coding:utf-8 -*- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Authors: Danilo Piparo # Omar Zapata http://oproject.org -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -12,18 +12,16 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. # ################################################################################ +import queue from threading import Thread from time import sleep as timeSleep -from sys import platform -from os import path -import queue -from JupyROOT import helpers import ROOT.libROOTPythonizations as _lib +from ROOT._jupyroot import helpers class IOHandler(object): - r'''Class used to capture output from C/C++ libraries. + r"""Class used to capture output from C/C++ libraries. >>> import sys >>> h = IOHandler() >>> h.GetStdout() @@ -33,7 +31,8 @@ class IOHandler(object): >>> h.GetStreamsDicts() (None, None) >>> del h - ''' + """ + def __init__(self): _lib.JupyROOTExecutorHandler_Ctor() @@ -53,17 +52,18 @@ def EndCapture(self): _lib.JupyROOTExecutorHandler_EndCapture() def GetStdout(self): - return _lib.JupyROOTExecutorHandler_GetStdout() + return _lib.JupyROOTExecutorHandler_GetStdout() def GetStderr(self): - return _lib.JupyROOTExecutorHandler_GetStderr() + return _lib.JupyROOTExecutorHandler_GetStderr() def GetStreamsDicts(self): - out = self.GetStdout() - err = self.GetStderr() - outDict = {'name': 'stdout', 'text': out} if out != "" else None - errDict = {'name': 'stderr', 'text': err} if err != "" else None - return outDict,errDict + out = self.GetStdout() + err = self.GetStderr() + outDict = {"name": "stdout", "text": out} if out != "" else None + errDict = {"name": "stderr", "text": err} if err != "" else None + return outDict, errDict + class Poller(Thread): def __init__(self): @@ -87,10 +87,11 @@ def run(self): def Stop(self): if self.is_alive(): self.queue.put(None) - self.join() + self.join() + class Runner(object): - ''' Asynchrously run functions + """Asynchrously run functions >>> import time >>> def f(code): ... print(code) @@ -114,7 +115,8 @@ class Runner(object): >>> print(r.HasFinished()) True >>> p.Stop() - ''' + """ + def __init__(self, function, poller): self.function = function self.poller = poller @@ -128,13 +130,14 @@ def AsyncRun(self, argument): def Wait(self): while self.poller.is_running: - timeSleep(.1) + timeSleep(0.1) def HasFinished(self): return not self.poller.is_running + class JupyROOTDeclarer(Runner): - ''' Asynchrously execute declarations + """Asynchrously execute declarations >>> import ROOT >>> p = Poller(); p.start() >>> d = JupyROOTDeclarer(p) @@ -143,21 +146,25 @@ class JupyROOTDeclarer(Runner): >>> ROOT.f() 3 >>> p.Stop() - ''' + """ + def __init__(self, poller): - super(JupyROOTDeclarer, self).__init__(_lib.JupyROOTDeclarer, poller) + super(JupyROOTDeclarer, self).__init__(_lib.JupyROOTDeclarer, poller) + class JupyROOTExecutor(Runner): - r''' Asynchrously execute process lines + r"""Asynchrously execute process lines >>> import ROOT >>> p = Poller(); p.start() >>> d = JupyROOTExecutor(p) >>> d.Run('cout << "Here am I" << endl;') 1 >>> p.Stop() - ''' + """ + def __init__(self, poller): - super(JupyROOTExecutor, self).__init__(_lib.JupyROOTExecutor, poller) + super(JupyROOTExecutor, self).__init__(_lib.JupyROOTExecutor, poller) + def display_drawables(displayFunction): drawers = helpers.utils.GetDrawers() @@ -165,12 +172,15 @@ def display_drawables(displayFunction): for dobj in drawer.GetDrawableObjects(): displayFunction(dobj) + class JupyROOTDisplayer(Runner): - ''' Display all canvases''' + """Display all canvases""" + def __init__(self, poller): - super(JupyROOTDisplayer, self).__init__(display_drawables, poller) + super(JupyROOTDisplayer, self).__init__(display_drawables, poller) + -def RunAsyncAndPrint(executor, code, ioHandler, printFunction, displayFunction, silent = False, timeout = 0.1): +def RunAsyncAndPrint(executor, code, ioHandler, printFunction, displayFunction, silent=False, timeout=0.1): ioHandler.Clear() ioHandler.InitCapture() executor.AsyncRun(code) @@ -179,12 +189,13 @@ def RunAsyncAndPrint(executor, code, ioHandler, printFunction, displayFunction, if not silent: printFunction(ioHandler) ioHandler.Clear() - if executor.HasFinished(): break - timeSleep(.1) + if executor.HasFinished(): + break + timeSleep(0.1) executor.Wait() ioHandler.EndCapture() + def Display(displayer, displayFunction): displayer.AsyncRun(displayFunction) displayer.Wait() - diff --git a/bindings/jupyroot/python/JupyROOT/helpers/utils.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/utils.py similarity index 98% rename from bindings/jupyroot/python/JupyROOT/helpers/utils.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/utils.py index 0e9699ea6de41..72918f4edd1e7 100644 --- a/bindings/jupyroot/python/JupyROOT/helpers/utils.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/helpers/utils.py @@ -26,11 +26,11 @@ from hashlib import sha1 from subprocess import check_output -import ROOT from IPython import display, get_ipython from IPython.core.extensions import ExtensionManager -from JupyROOT.helpers import handlers +import ROOT +from ROOT._jupyroot.helpers import handlers # We want iPython to take over the graphics ROOT.gROOT.SetBatch() @@ -610,7 +610,12 @@ def _getJsCode(self): options = "" thisJsCode = _jsCode.format( - jsCanvasWidth=width, jsCanvasHeight=height, jsonLength=len(json), jsonZip=jsonzip, jsDrawOptions=options, jsDivId=divId + jsCanvasWidth=width, + jsCanvasHeight=height, + jsonLength=len(json), + jsonZip=jsonzip, + jsDrawOptions=options, + jsDivId=divId, ) return thisJsCode @@ -700,7 +705,7 @@ def setStyle(): def loadMagicsAndCapturers(): global captures - extNames = ["JupyROOT.magics." + name for name in ["cppmagic", "jsrootmagic"]] + extNames = ["ROOT._jupyroot.magics." + name for name in ["cppmagic", "jsrootmagic"]] ip = get_ipython() extMgr = ExtensionManager(ip) for extName in extNames: diff --git a/bindings/jupyroot/python/JupyROOT/magics/__init__.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/html/__init__.py similarity index 81% rename from bindings/jupyroot/python/JupyROOT/magics/__init__.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/html/__init__.py index 6e2e520ef9219..664a53fbeafbc 100644 --- a/bindings/jupyroot/python/JupyROOT/magics/__init__.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/html/__init__.py @@ -1,7 +1,7 @@ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Author: Danilo Piparo CERN # Author: Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # diff --git a/bindings/jupyroot/python/JupyROOT/html/cpphighlighter.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/html/cpphighlighter.py similarity index 87% rename from bindings/jupyroot/python/JupyROOT/html/cpphighlighter.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/html/cpphighlighter.py index 4f912116556c2..c533bb19e3130 100644 --- a/bindings/jupyroot/python/JupyROOT/html/cpphighlighter.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/html/cpphighlighter.py @@ -1,7 +1,7 @@ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Author: Danilo Piparo CERN # Author: Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -20,18 +20,19 @@ find out about the notebook's language. """ -from IPython.nbconvert.preprocessors.base import Preprocessor import re +from IPython.nbconvert.preprocessors.base import Preprocessor + class CppHighlighter(Preprocessor): """ Detects and tags code cells that use the C++ language. """ - magics = [ '%%cpp' ] - cpp = 'cpp' - python = 'python' + magics = ["%%cpp"] + cpp = "cpp" + python = "python" def __init__(self, config=None, **kw): super(CppHighlighter, self).__init__(config=config, **kw) @@ -51,14 +52,14 @@ def matches(self, source, reg_expr): def _preprocess_cell_python(self, cell, resources, cell_index): # Mark %%cpp and %%dcl code cells as cpp if cell.cell_type == "code" and self.matches(cell.source, self.re_magic_language): - cell['metadata']['magics_language'] = self.cpp + cell["metadata"]["magics_language"] = self.cpp return cell, resources def _preprocess_cell_cpp(self, cell, resources, cell_index): # Mark all code cells as cpp if cell.cell_type == "code": - cell['metadata']['magics_language'] = self.cpp + cell["metadata"]["magics_language"] = self.cpp return cell, resources @@ -67,7 +68,7 @@ def preprocess(self, nb, resources): try: if nb.metadata.kernelspec.language == "c++": self.preprocess_cell = self._preprocess_cell_cpp - except: + except Exception: # if no language metadata, keep python as default pass return super(CppHighlighter, self).preprocess(nb, resources) diff --git a/bindings/jupyroot/python/JupyROOT/kernel/__init__.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/__init__.py similarity index 82% rename from bindings/jupyroot/python/JupyROOT/kernel/__init__.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/__init__.py index a77ea89ac373c..a0e0625422272 100644 --- a/bindings/jupyroot/python/JupyROOT/kernel/__init__.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/__init__.py @@ -1,8 +1,8 @@ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Author: Omar Zapata http://oproject.org # Author: Danilo Piparo CERN # Author: Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # diff --git a/bindings/jupyroot/python/JupyROOT/kernel/magics/__init__.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/magics/__init__.py similarity index 82% rename from bindings/jupyroot/python/JupyROOT/kernel/magics/__init__.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/magics/__init__.py index a77ea89ac373c..a0e0625422272 100644 --- a/bindings/jupyroot/python/JupyROOT/kernel/magics/__init__.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/magics/__init__.py @@ -1,8 +1,8 @@ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Author: Omar Zapata http://oproject.org # Author: Danilo Piparo CERN # Author: Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # diff --git a/bindings/jupyroot/python/JupyROOT/kernel/magics/cppmagic.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/magics/cppmagic.py similarity index 54% rename from bindings/jupyroot/python/JupyROOT/kernel/magics/cppmagic.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/magics/cppmagic.py index 231263d55c78b..beb6af8a88a44 100644 --- a/bindings/jupyroot/python/JupyROOT/kernel/magics/cppmagic.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/magics/cppmagic.py @@ -1,9 +1,9 @@ # -*- coding:utf-8 -*- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Authors: Omar Zapata http://oproject.org # Danilo Piparo CERN # Enric Tejedor enric.tejedor.saavedra@cern.ch> CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -13,41 +13,38 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. # ################################################################################ + from metakernel import Magic, option -import sys -#NOTE:actually JupyROOT is not capturing the error on %%cpp -d if the function is wrong +# NOTE:actually JupyROOT is not capturing the error on %%cpp -d if the function is wrong class CppMagics(Magic): def __init__(self, kernel): super(CppMagics, self).__init__(kernel) - @option( - '-a', '--aclic', action='store', default="default", help='Compile code with ACLiC.' - ) - @option( - '-d', '--declare', action='store', default=None, help='Declare functions and/or classes.' - ) + + @option("-a", "--aclic", action="store", default="default", help="Compile code with ACLiC.") + @option("-d", "--declare", action="store", default=None, help="Declare functions and/or classes.") def cell_cpp(self, args): - '''Executes the content of the cell as C++ code.''' + """Executes the content of the cell as C++ code.""" if self.code.strip(): - execFunc = None - if args == '-a': - execFunc = self.kernel.ACLiC - elif args == '-d': - execFunc = self.kernel.Declarer.Run - else: # normal flow + execFunc = None + if args == "-a": + execFunc = self.kernel.ACLiC + elif args == "-d": + execFunc = self.kernel.Declarer.Run + else: # normal flow self.kernel.do_execute_direct(str(self.code)) self.evaluate = False return - self.kernel.ioHandler.Clear() - self.kernel.ioHandler.InitCapture() - execFunc(self.code) - self.kernel.ioHandler.EndCapture() - self.kernel.print_output(self.kernel.ioHandler) + self.kernel.ioHandler.Clear() + self.kernel.ioHandler.InitCapture() + execFunc(self.code) + self.kernel.ioHandler.EndCapture() + self.kernel.print_output(self.kernel.ioHandler) self.evaluate = False + def register_magics(kernel): kernel.register_magics(CppMagics) - diff --git a/bindings/jupyroot/python/JupyROOT/kernel/magics/jsrootmagic.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/magics/jsrootmagic.py similarity index 57% rename from bindings/jupyroot/python/JupyROOT/kernel/magics/jsrootmagic.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/magics/jsrootmagic.py index df019fbd6c4cc..d4e172f979bfa 100644 --- a/bindings/jupyroot/python/JupyROOT/kernel/magics/jsrootmagic.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/magics/jsrootmagic.py @@ -1,8 +1,8 @@ # -*- coding:utf-8 -*- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (c) 2016, ROOT Team. # Authors: Danilo Piparo CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -12,30 +12,37 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. # ################################################################################ -from JupyROOT.helpers.utils import enableJSVis, disableJSVis, enableJSVisDebug, TBufferJSONErrorMessage, TBufferJSONAvailable - from metakernel import Magic, option +from ROOT._jupyroot.helpers.utils import ( + TBufferJSONAvailable, + TBufferJSONErrorMessage, + disableJSVis, + enableJSVis, + enableJSVisDebug, +) + + class JSRootMagics(Magic): def __init__(self, kernel): super(JSRootMagics, self).__init__(kernel) - @option('arg', default="on", help='Enable or disable JavaScript visualisation. Possible values: on (default), off') + @option("arg", default="on", help="Enable or disable JavaScript visualisation. Possible values: on (default), off") def line_jsroot(self, args): - '''Change the visualisation of plots from images to interactive JavaScript objects.''' - if args == 'on' or args == '': - self.printErrorIfNeeded() - enableJSVis() - elif args == 'off': - disableJSVis() - elif args == 'debug': - self.printErrorIfNeeded() - enableJSVisDebug() + """Change the visualisation of plots from images to interactive JavaScript objects.""" + if args == "on" or args == "": + self.printErrorIfNeeded() + enableJSVis() + elif args == "off": + disableJSVis() + elif args == "debug": + self.printErrorIfNeeded() + enableJSVisDebug() def printErrorIfNeeded(self): if not TBufferJSONAvailable(): self.kernel.Error(TBufferJSONErrorMessage) + def register_magics(kernel): kernel.register_magics(JSRootMagics) - diff --git a/bindings/jupyroot/python/JupyROOT/kernel/rootkernel.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/rootkernel.py similarity index 53% rename from bindings/jupyroot/python/JupyROOT/kernel/rootkernel.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/rootkernel.py index 49bf51d18fcae..274fe27042def 100644 --- a/bindings/jupyroot/python/JupyROOT/kernel/rootkernel.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/rootkernel.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding:utf-8 -*- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Authors: Omar Zapata http://oproject.org # Danilo Piparo CERN # Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -23,47 +23,48 @@ except ImportError: raise Exception("Error: package metakernel not found.(install it running 'pip install metakernel')") -import ROOT - -from JupyROOT.helpers.utils import setStyle, invokeAclic, GetDrawers -from JupyROOT.helpers.handlers import RunAsyncAndPrint, Display -from JupyROOT.helpers.cppcompleter import CppCompleter -from JupyROOT.kernel.utils import GetIOHandler, GetPoller, GetExecutor, GetDeclarer, GetDisplayer, MagicLoader -import IPython +import ROOT +from ROOT._jupyroot.helpers.cppcompleter import CppCompleter +from ROOT._jupyroot.helpers.handlers import Display, RunAsyncAndPrint +from ROOT._jupyroot.helpers.utils import invokeAclic, setStyle +from ROOT._jupyroot.kernel.utils import GetDeclarer, GetDisplayer, GetExecutor, GetIOHandler, GetPoller, MagicLoader # We want iPython to take over the graphics ROOT.gROOT.SetBatch() + def Debug(msg): - print('Kernel main: %r' % msg, file=sys.__stderr__) + print("Kernel main: %r" % msg, file=sys.__stderr__) + class ROOTKernel(MetaKernel): # These two regexes are considered by the parser of the metakernel # there is no need to create one explicitly - identifier_regex = r'(?:\w(?:\w|\.|->|::|\d)*)' - func_call_regex = r'(?:\w(?:(?:\w|\.|->|::|\d))*)\([^\)\()]*\Z' - - implementation = 'ROOT' - implementation_version = '1.0' - language = 'c++' - language_version = '0.1' - language_info = {'name': 'c++', - 'codemirror_mode': 'text/x-c++src', - 'mimetype': ' text/x-c++src', - 'file_extension': '.C'} + identifier_regex = r"(?:\w(?:\w|\.|->|::|\d)*)" + func_call_regex = r"(?:\w(?:(?:\w|\.|->|::|\d))*)\([^\)\()]*\Z" + + implementation = "ROOT" + implementation_version = "1.0" + language = "c++" + language_version = "0.1" + language_info = { + "name": "c++", + "codemirror_mode": "text/x-c++src", + "mimetype": " text/x-c++src", + "file_extension": ".C", + } banner = "ROOT Kernel" - def __init__(self,**kwargs): - - MetaKernel.__init__(self,**kwargs) + def __init__(self, **kwargs): + MetaKernel.__init__(self, **kwargs) setStyle() self.ioHandler = GetIOHandler() - self.Poller = GetPoller() - self.Executor = GetExecutor(self.Poller) - self.Declarer = GetDeclarer(self.Poller) #required for %%cpp -d magic + self.Poller = GetPoller() + self.Executor = GetExecutor(self.Poller) + self.Declarer = GetDeclarer(self.Poller) # required for %%cpp -d magic self.Displayer = GetDisplayer(self.Poller) - self.ACLiC = invokeAclic + self.ACLiC = invokeAclic self.magicloader = MagicLoader(self) self.completer = CppCompleter() self.completer.activate() @@ -72,54 +73,49 @@ def __del__(self): self.Poller.Stop() def get_completions(self, info): - return self.completer._completeImpl(info['code']) + return self.completer._completeImpl(info["code"]) def print_output(self, handler): streamDicts = handler.GetStreamsDicts() - for streamDict in filter(lambda d: None != d, streamDicts): - self.send_response(self.iopub_socket, 'stream', streamDict) + for streamDict in filter(lambda d: d is not None, streamDicts): + self.send_response(self.iopub_socket, "stream", streamDict) def do_execute_direct(self, code, silent=False): - if not code.strip(): return - status = 'ok' + status = "ok" try: - RunAsyncAndPrint(self.Executor, - code, - self.ioHandler, - self.print_output, - silent, - .1) + RunAsyncAndPrint(self.Executor, code, self.ioHandler, self.print_output, silent, 0.1) Display(self.Displayer, self.Display) except KeyboardInterrupt: ROOT.gROOT.SetInterrupt() - status = 'interrupted' + status = "interrupted" self.ioHandler.EndCapture() if not silent: self.print_output(self.ioHandler) traceback = None - reply = {'status': status, - 'execution_count': self.execution_count, - 'payload': [], - 'user_expressions': {}, - } - - if status == 'interrupted': + reply = { + "status": status, + "execution_count": self.execution_count, + "payload": [], + "user_expressions": {}, + } + + if status == "interrupted": pass - elif status == 'error': + elif status == "error": err = { - 'ename': 'ename', - 'evalue': 'evalue', - 'traceback': traceback, + "ename": "ename", + "evalue": "evalue", + "traceback": traceback, } - self.send_response(self.iopub_socket, 'error', err) + self.send_response(self.iopub_socket, "error", err) reply.update(err) - elif status == 'ok': + elif status == "ok": pass else: raise ValueError("Invalid status: %r" % status) @@ -133,5 +129,6 @@ def main(): from IPython.kernel.zmq.kernelapp import IPKernelApp IPKernelApp.launch_instance(kernel_class=ROOTKernel) -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/bindings/jupyroot/python/JupyROOT/kernel/utils.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/utils.py similarity index 59% rename from bindings/jupyroot/python/JupyROOT/kernel/utils.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/utils.py index 25f593facedca..cb3e7c0d4d9fa 100644 --- a/bindings/jupyroot/python/JupyROOT/kernel/utils.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/kernel/utils.py @@ -1,9 +1,9 @@ # -*- coding:utf-8 -*- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Authors: Omar Zapata http://oproject.org # Danilo Piparo CERN # Enric Tejedor enric.tejedor.saavedra@cern.ch> CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -13,27 +13,26 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. # ################################################################################ +import importlib import os from glob import glob -import importlib - -from JupyROOT.helpers.handlers import IOHandler, Poller, JupyROOTDeclarer, JupyROOTExecutor, JupyROOTDisplayer - -import ROOT +from ROOT._jupyroot.helpers.handlers import IOHandler, JupyROOTDeclarer, JupyROOTDisplayer, JupyROOTExecutor, Poller _ioHandler = None -_Poller = None -_Executor = None -_Declarer = None +_Poller = None +_Executor = None +_Declarer = None _Displayer = None + def GetIOHandler(): global _ioHandler if not _ioHandler: _ioHandler = IOHandler() return _ioHandler + def GetPoller(): global _Poller if not _Poller: @@ -41,39 +40,40 @@ def GetPoller(): _Poller.start() return _Poller + def GetExecutor(poller): global _Executor if not _Executor: _Executor = JupyROOTExecutor(poller) return _Executor + def GetDeclarer(poller): global _Declarer if not _Declarer: _Declarer = JupyROOTDeclarer(poller) return _Declarer + def GetDisplayer(poller): global _Displayer if not _Displayer: _Displayer = JupyROOTDisplayer(poller) return _Displayer -class MagicLoader(object): - '''Class to load JupyROOT Magics''' - def __init__(self,kernel): - magics_path = os.path.join(os.path.dirname(__file__), "magics", "*.py") - for file in glob(magics_path): - if file != magics_path.replace("*.py","__init__.py"): - module_prefix = "JupyROOT.kernel.magics." - module_name = os.path.splitext(os.path.basename(file))[0] - module_path = module_prefix + module_name - try: - module = importlib.import_module(module_path) - module.register_magics(kernel) - except ImportError: - raise Exception("Error importing Magic: %s"%module_path) - - - +class MagicLoader(object): + """Class to load JupyROOT Magics""" + + def __init__(self, kernel): + magics_path = os.path.join(os.path.dirname(__file__), "magics", "*.py") + for file in glob(magics_path): + if file != magics_path.replace("*.py", "__init__.py"): + module_prefix = "ROOT._jupyroot.kernel.magics." + module_name = os.path.splitext(os.path.basename(file))[0] + module_path = module_prefix + module_name + try: + module = importlib.import_module(module_path) + module.register_magics(kernel) + except ImportError: + raise Exception("Error importing Magic: %s" % module_path) diff --git a/bindings/jupyroot/python/JupyROOT/helpers/__init__.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/magics/__init__.py similarity index 81% rename from bindings/jupyroot/python/JupyROOT/helpers/__init__.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/magics/__init__.py index 6e2e520ef9219..664a53fbeafbc 100644 --- a/bindings/jupyroot/python/JupyROOT/helpers/__init__.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/magics/__init__.py @@ -1,7 +1,7 @@ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Author: Danilo Piparo CERN # Author: Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # diff --git a/bindings/jupyroot/python/JupyROOT/magics/cppmagic.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/magics/cppmagic.py similarity index 65% rename from bindings/jupyroot/python/JupyROOT/magics/cppmagic.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/magics/cppmagic.py index 5ff226952c139..a7f9671ccc2c9 100644 --- a/bindings/jupyroot/python/JupyROOT/magics/cppmagic.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/magics/cppmagic.py @@ -1,7 +1,7 @@ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Author: Danilo Piparo CERN # Author: Enric Tejedor CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -11,19 +11,20 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. # ################################################################################ -from IPython.core.magic import (Magics, magics_class, cell_magic) -from IPython.core.magic_arguments import (argument, magic_arguments, parse_argstring) -from JupyROOT.helpers import utils +from IPython.core.magic import Magics, cell_magic, magics_class +from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring + +from ROOT._jupyroot.helpers import utils @magics_class class CppMagics(Magics): @cell_magic @magic_arguments() - @argument('-a', '--aclic', action="store_true", help='Compile code with ACLiC.') - @argument('-d', '--declare', action="store_true", help='Declare functions and/or classes.') + @argument("-a", "--aclic", action="store_true", help="Compile code with ACLiC.") + @argument("-d", "--declare", action="store_true", help="Declare functions and/or classes.") def cpp(self, line, cell): - '''Executes the content of the cell as C++ code.''' + """Executes the content of the cell as C++ code.""" args = parse_argstring(self.cpp, line) if args.aclic: utils.invokeAclic(cell) @@ -32,5 +33,6 @@ def cpp(self, line, cell): else: utils.processMagicCppCode(cell) + def load_ipython_extension(ipython): ipython.register_magics(CppMagics) diff --git a/bindings/jupyroot/python/JupyROOT/magics/jsrootmagic.py b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/magics/jsrootmagic.py similarity index 54% rename from bindings/jupyroot/python/JupyROOT/magics/jsrootmagic.py rename to bindings/pyroot/pythonizations/python/ROOT/_jupyroot/magics/jsrootmagic.py index 17fe8f79483ac..05851b03b90b5 100644 --- a/bindings/jupyroot/python/JupyROOT/magics/jsrootmagic.py +++ b/bindings/pyroot/pythonizations/python/ROOT/_jupyroot/magics/jsrootmagic.py @@ -1,8 +1,8 @@ # -*- coding:utf-8 -*- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (c) 2016, ROOT Team. # Authors: Danilo Piparo CERN -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- ################################################################################ # Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. # @@ -12,9 +12,11 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. # ################################################################################ -from IPython.core.magic import (Magics, magics_class, line_magic) -from IPython.core.magic_arguments import (argument, magic_arguments, parse_argstring) -from JupyROOT.helpers.utils import enableJSVis, disableJSVis, enableJSVisDebug +from IPython.core.magic import Magics, line_magic, magics_class +from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring + +from ROOT._jupyroot.helpers.utils import disableJSVis, enableJSVis, enableJSVisDebug + @magics_class class JSRootMagics(Magics): @@ -23,17 +25,22 @@ def __init__(self, shell): @line_magic @magic_arguments() - @argument('arg', nargs="?", default="on", help='Enable or disable JavaScript visualisation. Possible values: on (default), off') - + @argument( + "arg", + nargs="?", + default="on", + help="Enable or disable JavaScript visualisation. Possible values: on (default), off", + ) def jsroot(self, line): - '''Change the visualisation of plots from images to interactive JavaScript objects.''' + """Change the visualisation of plots from images to interactive JavaScript objects.""" args = parse_argstring(self.jsroot, line) - if args.arg == 'on': - enableJSVis() - elif args.arg == 'off': - disableJSVis() - elif args.arg == 'debug': - enableJSVisDebug() + if args.arg == "on": + enableJSVis() + elif args.arg == "off": + disableJSVis() + elif args.arg == "debug": + enableJSVisDebug() + def load_ipython_extension(ipython): ipython.register_magics(JSRootMagics) diff --git a/bindings/pyroot/pythonizations/src/PyROOTModule.cxx b/bindings/pyroot/pythonizations/src/PyROOTModule.cxx index a3127ad25e681..dfb400658e628 100644 --- a/bindings/pyroot/pythonizations/src/PyROOTModule.cxx +++ b/bindings/pyroot/pythonizations/src/PyROOTModule.cxx @@ -212,9 +212,6 @@ extern "C" PyObject *PyInit_libROOTPythonizations() // signal policy: don't abort interpreter in interactive mode CallContext::SetGlobalPolicy(CallContext::kProtected, !gROOT->IsBatch()); - // inject ROOT namespace for convenience - PyModule_AddObject(gRootModule, (char *)"ROOT", CreateScopeProxy("ROOT")); - Py_INCREF(gRootModule); return gRootModule; } diff --git a/bindings/tpython/src/TPython.cxx b/bindings/tpython/src/TPython.cxx index 2b976e194a3c7..da5da424e7fac 100644 --- a/bindings/tpython/src/TPython.cxx +++ b/bindings/tpython/src/TPython.cxx @@ -185,6 +185,11 @@ Bool_t TPython::Initialize() std::cerr << "Error: import ROOT failed, check your PYTHONPATH environmental variable." << std::endl; return false; } + // to trigger the lazy initialization of the C++ runtime + if (PyRun_SimpleString("ROOT.gInterpreter") != 0) { + std::cerr << "Error: initializing ROOT Python module failed." << std::endl; + return false; + } if (!gMainDict) { diff --git a/etc/notebook/html/sample_config.py b/etc/notebook/html/sample_config.py deleted file mode 100644 index c960ac5c437d8..0000000000000 --- a/etc/notebook/html/sample_config.py +++ /dev/null @@ -1,10 +0,0 @@ -# JupyROOT sample configuration file for nbconvert - -c = get_config() - -# Custom C++ highlighter -c.Exporter.preprocessors = [ 'JupyROOT.html.cpphighlighter.CppHighlighter' ] - -# Custom Jinja template -c.HTMLExporter.template_path = [ '/path/to/JupyROOT/html/templates' ] -c.HTMLExporter.template_file = 'root_notebook.tpl' diff --git a/etc/notebook/kernels/root/kernel.json.in b/etc/notebook/kernels/root/kernel.json.in index 2025139fdc35a..4f58114d33eb9 100644 --- a/etc/notebook/kernels/root/kernel.json.in +++ b/etc/notebook/kernels/root/kernel.json.in @@ -4,7 +4,7 @@ "argv": [ "python@Python3_VERSION_MAJOR@.@Python3_VERSION_MINOR@", "-m", - "JupyROOT.kernel.rootkernel", + "ROOT._jupyroot.kernel.rootkernel", "-f", "{connection_file}" ] diff --git a/roottest/python/JupyROOT/CMakeLists.txt b/roottest/python/JupyROOT/CMakeLists.txt index 932fe478efe1f..07547c27328fb 100644 --- a/roottest/python/JupyROOT/CMakeLists.txt +++ b/roottest/python/JupyROOT/CMakeLists.txt @@ -4,7 +4,7 @@ if(NOT MSVC OR win_broken_tests) # Do not run with classic build or if tests are vetoed if (pyroot AND NOT ROOT_CLASSIC_BUILD) -set(MODULES_LOCATION ${ROOTSYS}/lib/JupyROOT/helpers) +set(MODULES_LOCATION ${ROOTSYS}/lib/ROOT/_jupyroot/helpers) set(NBDIFFUTIL ${CMAKE_CURRENT_SOURCE_DIR}/nbdiff.py ) set(DOCTEST_LAUNCHER ${CMAKE_CURRENT_SOURCE_DIR}/doctest_launcher.py) diff --git a/roottest/python/JupyROOT/ipythondir/kernels/root/kernel.json b/roottest/python/JupyROOT/ipythondir/kernels/root/kernel.json deleted file mode 100644 index 689b154b8eecf..0000000000000 --- a/roottest/python/JupyROOT/ipythondir/kernels/root/kernel.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "language": "c++", - "display_name": "ROOT C++", - "argv": [ - "python", - "-m", - "JupyROOT.kernel.rootkernel", - "-f", - "{connection_file}" - ] -} diff --git a/roottest/python/JupyROOT/nbdiff.py b/roottest/python/JupyROOT/nbdiff.py index ed6eb67ac9099..3b194452bdaa3 100644 --- a/roottest/python/JupyROOT/nbdiff.py +++ b/roottest/python/JupyROOT/nbdiff.py @@ -111,7 +111,7 @@ def createKernelSpec(): "argv": [ "%s", "-m", - "JupyROOT.kernel.rootkernel", + "ROOT._jupyroot.kernel.rootkernel", "-f", "{connection_file}" ]