Commit 1955a53e authored by Stefan Behnel's avatar Stefan Behnel

implement another try-finally corner case (the Py3 way only for now!):...

implement another try-finally corner case (the Py3 way only for now!): reraising a fresh exception in the finally clause
parent 4a25f1c1
...@@ -83,6 +83,8 @@ Bugs fixed ...@@ -83,6 +83,8 @@ Bugs fixed
* The PEP 3155 ``__qualname__`` was incorrect for nested classes and * The PEP 3155 ``__qualname__`` was incorrect for nested classes and
inner classes/functions declared as ``global``. inner classes/functions declared as ``global``.
* Several corner cases in the try-finally statement were fixed.
* The metaclass of a Python class was not inherited from its parent * The metaclass of a Python class was not inherited from its parent
class(es). It is now extracted from the list of base classes if not class(es). It is now extracted from the list of base classes if not
provided explicitly using the Py3 ``metaclass`` keyword argument. provided explicitly using the Py3 ``metaclass`` keyword argument.
......
...@@ -5275,8 +5275,10 @@ class ReraiseStatNode(StatNode): ...@@ -5275,8 +5275,10 @@ class ReraiseStatNode(StatNode):
vars = code.funcstate.exc_vars vars = code.funcstate.exc_vars
if vars: if vars:
code.globalstate.use_utility_code(restore_exception_utility_code) code.globalstate.use_utility_code(restore_exception_utility_code)
for varname in vars: code.put_giveref(vars[0])
code.put_giveref(varname) code.put_giveref(vars[1])
# fresh exceptions may not have a traceback yet (-> finally!)
code.put_xgiveref(vars[2])
code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars)) code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
for varname in vars: for varname in vars:
code.put("%s = 0; " % varname) code.put("%s = 0; " % varname)
...@@ -6506,7 +6508,10 @@ class TryFinallyStatNode(StatNode): ...@@ -6506,7 +6508,10 @@ class TryFinallyStatNode(StatNode):
finally_old_labels = code.all_new_labels() finally_old_labels = code.all_new_labels()
code.putln('{') code.putln('{')
old_exc_vars = code.funcstate.exc_vars
code.funcstate.exc_vars = exc_vars[:3]
fresh_finally_clause().generate_execution_code(code) fresh_finally_clause().generate_execution_code(code)
code.funcstate.exc_vars = old_exc_vars
code.putln('}') code.putln('}')
if needs_success_cleanup: if needs_success_cleanup:
......
...@@ -73,6 +73,31 @@ def except_finally_reraise(): ...@@ -73,6 +73,31 @@ def except_finally_reraise():
raise raise
def except_finally_reraise_new():
"""
>>> def py_check():
... try: raise ValueError
... except ValueError:
... try: raise TypeError
... finally:
... raise
>>> try: py_check()
... except ValueError: assert not IS_PY3
... except TypeError: assert IS_PY3
... else: assert False
>>> try: except_finally_reraise_new()
... except TypeError: pass # currently only Py3 semantics implemented
... else: assert False
"""
try:
raise ValueError
except ValueError:
try:
raise TypeError
finally:
raise
def finally_exception_check_return(): def finally_exception_check_return():
""" """
>>> if not IS_PY3: >>> if not IS_PY3:
......
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