Logo ROOT   6.12/07
Reference Guide
TPyReturn.cxx
Go to the documentation of this file.
1 // @(#)root/pyroot:$Id$
2 // Author: Wim Lavrijsen, May 2004
3 
4 // Bindings
5 #include "PyROOT.h"
6 #include "TPyReturn.h"
7 #include "ObjectProxy.h"
8 
9 // ROOT
10 #include "TObject.h"
11 #include "TInterpreter.h"
12 
13 // Standard
14 #include <stdexcept>
15 
16 
17 //______________________________________________________________________________
18 // Python expression eval result
19 // =============================
20 //
21 // Transport class for bringing objects from python (dynamically typed) to Cling
22 // (statically typed). It is best to immediately cast a TPyReturn to the real
23 // type, either implicitly (for builtin types) or explicitly (through a void*
24 // cast for pointers to ROOT objects).
25 //
26 // Examples:
27 //
28 // root [0] TBrowser* b = (void*)TPython::Eval( "ROOT.TBrowser()" );
29 // root [1] int i = TPython::Eval( "1+1" );
30 // root [2] i
31 // (int)2
32 // root [3] double d = TPython::Eval( "1+3.1415" );
33 // root [4] d
34 // (double)4.14150000000000063e+00
35 
36 
37 //- data ---------------------------------------------------------------------
39 
40 
41 //- constructors/destructor --------------------------------------------------
43 {
44 // Construct a TPyReturn object from Py_None.
45  Py_INCREF( Py_None );
46  fPyObject = Py_None;
47 }
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 /// Construct a TPyReturn from a python object. The python object may represent
51 /// a ROOT object. Steals reference to given python object.
52 
54 {
55  if ( ! pyobject ) {
56  Py_INCREF( Py_None );
57  fPyObject = Py_None;
58  } else
59  fPyObject = pyobject; // steals reference
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// Copy constructor. Applies python object reference counting.
64 
66 {
67  Py_INCREF( other.fPyObject );
68  fPyObject = other.fPyObject;
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 /// Assignment operator. Applies python object reference counting.
73 
75 {
76  if ( this != &other ) {
77  Py_INCREF( other.fPyObject );
78  Py_DECREF( fPyObject );
79  fPyObject = other.fPyObject;
80  }
81 
82  return *this;
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 /// Destructor. Reference counting for the held python object is in effect.
87 
89 {
90  Py_DECREF( fPyObject );
91 }
92 
93 
94 //- public members -----------------------------------------------------------
95 TPyReturn::operator char*() const
96 {
97 // Cast python return value to C-style string (may fail).
98  return (char*)((const char*)*this);
99 }
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 /// Cast python return value to C-style string (may fail).
103 
104 TPyReturn::operator const char*() const
105 {
106  if ( fPyObject == Py_None ) // for void returns
107  return 0;
108 
109  const char* s = PyROOT_PyUnicode_AsString( fPyObject );
110  if ( PyErr_Occurred() ) {
111  PyErr_Print();
112  return 0;
113  }
114 
115  return s;
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Cast python return value to C++ char (may fail).
120 
121 TPyReturn::operator Char_t() const
122 {
123  std::string s = operator const char*();
124  if ( s.size() )
125  return s[0];
126 
127  return '\0';
128 }
129 
130 ////////////////////////////////////////////////////////////////////////////////
131 /// Cast python return value to C++ long (may fail).
132 
133 TPyReturn::operator Long_t() const
134 {
135  Long_t l = PyLong_AsLong( fPyObject );
136 
137  if ( PyErr_Occurred() )
138  PyErr_Print();
139 
140  return l;
141 }
142 
143 ////////////////////////////////////////////////////////////////////////////////
144 /// Cast python return value to C++ unsigned long (may fail).
145 
146 TPyReturn::operator ULong_t() const
147 {
148  ULong_t ul = PyLong_AsUnsignedLong( fPyObject );
149 
150  if ( PyErr_Occurred() )
151  PyErr_Print();
152 
153  return ul;
154 }
155 
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 /// Cast python return value to C++ double (may fail).
159 
160 TPyReturn::operator Double_t() const
161 {
162  Double_t d = PyFloat_AsDouble( fPyObject );
163 
164  if ( PyErr_Occurred() )
165  PyErr_Print();
166 
167  return d;
168 }
169 
170 ////////////////////////////////////////////////////////////////////////////////
171 /// Cast python return value to ROOT object with dictionary (may fail; note that
172 /// you have to use the void* converter, as CINT will not call any other).
173 
174 TPyReturn::operator void*() const
175 {
176  if ( fPyObject == Py_None )
177  return 0;
178 
180  ((PyROOT::ObjectProxy*)fPyObject)->Release();
181  return ((PyROOT::ObjectProxy*)fPyObject)->GetObject();
182  } else
183  return fPyObject; // borrows reference
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Direct return of the held PyObject; note the new reference.
188 
189 TPyReturn::operator PyObject*() const
190 {
191  if ( fPyObject == Py_None )
192  return 0;
193 
194  Py_INCREF( fPyObject );
195  return fPyObject;
196 }
TPyReturn & operator=(const TPyReturn &)
Assignment operator. Applies python object reference counting.
Definition: TPyReturn.cxx:74
#define PyROOT_PyUnicode_AsString
Definition: PyROOT.h:66
virtual ~TPyReturn()
Destructor. Reference counting for the held python object is in effect.
Definition: TPyReturn.cxx:88
Bool_t ObjectProxy_Check(T *object)
Definition: ObjectProxy.h:91
long Long_t
Definition: RtypesCore.h:50
#define ClassImp(name)
Definition: Rtypes.h:359
double Double_t
Definition: RtypesCore.h:55
unsigned long ULong_t
Definition: RtypesCore.h:51
static constexpr double s
PyObject * fPyObject
Definition: TPyReturn.h:60
char Char_t
Definition: RtypesCore.h:29
auto * l
Definition: textangle.C:4
_object PyObject
Definition: TPyArg.h:20