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