Qucs-S S-parameter Viewer & RF Synthesis Tools
Loading...
Searching...
No Matches
greenlet_exceptions.hpp
1#ifndef GREENLET_EXCEPTIONS_HPP
2#define GREENLET_EXCEPTIONS_HPP
3
4#define PY_SSIZE_T_CLEAN
5#include <Python.h>
6#include <stdexcept>
7#include <string>
8
9#ifdef __clang__
10# pragma clang diagnostic push
11# pragma clang diagnostic ignored "-Wunused-function"
12#endif
13
14namespace greenlet {
15
16 class PyErrOccurred : public std::runtime_error
17 {
18 public:
19
20 // CAUTION: In debug builds, may run arbitrary Python code.
21 static const PyErrOccurred
22 from_current()
23 {
24 assert(PyErr_Occurred());
25#ifndef NDEBUG
26 // This is not exception safe, and
27 // not necessarily safe in general (what if it switches?)
28 // But we only do this in debug mode, where we are in
29 // tight control of what exceptions are getting raised and
30 // can prevent those issues.
31
32 // You can't call PyObject_Str with a pending exception.
33 PyObject* typ;
34 PyObject* val;
35 PyObject* tb;
36
37 PyErr_Fetch(&typ, &val, &tb);
38 PyObject* typs = PyObject_Str(typ);
39 PyObject* vals = PyObject_Str(val ? val : typ);
40 const char* typ_msg = PyUnicode_AsUTF8(typs);
41 const char* val_msg = PyUnicode_AsUTF8(vals);
42 PyErr_Restore(typ, val, tb);
43
44 std::string msg(typ_msg);
45 msg += ": ";
46 msg += val_msg;
47 PyErrOccurred ex(msg);
48 Py_XDECREF(typs);
49 Py_XDECREF(vals);
50
51 return ex;
52#else
53 return PyErrOccurred();
54#endif
55 }
56
57 PyErrOccurred() : std::runtime_error("")
58 {
59 assert(PyErr_Occurred());
60 }
61
62 PyErrOccurred(const std::string& msg) : std::runtime_error(msg)
63 {
64 assert(PyErr_Occurred());
65 }
66
67 PyErrOccurred(PyObject* exc_kind, const char* const msg)
68 : std::runtime_error(msg)
69 {
70 PyErr_SetString(exc_kind, msg);
71 }
72
73 PyErrOccurred(PyObject* exc_kind, const std::string msg)
74 : std::runtime_error(msg)
75 {
76 // This copies the c_str, so we don't have any lifetime
77 // issues to worry about.
78 PyErr_SetString(exc_kind, msg.c_str());
79 }
80
81 PyErrOccurred(PyObject* exc_kind,
82 const std::string msg, //This is the format
83 //string; that's not
84 //usually safe!
85
86 PyObject* borrowed_obj_one, PyObject* borrowed_obj_two)
87 : std::runtime_error(msg)
88 {
89
90 //This is designed specifically for the
91 //``check_switch_allowed`` function.
92
93 // PyObject_Str and PyObject_Repr are safe to call with
94 // NULL pointers; they return the string "<NULL>" in that
95 // case.
96 // This function always returns null.
97 PyErr_Format(exc_kind,
98 msg.c_str(),
99 borrowed_obj_one, borrowed_obj_two);
100 }
101 };
102
104 {
105 public:
106 TypeError(const char* const what)
107 : PyErrOccurred(PyExc_TypeError, what)
108 {
109 }
110 TypeError(const std::string what)
111 : PyErrOccurred(PyExc_TypeError, what)
112 {
113 }
114 };
115
117 {
118 public:
119 ValueError(const char* const what)
120 : PyErrOccurred(PyExc_ValueError, what)
121 {
122 }
123 };
124
126 {
127 public:
128 AttributeError(const char* const what)
129 : PyErrOccurred(PyExc_AttributeError, what)
130 {
131 }
132 };
133
138 class PyFatalError : public std::runtime_error
139 {
140 public:
141 PyFatalError(const char* const msg)
142 : std::runtime_error(msg)
143 {
144 Py_FatalError(msg);
145 }
146 };
147
148 static inline PyObject*
149 Require(PyObject* p, const std::string& msg="")
150 {
151 if (!p) {
152 throw PyErrOccurred(msg);
153 }
154 return p;
155 };
156
157 static inline void
158 Require(const int retval)
159 {
160 if (retval < 0) {
161 throw PyErrOccurred();
162 }
163 };
164
165
166};
167#ifdef __clang__
168# pragma clang diagnostic pop
169#endif
170
171#endif
Definition greenlet_exceptions.hpp:126
Definition greenlet_exceptions.hpp:17
Definition greenlet_exceptions.hpp:139
Definition greenlet_exceptions.hpp:104
Definition greenlet_exceptions.hpp:117
Definition __init__.py:1