12#include "nuitka/prelude.h"
15void SET_CURRENT_EXCEPTION_TYPE0_FORMAT1(PyObject *exception_type,
char const *format,
char const *value) {
16 PyErr_Format(exception_type, format, value);
19void SET_CURRENT_EXCEPTION_TYPE0_FORMAT2(PyObject *exception_type,
char const *format,
char const *value1,
21 PyErr_Format(exception_type, format, value1, value2);
24void SET_CURRENT_EXCEPTION_TYPE0_FORMAT3(PyObject *exception_type,
char const *format,
char const *value1,
25 char const *value2,
char const *value3) {
26 PyErr_Format(exception_type, format, value1, value2, value3);
29void SET_CURRENT_EXCEPTION_TYPE_COMPLAINT(
char const *format, PyObject *mistyped) {
30 SET_CURRENT_EXCEPTION_TYPE0_FORMAT1(PyExc_TypeError, format, Py_TYPE(mistyped)->tp_name);
33static char const *TYPE_NAME_DESC(PyObject *type) {
34 if (type == Py_None) {
37 return Py_TYPE(type)->tp_name;
41void SET_CURRENT_EXCEPTION_TYPE_COMPLAINT_NICE(
char const *format, PyObject *mistyped) {
42 SET_CURRENT_EXCEPTION_TYPE0_FORMAT1(PyExc_TypeError, format, TYPE_NAME_DESC(mistyped));
46 PyObject *variable_name) {
47#if PYTHON_VERSION < 0x300
48 char const *message =
"local variable '%s' referenced before assignment";
49 PyObject *exception_value = Nuitka_String_FromFormat(message, Nuitka_String_AsString_Unchecked(variable_name));
50#elif PYTHON_VERSION < 0x3b0
51 char const *message =
"local variable '%U' referenced before assignment";
52 PyObject *exception_value = Nuitka_String_FromFormat(message, variable_name);
54 char const *message =
"cannot access local variable '%U' where it is not associated with a value";
55 PyObject *exception_value = Nuitka_String_FromFormat(message, variable_name);
58 CHECK_OBJECT(exception_value);
59 SET_EXCEPTION_PRESERVATION_STATE_FROM_TYPE0_VALUE1(tstate, exception_state, PyExc_UnboundLocalError,
64 PyObject *variable_name) {
65#if PYTHON_VERSION < 0x3b0
66 char const *message =
"free variable '%s' referenced before assignment in enclosing scope";
68 char const *message =
"cannot access free variable '%s' where it is not associated with a value in enclosing scope";
71 PyObject *exception_value = Nuitka_String_FromFormat(message, Nuitka_String_AsString_Unchecked(variable_name));
72 CHECK_OBJECT(exception_value);
74 SET_EXCEPTION_PRESERVATION_STATE_FROM_TYPE0_VALUE1(tstate, exception_state, PyExc_NameError, exception_value);
77static PyObject *_Nuitka_Err_CreateException(PyThreadState *tstate, PyObject *exception_type, PyObject *value) {
80 if (value == NULL || value == Py_None) {
81 exc = CALL_FUNCTION_NO_ARGS(tstate, exception_type);
82 }
else if (PyTuple_Check(value)) {
83 exc = CALL_FUNCTION_WITH_POS_ARGS(tstate, exception_type, value);
85 exc = CALL_FUNCTION_WITH_SINGLE_ARG(tstate, exception_type, value);
88 if (exc != NULL && !PyExceptionInstance_Check(exc)) {
89 PyErr_Format(PyExc_TypeError,
90 "calling %s should have returned an instance of "
91 "BaseException, not %s",
92 GET_CALLABLE_NAME(exception_type), Py_TYPE(exc)->tp_name);
101PyObject *MAKE_EXCEPTION_WITH_VALUE(PyThreadState *tstate, PyObject *exception_type, PyObject *value) {
102 return _Nuitka_Err_CreateException(tstate, exception_type, value);
109#if PYTHON_VERSION >= 0x3d0
111void Nuitka_Err_NormalizeException(PyThreadState *tstate, PyObject **exc, PyObject **val, PyTracebackObject **tb) {
112 int recursion_depth = 0;
113 tstate->recursion_headroom++;
115 PyObject *type, *value;
116 PyTracebackObject *initial_tb;
122 tstate->recursion_headroom--;
129 Py_INCREF_IMMORTAL(Py_None);
133 if (PyExceptionClass_Check(type)) {
134 PyObject *instance_class = NULL;
138 if (PyExceptionInstance_Check(value)) {
139 instance_class = PyExceptionInstance_Class(value);
141 is_subclass = PyObject_IsSubclass(instance_class, type);
142 if (is_subclass < 0) {
148 PyObject *fixed_value = _Nuitka_Err_CreateException(tstate, type, value);
150 if (fixed_value == NULL) {
154 Py_SETREF(value, fixed_value);
155 }
else if (instance_class != type) {
156 Py_SETREF(type, Py_NewRef(instance_class));
161 tstate->recursion_headroom--;
168 if (recursion_depth == 32) {
169 _PyErr_SetString(tstate, PyExc_RecursionError,
170 "maximum recursion depth exceeded "
171 "while normalizing an exception");
177 FETCH_ERROR_OCCURRED_STATE(tstate, &exception_state);
179 ASSIGN_ARGS_FROM_EXCEPTION_PRESERVATION_STATE(&exception_state, exc, val, tb);
180 RELEASE_ERROR_OCCURRED_STATE(&exception_state);
182 assert(*exc != NULL);
183 if (initial_tb != NULL) {
187 Py_DECREF(initial_tb);
189 if (recursion_depth >= 32 + 2) {
190 if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) {
191 Py_FatalError(
"Cannot recover from MemoryErrors "
192 "while normalizing exceptions.");
194 Py_FatalError(
"Cannot recover from the recursive normalization "
201void Nuitka_Err_NormalizeException(PyThreadState *tstate, PyObject **exc, PyObject **val, PyTracebackObject **tb) {
202 PyObject *type = *exc;
205 assert(type != NULL && type != Py_None);
207 PyObject *value = *val;
212 Py_INCREF_IMMORTAL(value);
216 if (PyExceptionClass_Check(type)) {
217 PyObject *instance_class = NULL;
221 if (PyExceptionInstance_Check(value)) {
222 instance_class = PyExceptionInstance_Class(value);
224 is_subclass = PyObject_IsSubclass(instance_class, type);
226 if (is_subclass < 0) {
234 PyObject *fixed_value = _Nuitka_Err_CreateException(tstate, type, value);
236 if (unlikely(fixed_value == NULL)) {
242 }
else if (instance_class != type) {
244 Py_INCREF(instance_class);
247 type = instance_class;
260 PyTracebackObject *initial_tb = *tb;
263 FETCH_ERROR_OCCURRED_STATE(tstate, &exception_state);
265 ASSIGN_ARGS_FROM_EXCEPTION_PRESERVATION_STATE(&exception_state, exc, val, tb);
266 RELEASE_ERROR_OCCURRED_STATE(&exception_state);
268 if (initial_tb != NULL) {
272 Py_DECREF(initial_tb);
276#if PYTHON_VERSION >= 0x380
277 _PyErr_NormalizeException(tstate, exc, val, (PyObject **)tb);
279 PyErr_NormalizeException(exc, val, (PyObject **)tb);
Definition exceptions.h:712