Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CPPExcInstance.cxx
Go to the documentation of this file.
1// Bindings
2#include "cpyrt.h"
3
4using namespace cppjit;
5#include "CPPExcInstance.h"
6#include "PyStrings.h"
7
8//______________________________________________________________________________
9// Python-side exception proxy objects
10// ===================================
11//
12// Python exceptions need to derive from PyException as it expects a set of
13// specific data members. This class exists so that general CPPInstances need
14// not carry that overhead. In use, it forwards to the embedded CPPInstance.
15
16namespace cppjit::cpyrt {
17
18//= cpyrt exception object proxy construction/destruction =================
19static PyObject* ep_new(PyTypeObject* subtype, PyObject* args, PyObject* kwds) {
20 // Create a new exception object proxy (holder only).
21 PyObject* pyobj =
22 ((PyTypeObject*)PyExc_Exception)->tp_new(subtype, nullptr, nullptr);
23 if (!pyobj)
24 return nullptr;
25
26 CPPExcInstance* excobj = (CPPExcInstance*)pyobj;
27 excobj->fTopMessage = nullptr;
28 if (args) {
29 PyObject* ulc =
30 PyObject_GetAttr((PyObject*)subtype, PyStrings::gUnderlying);
31 excobj->fCppInstance = PyType_Type.tp_call(ulc, args, kwds);
32 if (!excobj->fCppInstance) {
33 // if this fails, then the construction may have been attempted from a
34 // string (e.g. from PyErr_Format); if so, drop the proxy and use
35 // fTopMessage instead
36 PyErr_Clear();
37 if (PyTuple_GET_SIZE(args) == 1) {
38 PyObject* msg = PyTuple_GET_ITEM(args, 0);
39 if (PyUnicode_Check(msg)) {
40 Py_INCREF(msg);
41 excobj->fTopMessage = msg;
42 }
43 }
44 }
45 Py_DECREF(ulc);
46 } else
47 excobj->fCppInstance = nullptr;
48
49 return pyobj;
50}
51
52//----------------------------------------------------------------------------
53static int ep_traverse(CPPExcInstance* pyobj, visitproc visit, void* args) {
54 // Garbage collector traverse of held python member objects.
55 ((PyTypeObject*)PyExc_Exception)->tp_traverse((PyObject*)pyobj, visit, args);
56
57 if (pyobj->fCppInstance)
58 visit(pyobj->fCppInstance, args);
59
60 if (pyobj->fTopMessage)
61 visit(pyobj->fTopMessage, args);
62
63 return 0;
64}
65
66//----------------------------------------------------------------------------
68 if (self->fCppInstance) {
69 PyObject* what =
70 PyObject_CallMethod((PyObject*)self, (char*)"what", nullptr);
71 if (what) {
72 if (self->fTopMessage) {
73 Py_INCREF(self->fTopMessage);
74 PyObject* top = self->fTopMessage;
75 PyUnicode_Append(&top, what);
76 Py_DECREF(what);
77 what = top;
78 }
79 return what;
80 }
81 PyErr_Clear();
82 return PyObject_Str(self->fCppInstance);
83 }
84
85 if (self->fTopMessage) {
86 Py_INCREF(self->fTopMessage);
87 return self->fTopMessage;
88 }
89
90 return PyType_Type.tp_str((PyObject*)self);
91}
92
93//----------------------------------------------------------------------------
95 if (self->fCppInstance)
96 return PyObject_Repr(self->fCppInstance);
97 return PyType_Type.tp_repr((PyObject*)self);
98}
99
100//----------------------------------------------------------------------------
101static void ep_dealloc(CPPExcInstance* pyobj) {
102 PyObject* tmp1 = pyobj->fCppInstance;
103 PyObject* tmp2 = pyobj->fTopMessage;
104
105 ((PyTypeObject*)PyExc_Exception)->tp_dealloc((PyObject*)pyobj);
106 Py_CLEAR(tmp1);
107 Py_CLEAR(tmp2);
108}
109
110//----------------------------------------------------------------------------
111static int ep_clear(CPPExcInstance* pyobj) {
112 // Garbage collector clear of held python member objects.
113 ((PyTypeObject*)PyExc_Exception)->tp_clear((PyObject*)pyobj);
114
115 Py_CLEAR(pyobj->fCppInstance);
116 Py_CLEAR(pyobj->fTopMessage);
117
118 return 0;
119}
120
121//= forwarding methods =======================================================
123 if (self->fCppInstance) {
124 PyObject* res = PyObject_GetAttr(self->fCppInstance, attr);
125 if (res)
126 return res;
127 PyErr_Clear();
128 }
129
130 return ((PyTypeObject*)PyExc_Exception)->tp_getattro((PyObject*)self, attr);
131}
132
133//----------------------------------------------------------------------------
135 if (self->fCppInstance) {
136 int res = PyObject_SetAttr(self->fCppInstance, attr, value);
137 if (!res)
138 return res;
139 PyErr_Clear();
140 }
141
142 return ((PyTypeObject*)PyExc_Exception)
143 ->tp_setattro((PyObject*)self, attr, value);
144}
145
146//----------------------------------------------------------------------------
147static PyObject* ep_richcompare(CPPExcInstance* self, PyObject* other, int op) {
148 return PyObject_RichCompare(self->fCppInstance, other, op);
149}
150
151//----------------------------------------------------------------------------
152static int ep_nonzero(CPPExcInstance* self) {
153 if (self->fCppInstance)
154 return PyObject_IsTrue(self->fCppInstance);
155
156 return 0;
157}
158
159//-----------------------------------------------------------------------------
160static PyNumberMethods ep_as_number = {
161 0, // nb_add
162 0, // nb_subtract
163 0, // nb_multiply
164 0, // nb_remainder
165 0, // nb_divmod
166 0, // nb_power
167 0, // nb_negative
168 0, // nb_positive
169 0, // nb_absolute
170 (inquiry)ep_nonzero, // nb_bool (nb_nonzero in p2)
171 0, // nb_invert
172 0, // nb_lshift
173 0, // nb_rshift
174 0, // nb_and
175 0, // nb_xor
176 0, // nb_or
177 0, // nb_int
178 0, // nb_long (nb_reserved in p3)
179 0, // nb_float
180 0, // nb_inplace_add
181 0, // nb_inplace_subtract
182 0, // nb_inplace_multiply
183 0, // nb_inplace_remainder
184 0, // nb_inplace_power
185 0, // nb_inplace_lshift
186 0, // nb_inplace_rshift
187 0, // nb_inplace_and
188 0, // nb_inplace_xor
189 0, // nb_inplace_or
190 0, // nb_floor_divide
191 0, // nb_true_divide
192 0, // nb_inplace_floor_divide
193 0, // nb_inplace_true_divide
194 0, // nb_index
195 0, // nb_matrix_multiply
196 0 // nb_inplace_matrix_multiply
197};
198
199//= cpyrt exception object proxy type ======================================
200PyTypeObject CPPExcInstance_Type = {
201 PyVarObject_HEAD_INIT(&PyType_Type,
202 0)(char*) "cppjit.CPPExcInstance", // tp_name
203 sizeof(CPPExcInstance), // tp_basicsize
204 0, // tp_itemsize
205 (destructor)ep_dealloc, // tp_dealloc
206 0, // tp_vectorcall_offset / tp_print
207 0, // tp_getattr
208 0, // tp_setattr
209 0, // tp_as_async / tp_compare
210 (reprfunc)ep_repr, // tp_repr
211 &ep_as_number, // tp_as_number
212 0, // tp_as_sequence
213 0, // tp_as_mapping
214 0, // tp_hash
215 0, // tp_call
216 (reprfunc)ep_str, // tp_str
217 (getattrofunc)ep_getattro, // tp_getattro
218 (setattrofunc)ep_setattro, // tp_setattro
219 0, // tp_as_buffer
220 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_BASE_EXC_SUBCLASS |
221 Py_TPFLAGS_HAVE_GC, // tp_flags
222 (char*)"cppjit exception object proxy (internal)", // tp_doc
223 (traverseproc)ep_traverse, // tp_traverse
224 (inquiry)ep_clear, // tp_clear
225 (richcmpfunc)ep_richcompare, // tp_richcompare
226 0, // tp_weaklistoffset
227 0, // tp_iter
228 0, // tp_iternext
229 0, // tp_methods
230 0, // tp_members
231 0, // tp_getset
232 (PyTypeObject*)PyExc_Exception, // tp_base
233 0, // tp_dict
234 0, // tp_descr_get
235 0, // tp_descr_set
236 0, // tp_dictoffset
237 0, // tp_init
238 0, // tp_alloc
239 (newfunc)ep_new, // tp_new
240 0, // tp_free
241 0, // tp_is_gc
242 0, // tp_bases
243 0, // tp_mro
244 0, // tp_cache
245 0, // tp_subclasses
246 0, // tp_weaklist
247 0, // tp_del
248 0, // tp_version_tag
249 0, // tp_finalize
250 0 // tp_vectorcall
252
253} // namespace cppjit::cpyrt
_object PyObject
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
#define CPYRT_PYTYPE_TAIL
Definition cpyrt.h:159
static PyObject * ep_getattro(CPPExcInstance *self, PyObject *attr)
static PyObject * ep_repr(CPPExcInstance *self)
static void ep_dealloc(CPPExcInstance *pyobj)
static PyNumberMethods ep_as_number
static int ep_clear(CPPExcInstance *pyobj)
static PyObject * ep_str(CPPExcInstance *self)
static PyObject * ep_richcompare(CPPExcInstance *self, PyObject *other, int op)
static int ep_setattro(CPPExcInstance *self, PyObject *attr, PyObject *value)
PyTypeObject CPPExcInstance_Type
static int ep_nonzero(CPPExcInstance *self)
static PyObject * ep_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
static int ep_traverse(CPPExcInstance *pyobj, visitproc visit, void *args)
Definition API.cxx:34
static const char * what
Definition stlLoader.cc:5