Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TPyArg.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 <Python.h>
14
15#include "TPyArg.h"
16
17//______________________________________________________________________________
18// Generic wrapper for arguments
19// =============================
20//
21// Transport class for bringing C++ values and objects from Cling to Python. It
22// provides, from the selected constructor, the proper conversion to a PyObject.
23// In principle, there should be no need to use this class directly: it relies
24// on implicit conversions.
25
26//- data ---------------------------------------------------------------------
27
28namespace {
29 class PyGILRAII {
30 PyGILState_STATE m_GILState;
31 public:
32 PyGILRAII() : m_GILState(PyGILState_Ensure()) { }
33 ~PyGILRAII() { PyGILState_Release(m_GILState); }
34 };
35}
36
37//- constructor dispatcher ---------------------------------------------------
38void TPyArg::CallConstructor(PyObject *&pyself, PyObject *pyclass, const std::vector<TPyArg> &args)
39{
40 PyGILRAII gilRaii;
41
42 int nArgs = args.size();
43 PyObject *pyargs = PyTuple_New(nArgs);
44 for (int i = 0; i < nArgs; ++i)
45 PyTuple_SetItem(pyargs, i, (PyObject *)args[i]);
46 pyself = PyObject_Call(pyclass, pyargs, NULL);
47 Py_DecRef(pyargs);
48}
49
50////////////////////////////////////////////////////////////////////////////////
51void CallConstructor(PyObject *&pyself, PyObject *pyclass)
52{
53 PyGILRAII gilRaii;
54
55 PyObject *pyargs = PyTuple_New(0);
56 pyself = PyObject_Call(pyclass, pyargs, NULL);
57 Py_DecRef(pyargs);
58}
59
60//- generic dispatcher -------------------------------------------------------
61PyObject *TPyArg::CallMethod(PyObject *pymeth, const std::vector<TPyArg> &args)
62{
63 PyGILRAII gilRaii;
64
65 int nArgs = args.size();
66 PyObject *pyargs = PyTuple_New(nArgs);
67 for (int i = 0; i < nArgs; ++i)
68 PyTuple_SetItem(pyargs, i, (PyObject *)args[i]);
69 PyObject *result = PyObject_Call(pymeth, pyargs, NULL);
70 Py_DecRef(pyargs);
71 return result;
72}
73
74//- denstructor dispatcher ----------------------------------------------------
75void TPyArg::CallDestructor(PyObject *&pyself, PyObject *, const std::vector<TPyArg> &)
76{
77 PyGILRAII gilRaii;
78
79 Py_DecRef(pyself); // calls actual dtor if ref-count down to 0
80}
81
82////////////////////////////////////////////////////////////////////////////////
84{
85 PyGILRAII gilRaii;
86
87 Py_DecRef(pyself);
88}
89
90//- constructors/destructor --------------------------------------------------
92{
93 PyGILRAII gilRaii;
94
95 // Construct a TPyArg from a python object.
96 Py_IncRef(pyobject);
97 fPyObject = pyobject;
98}
99
100////////////////////////////////////////////////////////////////////////////////
101/// Construct a TPyArg from an integer value.
102
104{
105 PyGILRAII gilRaii;
106
107 fPyObject = PyLong_FromLong(value);
108}
109
110////////////////////////////////////////////////////////////////////////////////
111/// Construct a TPyArg from an integer value.
112
114{
115 PyGILRAII gilRaii;
116
117 fPyObject = PyLong_FromLong(value);
118}
119
120////////////////////////////////////////////////////////////////////////////////
121/// Construct a TPyArg from a double value.
122
124{
125 PyGILRAII gilRaii;
126
127 fPyObject = PyFloat_FromDouble(value);
128}
129
130////////////////////////////////////////////////////////////////////////////////
131/// Construct a TPyArg from a C-string.
132
133TPyArg::TPyArg(const char *value)
134{
135 PyGILRAII gilRaii;
136
137 fPyObject = PyUnicode_FromString(value);
138}
139
140////////////////////////////////////////////////////////////////////////////////
141/// Copy constructor.
142
144{
145 PyGILRAII gilRaii;
146
147 Py_IncRef(s.fPyObject);
149}
150
151////////////////////////////////////////////////////////////////////////////////
152/// Assignment operator.
153
155{
156 PyGILRAII gilRaii;
157
158 if (&s != this) {
159 Py_IncRef(s.fPyObject);
161 }
162 return *this;
163}
164
165////////////////////////////////////////////////////////////////////////////////
166/// Done with held PyObject.
167
169{
170 PyGILRAII gilRaii;
171
172 Py_DecRef(fPyObject);
173 fPyObject = NULL;
174}
175
176//- public members -----------------------------------------------------------
177TPyArg::operator PyObject *() const
178{
179 PyGILRAII gilRaii;
180
181 // Extract the python object.
182 Py_IncRef(fPyObject);
183 return fPyObject;
184}
_object PyObject
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
void CallConstructor(PyObject *&pyself, PyObject *pyclass)
Definition TPyArg.cxx:51
static PyObject * CallMethod(PyObject *pymeth, const std::vector< TPyArg > &args)
Definition TPyArg.cxx:61
PyObject * fPyObject
! converted C++ value as python object
Definition TPyArg.h:52
static void CallDestructor(PyObject *&pyself, PyObject *pymeth, const std::vector< TPyArg > &args)
Definition TPyArg.cxx:75
TPyArg(PyObject *)
Definition TPyArg.cxx:91
TPyArg & operator=(const TPyArg &)
Assignment operator.
Definition TPyArg.cxx:154
virtual ~TPyArg()
Done with held PyObject.
Definition TPyArg.cxx:168
static void CallConstructor(PyObject *&pyself, PyObject *pyclass, const std::vector< TPyArg > &args)
Definition TPyArg.cxx:38