Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
PyException.cxx
Go to the documentation of this file.
1// Standard
2#include <string.h>
3
4// Bindings
5#include "cpyrt.h"
6
7using namespace cppjit;
8#define CPYRT_INTERNAL 1
9#include "cpyrt/DispatchPtr.h"
10#include "cpyrt/PyException.h"
11#undef CPYRT_INTERNAL
12
13//______________________________________________________________________________
14// C++ exception for throwing python exceptions
15// ============================================
16// Purpose: A C++ exception class for throwing python exceptions
17// through C++ code.
18// Created: Apr, 2004, Scott Snyder, from the version in D0's python_util.
19//
20// Note: Don't be tempted to declare the virtual functions defined here
21// as inline.
22// If you do, you may not be able to properly throw these
23// exceptions across shared libraries.
24
25//- constructors/destructor --------------------------------------------------
27#ifdef WITH_THREAD
28 PythonGILRAII python_gil_raii;
29#endif
30
31#if PY_VERSION_HEX >= 0x030c0000
32 PyObject* pyvalue = PyErr_GetRaisedException();
33 PyObject* pytype = pyvalue ? (PyObject*)Py_TYPE(pyvalue) : nullptr;
34 PyObject* traceback = pyvalue ? PyException_GetTraceback(pyvalue) : nullptr;
35#else
36 PyObject *pytype = nullptr, *pyvalue = nullptr, *pytrace = nullptr;
37 PyErr_Fetch(&pytype, &pyvalue, &pytrace);
38 PyObject* traceback = pytrace; // to keep the original unchanged
39 Py_XINCREF(traceback);
40#endif
41
42 if (pytype && pyvalue) {
43 const char* tname = PyExceptionClass_Name(pytype);
44 if (tname) {
45 char* dot = strrchr((char*)tname, '.');
46 if (dot)
47 tname = dot + 1;
48 fMsg += tname;
49 fMsg += ": ";
50 }
51
52 PyObject* msg = PyObject_Str(pyvalue);
53 if (msg) {
54 fMsg += PyUnicode_AsUTF8(msg);
55 Py_DECREF(msg);
56 }
57 }
58
59 std::string locName;
60 std::string locFile;
61 int locLine = 0;
62
63 while (traceback && traceback != Py_None) {
64 PyObject* frame = PyObject_GetAttrString(traceback, "tb_frame");
65 PyObject* code = PyObject_GetAttrString(frame, "f_code");
66 Py_DECREF(frame);
67
68 PyObject* filename = PyObject_GetAttrString(code, "co_filename");
69 Py_DECREF(code);
70
71 PyObject* filenameStr = PyObject_Str(filename);
72 locFile = PyUnicode_AsUTF8(filenameStr);
73 Py_DECREF(filenameStr);
74 Py_DECREF(filename);
75
76 PyObject* name = PyObject_GetAttrString(code, "co_name");
77 PyObject* nameStr = PyObject_Str(name);
78 locName = PyUnicode_AsUTF8(nameStr);
79 Py_DECREF(nameStr);
80 Py_DECREF(name);
81
82 PyObject* lineno = PyObject_GetAttrString(traceback, "tb_lineno");
83 locLine = PyLong_AsLong(lineno);
84 Py_DECREF(lineno);
85
86 if (locFile == "<string>") { // these are not that useful, skipping
87 PyObject* nextTraceback = PyObject_GetAttrString(traceback, "tb_next");
88 Py_DECREF(traceback);
89 traceback = nextTraceback;
90 continue;
91 }
92
93 break;
94 }
95
96 Py_XDECREF(traceback);
97
98#if PY_VERSION_HEX >= 0x030c0000
99 PyErr_SetRaisedException(pyvalue);
100#else
101 PyErr_Restore(pytype, pyvalue, pytrace);
102#endif
103
104 if (fMsg.empty())
105 fMsg = "python exception";
106
107 if (!locFile.empty()) {
108
109 // only keeping the filename, not the full path
110 locFile = locFile.substr(locFile.find_last_of("/\\") + 1);
111
112 fMsg += " (at " + locFile + ":" + std::to_string(locLine);
113
114 if (locName != "<module>")
115 fMsg += " in " + locName;
116
117 fMsg += ")";
118 }
119}
120
122 // destructor
123}
124
125//- public members -----------------------------------------------------------
126const char* cppjit::cpyrt::PyException::what() const noexcept {
127 // Return reason for throwing this exception: a python exception was raised.
128 return fMsg.c_str();
129}
130
132#ifdef WITH_THREAD
133 PythonGILRAII python_gil_raii;
134#endif
135 // clear Python error, to allow full error handling C++ side
136 PyErr_Clear();
137}
_object PyObject
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
char name[80]
Definition TGX11.cxx:142
~PyException() noexcept override
void clear() const noexcept
const char * what() const noexcept override
Definition API.cxx:34