Commit f5f34c7b authored by Stefan Behnel's avatar Stefan Behnel

implement bare 'raise' statement outside of except blocks

parent 9185e2ca
...@@ -5006,7 +5006,7 @@ class ReraiseStatNode(StatNode): ...@@ -5006,7 +5006,7 @@ class ReraiseStatNode(StatNode):
is_terminator = True is_terminator = True
def analyse_expressions(self, env): def analyse_expressions(self, env):
env.use_utility_code(restore_exception_utility_code) pass
nogil_check = Node.gil_error nogil_check = Node.gil_error
gil_message = "Raising exception" gil_message = "Raising exception"
...@@ -5014,6 +5014,7 @@ class ReraiseStatNode(StatNode): ...@@ -5014,6 +5014,7 @@ class ReraiseStatNode(StatNode):
def generate_execution_code(self, code): def generate_execution_code(self, code):
vars = code.funcstate.exc_vars vars = code.funcstate.exc_vars
if vars: if vars:
code.globalstate.use_utility_code(restore_exception_utility_code)
for varname in vars: for varname in vars:
code.put_giveref(varname) code.put_giveref(varname)
code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars)) code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
...@@ -5022,8 +5023,9 @@ class ReraiseStatNode(StatNode): ...@@ -5022,8 +5023,9 @@ class ReraiseStatNode(StatNode):
code.putln() code.putln()
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
else: 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): class AssertStatNode(StatNode):
# assert statement # assert statement
......
...@@ -255,6 +255,41 @@ bad: ...@@ -255,6 +255,41 @@ bad:
return -1; 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 /////////////// /////////////// SaveResetException.proto ///////////////
static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
......
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment