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