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