Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TPyReturn.cxx
Go to the documentation of this file.
1// Author: Enric Tejedor CERN 08/2019
2// Original PyROOT code by Wim Lavrijsen, LBL
3//
4// /*************************************************************************
5// * Copyright (C) 1995-2019, 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 "CPyCppyy/API.h"
14#include "TPyReturn.h"
15
16// ROOT
17#include "TObject.h"
18#include "TInterpreter.h"
19
20// Standard
21#include <stdexcept>
22
23//______________________________________________________________________________
24// Python expression eval result
25// =============================
26//
27// Transport class for bringing objects from python (dynamically typed) to Cling
28// (statically typed). It is best to immediately cast a TPyReturn to the real
29// type, either implicitly (for builtin types) or explicitly (through a void*
30// cast for pointers to ROOT objects).
31//
32// Examples:
33//
34// root [0] TBrowser* b = (void*)TPython::Eval( "ROOT.TBrowser()" );
35// root [1] int i = TPython::Eval( "1+1" );
36// root [2] i
37// (int)2
38// root [3] double d = TPython::Eval( "1+3.1415" );
39// root [4] d
40// (double)4.14150000000000063e+00
41
42//- data ---------------------------------------------------------------------
44
45namespace {
46 class PyGILRAII {
47 PyGILState_STATE m_GILState;
48 public:
49 PyGILRAII() : m_GILState(PyGILState_Ensure()) { }
50 ~PyGILRAII() { PyGILState_Release(m_GILState); }
51 };
52}
53
54//- constructors/destructor --------------------------------------------------
56{
57 PyGILRAII gilRaii;
58
59 // Construct a TPyReturn object from Py_None.
60 Py_INCREF(Py_None);
61 fPyObject = Py_None;
62}
63
64////////////////////////////////////////////////////////////////////////////////
65/// Construct a TPyReturn from a python object. The python object may represent
66/// a ROOT object. Steals reference to given python object.
67
69{
70 PyGILRAII gilRaii;
71
72 if (!pyobject) {
73 Py_INCREF(Py_None);
74 fPyObject = Py_None;
75 } else
76 fPyObject = pyobject; // steals reference
77}
78
79////////////////////////////////////////////////////////////////////////////////
80/// Copy constructor. Applies python object reference counting.
81
83{
84 PyGILRAII gilRaii;
85
86 Py_INCREF(other.fPyObject);
87 fPyObject = other.fPyObject;
88}
89
90////////////////////////////////////////////////////////////////////////////////
91/// Assignment operator. Applies python object reference counting.
92
94{
95 PyGILRAII gilRaii;
96
97 if (this != &other) {
98 Py_INCREF(other.fPyObject);
99 Py_DECREF(fPyObject);
100 fPyObject = other.fPyObject;
101 }
102
103 return *this;
104}
105
106////////////////////////////////////////////////////////////////////////////////
107/// Destructor. Reference counting for the held python object is in effect.
108
110{
111 PyGILRAII gilRaii;
112
113 Py_DECREF(fPyObject);
114}
115
116//- public members -----------------------------------------------------------
117TPyReturn::operator char *() const
118{
119 PyGILRAII gilRaii;
120
121 // Cast python return value to C-style string (may fail).
122 return (char *)((const char *)*this);
123}
124
125////////////////////////////////////////////////////////////////////////////////
126/// Cast python return value to C-style string (may fail).
127
128TPyReturn::operator const char *() const
129{
130 PyGILRAII gilRaii;
131
132 if (fPyObject == Py_None) // for void returns
133 return 0;
134
135 const char *s = PyUnicode_AsUTF8(fPyObject);
136 if (PyErr_Occurred()) {
137 PyErr_Print();
138 return 0;
139 }
140
141 return s;
142}
143
144////////////////////////////////////////////////////////////////////////////////
145/// Cast python return value to C++ char (may fail).
146
147TPyReturn::operator Char_t() const
148{
149 PyGILRAII gilRaii;
150
151 std::string s = operator const char *();
152 if (s.size())
153 return s[0];
154
155 return '\0';
156}
157
158////////////////////////////////////////////////////////////////////////////////
159/// Cast python return value to C++ long (may fail).
160
161TPyReturn::operator Long_t() const
162{
163 PyGILRAII gilRaii;
164
165 Long_t l = PyLong_AsLong(fPyObject);
166
167 if (PyErr_Occurred())
168 PyErr_Print();
169
170 return l;
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Cast python return value to C++ unsigned long (may fail).
175
176TPyReturn::operator ULong_t() const
177{
178 PyGILRAII gilRaii;
179
180 ULong_t ul = PyLong_AsUnsignedLong(fPyObject);
181
182 if (PyErr_Occurred())
183 PyErr_Print();
184
185 return ul;
186}
187
188////////////////////////////////////////////////////////////////////////////////
189/// Cast python return value to C++ double (may fail).
190
191TPyReturn::operator Double_t() const
192{
193 PyGILRAII gilRaii;
194
195 Double_t d = PyFloat_AsDouble(fPyObject);
196
197 if (PyErr_Occurred())
198 PyErr_Print();
199
200 return d;
201}
202
203////////////////////////////////////////////////////////////////////////////////
204/// Cast python return value to ROOT object with dictionary (may fail; note that
205/// you have to use the void* converter, as CINT will not call any other).
206
207TPyReturn::operator void *() const
208{
209 PyGILRAII gilRaii;
210
211 if (fPyObject == Py_None)
212 return 0;
213
214 return static_cast<void *>(CPyCppyy::PyResult{fPyObject});
215}
216
217////////////////////////////////////////////////////////////////////////////////
218/// Direct return of the held PyObject; note the new reference.
219
220TPyReturn::operator PyObject *() const
221{
222 PyGILRAII gilRaii;
223
224 if (fPyObject == Py_None)
225 return 0;
226
227 Py_INCREF(fPyObject);
228 return fPyObject;
229}
#define d(i)
Definition RSha256.hxx:102
char Char_t
Definition RtypesCore.h:37
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
double Double_t
Definition RtypesCore.h:59
#define ClassImp(name)
Definition Rtypes.h:382
_object PyObject
Definition TPyReturn.h:28
TPyReturn & operator=(const TPyReturn &)
Assignment operator. Applies python object reference counting.
Definition TPyReturn.cxx:93
virtual ~TPyReturn()
Destructor. Reference counting for the held python object is in effect.
PyObject * fPyObject
Definition TPyReturn.h:69
TLine l
Definition textangle.C:4