Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
PyROOTModule.cxx
Go to the documentation of this file.
1// Author: Enric Tejedor CERN 06/2018
2// Original PyROOT code by Wim Lavrijsen, LBL
3
4/*************************************************************************
5 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12// Bindings
13#include "PyROOTPythonize.h"
14#include "RPyROOTApplication.h"
15
16// Cppyy
17#include "CPyCppyy/API.h"
20
21// ROOT
22#include "TInterpreter.h"
23#include "TROOT.h"
24#include "TSystem.h"
25#include "RConfigure.h"
26
27// Standard
28#include <any>
29#include <string>
30#include <sstream>
31#include <utility>
32#include <vector>
33
34#include "IOHandler.cxx"
35
36namespace PyROOT {
37
39
41{
42 PyObject *name = nullptr;
43 PyObject *target = nullptr;
44
45 PyArg_ParseTuple(args, "UU:RegisterConverterAlias", &name, &target);
46
48
50}
51
53{
54 PyObject *name = nullptr;
55 PyObject *target = nullptr;
56
57 PyArg_ParseTuple(args, "UU:RegisterExecutorAlias", &name, &target);
58
60
62}
63
64/// \brief A PyObject wrapper to track reference counting of external objects
65///
66/// This wrapper can be useful in shared ownership scenarios when a C++ object
67/// is created on the Python side and there is no easy way to track its ownership
68/// on the C++ side. If multiple instances of this class are given the same
69/// Python proxy, they will increase/decrease its reference counting following
70/// Python rules and ensure proper destruction of the underlying C++ object when
71/// no other Python objects are referencing it.
73 PyObject *fObject{nullptr};
74
75 void Reset(PyObject *object)
76 {
77 if (fObject) {
79 fObject = nullptr;
80 }
81 if (object) {
82 Py_INCREF(object);
84 }
85 }
86
87public:
88 PyObjRefCounter(PyObject *object) { Reset(object); }
89
90 ~PyObjRefCounter() { Reset(nullptr); }
91
93
95 {
96 Reset(other.fObject);
97 return *this;
98 }
99
101 {
102 fObject = other.fObject;
103 other.fObject = nullptr;
104 }
105
107 {
108 fObject = other.fObject;
109 other.fObject = nullptr;
110 return *this;
111 }
112};
113
115{
116 PyObject *object = nullptr;
117
118 PyArg_ParseTuple(args, "O:PyObjRefCounterAsStdAny", &object);
119
120 // The std::any is managed by Python
121 return CPyCppyy::Instance_FromVoidPtr(new std::any{std::in_place_type<PyObjRefCounter>, object}, "std::any",
122 /*python_owns=*/true);
123}
124
125} // namespace PyROOT
126
127// Methods offered by the interface
129 {(char *)"AddCPPInstancePickling", (PyCFunction)PyROOT::AddCPPInstancePickling, METH_VARARGS,
130 (char *)"Add a custom pickling mechanism for Cppyy Python proxy objects"},
131 {(char *)"GetBranchAttr", (PyCFunction)PyROOT::GetBranchAttr, METH_VARARGS,
132 (char *)"Allow to access branches as tree attributes"},
133 {(char *)"AddTClassDynamicCastPyz", (PyCFunction)PyROOT::AddTClassDynamicCastPyz, METH_VARARGS,
134 (char *)"Cast the void* returned by TClass::DynamicCast to the right type"},
135 {(char *)"AddTObjectEqNePyz", (PyCFunction)PyROOT::AddTObjectEqNePyz, METH_VARARGS,
136 (char *)"Add equality and inequality comparison operators to TObject"},
137 {(char *)"BranchPyz", (PyCFunction)PyROOT::BranchPyz, METH_VARARGS,
138 (char *)"Fully enable the use of TTree::Branch from Python"},
139 {(char *)"AddPrettyPrintingPyz", (PyCFunction)PyROOT::AddPrettyPrintingPyz, METH_VARARGS,
140 (char *)"Add pretty printing pythonization"},
142 (char *)"Initialize interactive ROOT use from Python"},
144 (char *)"Install an input hook to process GUI events"},
145 {(char *)"_CPPInstance__expand__", (PyCFunction)PyROOT::CPPInstanceExpand, METH_VARARGS,
146 (char *)"Deserialize a pickled object"},
147 {(char *)"JupyROOTExecutor", (PyCFunction)JupyROOTExecutor, METH_VARARGS, (char *)"Create JupyROOTExecutor"},
148 {(char *)"JupyROOTDeclarer", (PyCFunction)JupyROOTDeclarer, METH_VARARGS, (char *)"Create JupyROOTDeclarer"},
149 {(char *)"JupyROOTExecutorHandler_Clear", (PyCFunction)JupyROOTExecutorHandler_Clear, METH_NOARGS,
150 (char *)"Clear JupyROOTExecutorHandler"},
151 {(char *)"JupyROOTExecutorHandler_Ctor", (PyCFunction)JupyROOTExecutorHandler_Ctor, METH_NOARGS,
152 (char *)"Create JupyROOTExecutorHandler"},
153 {(char *)"JupyROOTExecutorHandler_Poll", (PyCFunction)JupyROOTExecutorHandler_Poll, METH_NOARGS,
154 (char *)"Poll JupyROOTExecutorHandler"},
155 {(char *)"JupyROOTExecutorHandler_EndCapture", (PyCFunction)JupyROOTExecutorHandler_EndCapture, METH_NOARGS,
156 (char *)"End capture JupyROOTExecutorHandler"},
157 {(char *)"JupyROOTExecutorHandler_InitCapture", (PyCFunction)JupyROOTExecutorHandler_InitCapture, METH_NOARGS,
158 (char *)"Init capture JupyROOTExecutorHandler"},
159 {(char *)"JupyROOTExecutorHandler_GetStdout", (PyCFunction)JupyROOTExecutorHandler_GetStdout, METH_NOARGS,
160 (char *)"Get stdout JupyROOTExecutorHandler"},
161 {(char *)"JupyROOTExecutorHandler_GetStderr", (PyCFunction)JupyROOTExecutorHandler_GetStderr, METH_NOARGS,
162 (char *)"Get stderr JupyROOTExecutorHandler"},
163 {(char *)"JupyROOTExecutorHandler_Dtor", (PyCFunction)JupyROOTExecutorHandler_Dtor, METH_NOARGS,
164 (char *)"Destruct JupyROOTExecutorHandler"},
165 {(char *)"CPyCppyyRegisterConverterAlias", (PyCFunction)PyROOT::RegisterConverterAlias, METH_VARARGS,
166 (char *)"Register a custom converter that is a reference to an existing converter"},
167 {(char *)"CPyCppyyRegisterExecutorAlias", (PyCFunction)PyROOT::RegisterExecutorAlias, METH_VARARGS,
168 (char *)"Register a custom executor that is a reference to an existing executor"},
169 {(char *)"PyObjRefCounterAsStdAny", (PyCFunction)PyROOT::PyObjRefCounterAsStdAny, METH_VARARGS,
170 (char *)"Wrap a reference count to any Python object in a std::any for resource management in C++"},
171 {NULL, NULL, 0, NULL}};
172
176
177using namespace CPyCppyy;
178
179#define GETSTATE(m) ((struct module_state *)PyModule_GetState(m))
180
182{
183 Py_VISIT(GETSTATE(m)->error);
184 return 0;
185}
186
188{
189 Py_CLEAR(GETSTATE(m)->error);
190 return 0;
191}
192
193static struct PyModuleDef moduledef = {PyModuleDef_HEAD_INIT, "libROOTPythonizations", NULL,
194 sizeof(struct module_state), gPyROOTMethods, NULL,
196
197/// Initialization of extension module libROOTPythonizations
198
200{
201 using namespace PyROOT;
202
203 // setup PyROOT
204 gRootModule = PyModule_Create(&moduledef);
205 if (!gRootModule)
206 return nullptr;
207
208 // keep gRootModule, but do not increase its reference count even as it is borrowed,
209 // or a self-referencing cycle would be created
210
211 // Initialize and acquire the GIL to allow for threading in ROOT
212#if PY_VERSION_HEX < 0x03090000
214#endif
215
216 // Make sure the interpreter is initialized once gROOT has been initialized
218
219 // signal policy: don't abort interpreter in interactive mode
221
222 // inject ROOT namespace for convenience
223 PyModule_AddObject(gRootModule, (char *)"ROOT", CreateScopeProxy("ROOT"));
224
225 Py_INCREF(gRootModule);
226 return gRootModule;
227}
#define Py_RETURN_NONE
Definition CPyCppyy.h:268
PyObject * JupyROOTExecutorHandler_Ctor(PyObject *, PyObject *)
PyObject * JupyROOTDeclarer(PyObject *, PyObject *args)
PyObject * JupyROOTExecutorHandler_GetStdout(PyObject *, PyObject *)
PyObject * JupyROOTExecutor(PyObject *, PyObject *args)
PyObject * JupyROOTExecutorHandler_EndCapture(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_Poll(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_Clear(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_GetStderr(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_InitCapture(PyObject *, PyObject *)
PyObject * JupyROOTExecutorHandler_Dtor(PyObject *, PyObject *)
_object PyObject
static struct PyModuleDef moduledef
#define GETSTATE(m)
PyObject * PyInit_libROOTPythonizations()
Initialization of extension module libROOTPythonizations.
static int rootmodule_clear(PyObject *m)
static int rootmodule_traverse(PyObject *m, visitproc visit, void *arg)
static PyMethodDef gPyROOTMethods[]
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
char name[80]
Definition TGX11.cxx:110
#define gROOT
Definition TROOT.h:406
A PyObject wrapper to track reference counting of external objects.
PyObjRefCounter(PyObject *object)
PyObjRefCounter & operator=(PyObjRefCounter &&other)
void Reset(PyObject *object)
PyObjRefCounter(const PyObjRefCounter &other)
PyObjRefCounter(PyObjRefCounter &&other)
PyObjRefCounter & operator=(const PyObjRefCounter &other)
static PyObject * InstallGUIEventInputHook(PyObject *self, PyObject *args)
Install a method hook for sending events to the GUI.
static PyObject * InitApplication(PyObject *self, PyObject *args)
Initialize an RPyROOTApplication.
static TInterpreter * Instance()
returns gInterpreter global
CPYCPPYY_EXTERN bool RegisterExecutorAlias(const std::string &name, const std::string &target)
PyObject * CreateScopeProxy(Cppyy::TCppScope_t, const unsigned flags=0)
CPYCPPYY_EXTERN PyObject * Instance_FromVoidPtr(void *addr, const std::string &classname, bool python_owns=false)
Definition API.cxx:121
CPYCPPYY_EXTERN bool RegisterConverterAlias(const std::string &name, const std::string &target)
PyObject * AddTObjectEqNePyz(PyObject *self, PyObject *args)
Add pythonization for equality and inequality operators in TObject.
PyObject * PyObjRefCounterAsStdAny(PyObject *, PyObject *args)
PyObject * BranchPyz(PyObject *self, PyObject *args)
Add pythonization for TTree::Branch.
Definition TTreePyz.cxx:361
PyObject * AddCPPInstancePickling(PyObject *self, PyObject *args)
Set reduce attribute for CPPInstance objects.
PyObject * CPPInstanceExpand(PyObject *self, PyObject *args)
Deserialize pickled objects.
PyObject * gRootModule
PyObject * AddTClassDynamicCastPyz(PyObject *self, PyObject *args)
Add pythonization for TClass::DynamicCast.
Definition TClassPyz.cxx:68
PyObject * RegisterExecutorAlias(PyObject *, PyObject *args)
PyObject * GetBranchAttr(PyObject *self, PyObject *args)
Definition TTreePyz.cxx:177
PyObject * RegisterConverterAlias(PyObject *, PyObject *args)
PyObject * AddPrettyPrintingPyz(PyObject *self, PyObject *args)
Add pretty printing pythonization.
static bool SetGlobalSignalPolicy(bool setProtected)
PyObject * error
TMarker m
Definition textangle.C:8