Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
PyzPythonHelpers.cxx
Go to the documentation of this file.
1// Author: Stefan Wunsch CERN 08/2018
2// Original PyROOT code by Wim Lavrijsen, LBL
3
4/*************************************************************************
5 * Copyright (C) 1995-2018, 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/**
13
14Set of helper functions that are invoked from the pythonizors, on the
15Python side. For that purpose, they are included in the interface of the
16PyROOT extension module.
17
18*/
19
20#include "CPyCppyy.h"
21#include "CPPInstance.h"
22#include "CPPOverload.h"
23
24#include "PyROOTPythonize.h"
25
26#include "ROOT/RConfig.hxx"
27#include "TInterpreter.h"
28
29#include <sstream>
30
31// needed to properly resolve (dllimport) symbols on Windows
32namespace CPyCppyy {
33 namespace PyStrings {
35 }
36}
37
38////////////////////////////////////////////////////////////////////////////
39/// \brief Get endianess of the system
40/// \param[in] self Always null, since this is a module function.
41/// \param[in] args Pointer to an empty Python tuple.
42/// \return Endianess as Python string
43///
44/// This function returns endianess of the system as a Python integer. The
45/// return value is either '<' or '>' for little or big endian, respectively.
46PyObject *PyROOT::GetEndianess(PyObject * /* self */, PyObject * /* args */)
47{
48#ifdef R__BYTESWAP
50#else
52#endif
53}
54
55using namespace CPyCppyy;
56
57// Helper to add base class methods to the derived class one
58static bool AddUsingToClass(PyObject *pyclass, const char *method)
59{
60 CPPOverload *derivedMethod = (CPPOverload *)PyObject_GetAttrString(pyclass, const_cast<char *>(method));
61 if (!CPPOverload_Check(derivedMethod)) {
62 Py_XDECREF(derivedMethod);
63 return false;
64 }
65
66 PyObject *mro = PyObject_GetAttr(pyclass, PyStrings::gMRO);
67 if (!mro || !PyTuple_Check(mro)) {
68 Py_XDECREF(mro);
69 Py_DECREF(derivedMethod);
70 return false;
71 }
72
73 CPPOverload *baseMethod = nullptr;
74 for (int i = 1; i < PyTuple_GET_SIZE(mro); ++i) {
75 baseMethod = (CPPOverload *)PyObject_GetAttrString(PyTuple_GET_ITEM(mro, i), const_cast<char *>(method));
76
77 if (!baseMethod) {
78 PyErr_Clear();
79 continue;
80 }
81
82 if (CPPOverload_Check(baseMethod))
83 break;
84
85 Py_DECREF(baseMethod);
86 baseMethod = nullptr;
87 }
88
89 Py_DECREF(mro);
90
91 if (!CPPOverload_Check(baseMethod)) {
92 Py_XDECREF(baseMethod);
93 Py_DECREF(derivedMethod);
94 return false;
95 }
96
97 for (PyCallable *pc : baseMethod->fMethodInfo->fMethods) {
98 derivedMethod->AdoptMethod(pc->Clone());
99 }
100
101 Py_DECREF(baseMethod);
102 Py_DECREF(derivedMethod);
103
104 return true;
105}
106
107////////////////////////////////////////////////////////////////////////////
108/// \brief Add base class overloads of a given method to a derived class
109/// \param[in] self Always null, since this is a module function.
110/// \param[in] args [0] Derived class. [1] Name of the method whose base
111/// class overloads to inject in the derived class.
112///
113/// This function adds base class overloads to a derived class for a given
114/// method. This covers the 'using' case, which is not supported by default
115/// by the bindings.
117{
118 // Get derived class to pythonize
119 PyObject *pyclass = PyTuple_GetItem(args, 0);
120
121 // Get method name where to add overloads
122 PyObject *pyname = PyTuple_GetItem(args, 1);
123 auto cppname = CPyCppyy_PyText_AsString(pyname);
124
125 AddUsingToClass(pyclass, cppname);
126
128}
#define CPyCppyy_PyText_AsString
Definition CPyCppyy.h:97
#define Py_RETURN_NONE
Definition CPyCppyy.h:289
#define CPyCppyy_PyText_FromString
Definition CPyCppyy.h:102
#define R__EXTERN
Definition DllImport.h:27
_object PyObject
static bool AddUsingToClass(PyObject *pyclass, const char *method)
#define pyname
void AdoptMethod(PyCallable *pc)
MethodInfo_t * fMethodInfo
Definition CPPOverload.h:72
Set of helper functions that are invoked from the pythonizors, on the Python side.
bool CPPOverload_Check(T *object)
Definition CPPOverload.h:83
PyObject * GetEndianess(PyObject *self, PyObject *args)
Get endianess of the system.
PyObject * AddUsingToClass(PyObject *self, PyObject *args)
Add base class overloads of a given method to a derived class.
CPPOverload::Methods_t fMethods
Definition CPPOverload.h:47