Logo ROOT  
Reference Guide
PyResult.cxx
Go to the documentation of this file.
1// Bindings
2#include "CPyCppyy.h"
3#define CPYCPPYY_INTERNAL 1
4#include "CPyCppyy/PyResult.h"
5#undef CPYCPPYY_INTERNAL
6
7#include "CPPInstance.h"
8
9// Standard
10#include <stdexcept>
11
12
13//______________________________________________________________________________
14// Python expression eval result
15// =============================
16//
17// Transport class for bringing objects from python (dynamically typed) to Cling
18// (statically typed). It is best to immediately cast a PyResult to the real
19// type, either implicitly (for builtin types) or explicitly (through a void*
20// cast for pointers to C++ objects).
21
22
23//- constructors/destructor --------------------------------------------------
25{
26// Construct a PyResult object from Py_None.
27 Py_INCREF(Py_None);
28 fPyObject = Py_None;
29}
30
31//----------------------------------------------------------------------------
33{
34// Construct a PyResult from a python object. The python object may represent
35// a C++ object. Steals reference to given python object.
36 if (!pyobject) {
37 Py_INCREF(Py_None);
38 fPyObject = Py_None;
39 } else
40 fPyObject = pyobject; // steals reference
41}
42
43//----------------------------------------------------------------------------
45{
46// Copy constructor. Applies python object reference counting.
47 Py_INCREF(other.fPyObject);
48 fPyObject = other.fPyObject;
49}
50
51//----------------------------------------------------------------------------
53{
54// Assignment operator. Applies python object reference counting.
55 if (this != &other) {
56 Py_INCREF(other.fPyObject);
57 Py_DECREF(fPyObject);
58 fPyObject = other.fPyObject;
59 }
60
61 return *this;
62}
63
64//----------------------------------------------------------------------------
66{
67// Destructor. Reference counting for the held python object is in effect.
68 Py_DECREF(fPyObject);
69}
70
71
72//- public members -----------------------------------------------------------
73CPyCppyy::PyResult::operator char*() const
74{
75// Cast python return value to C-style string (may fail).
76 return (char*)((const char*)*this);
77}
78
79//----------------------------------------------------------------------------
80CPyCppyy::PyResult::operator const char*() const
81{
82// Cast python return value to C-style string (may fail).
83 if (fPyObject == Py_None) // for void returns
84 return nullptr;
85
86 const char* s = CPyCppyy_PyText_AsString(fPyObject);
87 if (PyErr_Occurred()) {
88 PyErr_Print();
89 return nullptr;
90 }
91
92 return s;
93}
94
95//----------------------------------------------------------------------------
96CPyCppyy::PyResult::operator char() const
97{
98// Cast python return value to C++ char (may fail).
99 std::string s = operator const char*();
100 if (s.size())
101 return s[0];
102
103 return '\0';
104}
105
106//----------------------------------------------------------------------------
107CPyCppyy::PyResult::operator long() const
108{
109// Cast python return value to C++ long (may fail).
110 long l = PyLong_AsLong(fPyObject);
111
112 if (PyErr_Occurred())
113 PyErr_Print();
114
115 return l;
116}
117
118//----------------------------------------------------------------------------
119CPyCppyy::PyResult::operator unsigned long() const
120{
121// Cast python return value to C++ unsigned long (may fail).
122 unsigned long ul = PyLong_AsUnsignedLong(fPyObject);
123
124 if (PyErr_Occurred())
125 PyErr_Print();
126
127 return ul;
128}
129
130//----------------------------------------------------------------------------
131CPyCppyy::PyResult::operator double() const
132{
133// Cast python return value to C++ double (may fail).
134 double d = PyFloat_AsDouble(fPyObject);
135
136 if (PyErr_Occurred())
137 PyErr_Print();
138
139 return d;
140}
141
142//----------------------------------------------------------------------------
143CPyCppyy::PyResult::operator void*() const
144{
145// Cast python return value to C++ object with dictionary (may fail; note that
146// you have to use the void* converter, as CINT will not call any other).
147 if (fPyObject == Py_None)
148 return nullptr;
149
150 if (CPyCppyy::CPPInstance_Check(fPyObject)) {
151 ((CPyCppyy::CPPInstance*)fPyObject)->CppOwns();
152 return ((CPyCppyy::CPPInstance*)fPyObject)->GetObject();
153 } else
154 return fPyObject; // borrows reference
155}
156
157//----------------------------------------------------------------------------
158CPyCppyy::PyResult::operator PyObject*() const
159{
160// Direct return of the held PyObject; note the new reference.
161 if (fPyObject == Py_None)
162 return nullptr;
163
164 Py_INCREF(fPyObject);
165 return fPyObject;
166}
#define CPyCppyy_PyText_AsString
Definition: CPyCppyy.h:97
double
Definition: Converters.cxx:921
PyFloat_AsDouble
Definition: Converters.cxx:921
long
Definition: Converters.cxx:858
_object PyObject
Definition: PyMethodBase.h:41
#define d(i)
Definition: RSha256.hxx:102
virtual ~PyResult()
Definition: PyResult.cxx:65
PyObject * fPyObject
Definition: PyResult.h:60
PyResult & operator=(const PyResult &)
Definition: PyResult.cxx:52
bool CPPInstance_Check(T *object)
Definition: CPPInstance.h:118
static constexpr double s
auto * l
Definition: textangle.C:4