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 "CPyCppyy.h"
6#define CPYCPPYY_INTERNAL 1
8#undef CPYCPPYY_INTERNAL
9
10
11//______________________________________________________________________________
12// C++ exception for throwing python exceptions
13// ============================================
14// Purpose: A C++ exception class for throwing python exceptions
15// through C++ code.
16// Created: Apr, 2004, Scott Snyder, from the version in D0's python_util.
17//
18// Note: Don't be tempted to declare the virtual functions defined here
19// as inline.
20// If you do, you may not be able to properly throw these
21// exceptions across shared libraries.
22
23
24//- constructors/destructor --------------------------------------------------
26{
27#ifdef WITH_THREAD
28 PyGILState_STATE state = PyGILState_Ensure();
29#endif
30
31 PyObject* pytype = nullptr, *pyvalue = nullptr, *pytrace = nullptr;
32 PyErr_Fetch(&pytype, &pyvalue, &pytrace);
33 if (pytype && pyvalue) {
34 const char* tname = PyExceptionClass_Name(pytype);
35 if (tname) {
36 char* dot = strrchr((char*)tname, '.');
37 if (dot) tname = dot+1;
38 fMsg += tname;
39 fMsg += ": ";
40 }
41
42 PyObject* msg = PyObject_Str(pyvalue);
43 if (msg) {
45 Py_DECREF(msg);
46 }
47 }
48
49 PyObject* traceback = pytrace; // to keep the original unchanged
50 Py_XINCREF(traceback);
51
52 std::string locName;
53 std::string locFile;
54 int locLine = 0;
55
56 while (traceback && traceback != Py_None) {
57 PyObject* frame = PyObject_GetAttrString(traceback, "tb_frame");
58 PyObject* code = PyObject_GetAttrString(frame, "f_code");
59 Py_DECREF(frame);
60
61 PyObject* filename = PyObject_GetAttrString(code, "co_filename");
62 Py_DECREF(code);
63
64 PyObject* filenameStr = PyObject_Str(filename);
65 locFile = CPyCppyy_PyText_AsString(filenameStr);
66 Py_DECREF(filenameStr);
67 Py_DECREF(filename);
68
69 PyObject* name = PyObject_GetAttrString(code, "co_name");
70 PyObject* nameStr = PyObject_Str(name);
71 locName = CPyCppyy_PyText_AsString(nameStr);
72 Py_DECREF(nameStr);
73 Py_DECREF(name);
74
75 PyObject* lineno = PyObject_GetAttrString(traceback, "tb_lineno");
76 locLine = PyLong_AsLong(lineno);
77 Py_DECREF(lineno);
78
79 if (locFile == "<string>") { // these are not that useful, skipping
80 PyObject* nextTraceback = PyObject_GetAttrString(traceback, "tb_next");
81 Py_DECREF(traceback);
82 traceback = nextTraceback;
83 continue;
84 }
85
86 break;
87 }
88
89 Py_XDECREF(traceback);
90
91 PyErr_Restore(pytype, pyvalue, pytrace);
92
93 if (fMsg.empty())
94 fMsg = "python exception";
95
96 if (!locFile.empty()) {
97
98 // only keeping the filename, not the full path
99 locFile = locFile.substr(locFile.find_last_of("/\\") + 1);
100
101 fMsg += " (at " + locFile + ":" + std::to_string(locLine);
102
103 if (locName != "<module>")
104 fMsg += " in " + locName;
105
106 fMsg += ")";
107 }
108
109#ifdef WITH_THREAD
110 PyGILState_Release(state);
111#endif
112}
113
115{
116// destructor
117}
118
119
120//- public members -----------------------------------------------------------
121const char* CPyCppyy::PyException::what() const noexcept
122{
123// Return reason for throwing this exception: a python exception was raised.
124 return fMsg.c_str();
125}
126
127void CPyCppyy::PyException::clear() const noexcept
128{
129// clear Python error, to allow full error handling C++ side
130 PyErr_Clear();
131}
#define CPyCppyy_PyText_AsString
Definition CPyCppyy.h:76
_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:110
virtual const char * what() const noexcept
void clear() const noexcept
virtual ~PyException() noexcept