is_terminator = True
def analyse_expressions(self, env):
- env.use_utility_code(restore_exception_utility_code)
+ pass
nogil_check = Node.gil_error
gil_message = "Raising exception"
def generate_execution_code(self, code):
vars = code.funcstate.exc_vars
if vars:
+ code.globalstate.use_utility_code(restore_exception_utility_code)
for varname in vars:
code.put_giveref(varname)
code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
code.putln()
code.putln(code.error_goto(self.pos))
else:
- error(self.pos, "Reraise not inside except clause")
-
+ code.globalstate.use_utility_code(
+ UtilityCode.load_cached("ReRaiseException", "Exceptions.c"))
+ code.putln("__Pyx_ReraiseException(); %s" % code.error_goto(self.pos))
class AssertStatNode(StatNode):
# assert statement
return -1;
}
+/////////////// ReRaiseException.proto ///////////////
+
+static CYTHON_INLINE void __Pyx_ReraiseException(void); /*proto*/
+
+/////////////// ReRaiseException.proto ///////////////
+
+static CYTHON_INLINE void __Pyx_ReraiseException(void) {
+ PyObject *type = NULL, *value = NULL, *tb = NULL;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ type = tstate->exc_type;
+ value = tstate->exc_value;
+ tb = tstate->exc_traceback;
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+ if (!type || type == Py_None) {
+#if !CYTHON_COMPILING_IN_CPYTHON
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(tb);
+#endif
+ PyErr_SetString(PyExc_RuntimeError,
+ "No active exception to reraise"); // message copied from Py3
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON
+ Py_INCREF(type);
+ Py_XINCREF(value);
+ Py_XINCREF(tb);
+
+#endif
+ PyErr_Restore(type, value, tb);
+ }
+}
+
/////////////// SaveResetException.proto ///////////////
static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
--- /dev/null
+
+def reraise():
+ raise
+
+def test_reraise():
+ """
+ >>> test_reraise()
+ Traceback (most recent call last):
+ ValueError: TEST
+ """
+ try:
+ raise ValueError("TEST")
+ except ValueError:
+ raise
+
+def test_reraise_indirect():
+ """
+ >>> test_reraise_indirect()
+ Traceback (most recent call last):
+ ValueError: TEST INDIRECT
+ """
+ try:
+ raise ValueError("TEST INDIRECT")
+ except ValueError:
+ reraise()
+
+def test_reraise_error():
+ """
+ >>> try: test_reraise_error()
+ ... except (RuntimeError, TypeError): pass # Py2, Py3, ...
+ ... else: print("FAILED")
+ """
+ import sys
+ sys.exc_clear()
+ raise