Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
reference.hh
Go to the documentation of this file.
1// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set ts=8 sw=4 et sts=4:
3
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUFEM_PYTHON_REFERENCE_HH
8#define DUNE_FUFEM_PYTHON_REFERENCE_HH
9
10// Only introduce the dune-python interface if python
11// was found and enabled.
12#if HAVE_PYTHON || DOXYGEN
13
14#include <Python.h>
15
16#include <string>
17#include <type_traits>
18
22
23
24
25namespace Python
26{
27
28
29
30// forward declaration needed by Python::Reference
31class Reference;
32template<class T> struct Conversion;
33template<class T> Reference makeObject(const T& t);
34template<typename... Ts> Reference makeTuple(const Ts&...);
35void handlePythonError(const std::string& origin, const std::string& message);
36
37
38
77{
78 public:
79
84 p_(0)
85 {}
86
106 Reference(PyObject* p) :
107 p_(p)
108 {}
109
118 Reference(const Reference& other) :
119 p_(other.p_)
120 {
121 Py_XINCREF(p_);
122 }
123
131 virtual ~Reference()
132 {
133 if (Py_IsInitialized())
134 Py_XDECREF(p_);
135 }
136
145 virtual Reference& operator= (const Reference& other)
146 {
147 Py_XINCREF(other.p_);
148 Py_XDECREF(p_);
149 p_ = other.p_;
150 return *this;
151 }
152
162 operator PyObject* () const
163 {
164 return p_;
165 }
166
176 template<class T>
177 void toC(T& t) const
178 {
179 assertPyObject("toC()");
181 }
182
191 template<class T>
193 {
194 assertPyObject("toC()");
195 T t;
197 return t;
198 }
199
208 template<class T>
210 {
211 assertPyObject("toC()");
212 return Conversion<T>::toC(p_);
213 }
214
220 bool hasAttr(const std::string& name) const
221 {
222 assertPyObject("hasAttr()");
223 return PyObject_HasAttrString(p_, name.c_str());
224 }
225
237 {
238 assertPyObject("get()");
239 // This returns a new reference, i.e., it increments the reference count.
240 PyObject* value = PyObject_GetAttrString(p_, name.c_str());
241 if (not value)
242 handlePythonError("get()", Dune::formatString("failed to get attribute '%s'", name.c_str()));
243 return value;
244 }
245
257 template<class V>
258 void set(const std::string& name, const V& value)
259 {
260 assertPyObject("set()");
261 if (PyObject_SetAttrString(p_, name.c_str(), makeObject(value))==-1)
262 handlePythonError("set()", Dune::formatString("failed to set attribute '%s'", name.c_str()));
263 }
264
269 {
270 assertPyObject("str()");
271#if PY_MAJOR_VERSION >= 3
272 const char* s = PyUnicode_AsUTF8(PyObject_Str(p_));
273#else
274 char* s = PyString_AsString(PyObject_Str(p_));
275#endif
276 if (not s)
277 handlePythonError("str()", "cannot obtain string representation");
278 return s;
279 }
280
281 protected:
282
288 void assertPyObject(const std::string& origin) const
289 {
290 if (not p_)
292 "Python error occurred." << std::endl <<
293 " Origin: " << origin << std::endl <<
294 " Error: Python::Reference points to NULL object");
295 }
296
297 // We must store a mutable pointer since all methods of the
298 // python api use nonsonst PyObject* pointers.
299 mutable PyObject* p_;
300};
301
302
303} // end of namespace Python
304
305
306
307#else
308 #warning dunepython.hh was included but python was not found or enabled!
309#endif // DUNE_FUFEM_PYTHON_REFERENCE_HH
310
311
312#endif
313
const char * name()
static std::string formatString(const std::string &s, const T &... args)
void message(const std::string &msg)
#define DUNE_THROW(E,...)
Definition callable.hh:34
void handlePythonError(const std::string &origin, const std::string &message)
If a python error occurred throw an exception and clear python error indicator.
Definition common.hh:589
Reference makeTuple(const Ts &... ts)
create a Python tuple
Definition common.hh:364
Reference makeObject(const T &t)
Create python object from C++ object.
Definition common.hh:351
static void toC(PyObject *x, T &y)
Definition common.hh:67
Wrapper class for python objects.
Definition reference.hh:77
std::enable_if< Conversion< T >::useCustomConstructorConversion, T >::type toC() const
Convert to C object.
Definition reference.hh:209
void set(const std::string &name, const V &value)
Set attribute of given name.
Definition reference.hh:258
void toC(T &t) const
Convert to C object.
Definition reference.hh:177
bool hasAttr(const std::string &name) const
Check if object has attribute of given name.
Definition reference.hh:220
Reference(PyObject *p)
Construct Reference from PyObject*.
Definition reference.hh:106
Reference get(const std::string &name) const
Query attribute of given name.
Definition reference.hh:236
virtual Reference & operator=(const Reference &other)
Assignment.
Definition reference.hh:145
Reference(const Reference &other)
Copy constructor.
Definition reference.hh:118
PyObject * p_
Definition reference.hh:299
Reference()
Construct empty Reference.
Definition reference.hh:83
void assertPyObject(const std::string &origin) const
Assert that internal PyObject* is not NULL and raise exception otherwise.
Definition reference.hh:288
virtual ~Reference()
Destructor.
Definition reference.hh:131
std::string str() const
String representation of this object.
Definition reference.hh:268
std::enable_if< Conversion< T >::useDefaultConstructorConversion, T >::type toC() const
Convert to C object.
Definition reference.hh:192
T endl(T... args)