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 ---------------------------------------------------------------------
43
44namespace {
45 class PyGILRAII {
46 PyGILState_STATE m_GILState;
47 public:
48 PyGILRAII() : m_GILState(PyGILState_Ensure()) { }
49 ~PyGILRAII() { PyGILState_Release(m_GILState); }
50 };
51}
52
53//- constructors/destructor --------------------------------------------------
55{
56 PyGILRAII gilRaii;
57
58 // Construct a TPyReturn object from Py_None.
61}
62
63////////////////////////////////////////////////////////////////////////////////
64/// Construct a TPyReturn from a python object. The python object may represent
65/// a ROOT object. Steals reference to given python object.
66
68{
69 PyGILRAII gilRaii;
70
71 if (!pyobject) {
74 } else
75 fPyObject = pyobject; // steals reference
76}
77
78////////////////////////////////////////////////////////////////////////////////
79/// Copy constructor. Applies python object reference counting.
80
82{
83 PyGILRAII gilRaii;
84
85 Py_IncRef(other.fPyObject);
86 fPyObject = other.fPyObject;
87}
88
89////////////////////////////////////////////////////////////////////////////////
90/// Assignment operator. Applies python object reference counting.
91
93{
94 PyGILRAII gilRaii;
95
96 if (this != &other) {
97 Py_IncRef(other.fPyObject);
99 fPyObject = other.fPyObject;
100 }
101
102 return *this;
103}
104
105////////////////////////////////////////////////////////////////////////////////
106/// Destructor. Reference counting for the held python object is in effect.
107
109{
110 PyGILRAII gilRaii;
111
113}
114
115//- public members -----------------------------------------------------------
116TPyReturn::operator char *() const
117{
118 PyGILRAII gilRaii;
119
120 // Cast python return value to C-style string (may fail).
121 return (char *)((const char *)*this);
122}
123
124////////////////////////////////////////////////////////////////////////////////
125/// Cast python return value to C-style string (may fail).
126
127TPyReturn::operator const char *() const
128{
129 PyGILRAII gilRaii;
130
131 if (fPyObject == Py_None) // for void returns
132 return 0;
133
134 const char *s = PyUnicode_AsUTF8(fPyObject);
135 if (PyErr_Occurred()) {
136 PyErr_Print();
137 return 0;
138 }
139
140 return s;
141}
142
143////////////////////////////////////////////////////////////////////////////////
144/// Cast python return value to C++ char (may fail).
145
146TPyReturn::operator Char_t() const
147{
148 PyGILRAII gilRaii;
149
150 std::string s = operator const char *();
151 if (s.size())
152 return s[0];
153
154 return '\0';
155}
156
157////////////////////////////////////////////////////////////////////////////////
158/// Cast python return value to C++ long (may fail).
159
160TPyReturn::operator Long_t() const
161{
162 PyGILRAII gilRaii;
163
164 Long_t l = PyLong_AsLong(fPyObject);
165
166 if (PyErr_Occurred())
167 PyErr_Print();
168
169 return l;
170}
171
172////////////////////////////////////////////////////////////////////////////////
173/// Cast python return value to C++ unsigned long (may fail).
174
175TPyReturn::operator ULong_t() const
176{
177 PyGILRAII gilRaii;
178
179 ULong_t ul = PyLong_AsUnsignedLong(fPyObject);
180
181 if (PyErr_Occurred())
182 PyErr_Print();
183
184 return ul;
185}
186
187////////////////////////////////////////////////////////////////////////////////
188/// Cast python return value to C++ double (may fail).
189
190TPyReturn::operator Double_t() const
191{
192 PyGILRAII gilRaii;
193
194 Double_t d = PyFloat_AsDouble(fPyObject);
195
196 if (PyErr_Occurred())
197 PyErr_Print();
198
199 return d;
200}
201
202////////////////////////////////////////////////////////////////////////////////
203/// Cast python return value to ROOT object with dictionary (may fail; note that
204/// you have to use the void* converter, as CINT will not call any other).
205
206TPyReturn::operator void *() const
207{
208 PyGILRAII gilRaii;
209
210 if (fPyObject == Py_None)
211 return 0;
212
213 return static_cast<void *>(CPyCppyy::PyResult{fPyObject});
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Direct return of the held PyObject; note the new reference.
218
219TPyReturn::operator PyObject *() const
220{
221 PyGILRAII gilRaii;
222
223 if (fPyObject == Py_None)
224 return 0;
225
226 Py_IncRef(fPyObject);
227 return fPyObject;
228}
#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:92
virtual ~TPyReturn()
Destructor. Reference counting for the held python object is in effect.
PyObject * fPyObject
Definition TPyReturn.h:62
TLine l
Definition textangle.C:4