Raise exceptions when no handlers are provided.

Also small DRYing in try handling.

Previously, writing a bare (try (foo)) would invoke Pokemon
exception catching (gotta catch 'em all) instead of the correct
behavior, which is to raise the exception if no handler is provided.

Note that this is a cute feature of Hy, as a `try` with no `except`
is a syntax error.  We avoid the syntax error here because we don't
use Python's compiler, which is the only thing that can throw
Syntax Errors.  :D

Fixes #555.
This commit is contained in:
Allison Kaptur 2014-04-15 17:27:54 -04:00 committed by Berker Peksag
parent 4f8ab5af8c
commit 3f9ae9122e
3 changed files with 22 additions and 20 deletions

View File

@ -45,3 +45,4 @@
* kirbyfan64 <kirbyfan64@users.noreply.github.com>
* Brendan Curran-Johnson <brendan@bcjbcj.ca>
* Ivan Kozik <ivan@ludios.org>
* Allison Kaptur <allison.kaptur@gmail.com>

View File

@ -732,25 +732,10 @@ class HyASTCompiler(object):
handler_results += self._compile_catch_expression(e, name)
handlers.append(handler_results.stmts.pop())
elif e[0] == HySymbol("else"):
if orelse:
raise HyTypeError(
e,
"`try' cannot have more than one `else'")
else:
orelse = self._compile_branch(e[1:])
# XXX tempvar magic
orelse += orelse.expr_as_stmt()
orelse = orelse.stmts
orelse = self.try_except_helper(e, HySymbol("else"), orelse)
elif e[0] == HySymbol("finally"):
if finalbody:
raise HyTypeError(
e,
"`try' cannot have more than one `finally'")
else:
finalbody = self._compile_branch(e[1:])
# XXX tempvar magic
finalbody += finalbody.expr_as_stmt()
finalbody = finalbody.stmts
finalbody = self.try_except_helper(e, HySymbol("finally"),
finalbody)
else:
raise HyTypeError(e, "Unknown expression in `try'")
@ -768,8 +753,8 @@ class HyASTCompiler(object):
col_offset=expr.start_column,
type=None,
name=None,
body=[ast.Pass(lineno=expr.start_line,
col_offset=expr.start_column)])]
body=[ast.Raise(lineno=expr.start_line,
col_offset=expr.start_column)])]
ret = handler_results
@ -809,6 +794,17 @@ class HyASTCompiler(object):
body=body,
orelse=orelse) + returnable
def try_except_helper(self, hy_obj, symbol, accumulated):
if accumulated:
raise HyTypeError(
hy_obj,
"`try' cannot have more than one `%s'" % symbol)
else:
accumulated = self._compile_branch(hy_obj[1:])
accumulated += accumulated.expr_as_stmt()
accumulated = accumulated.stmts
return accumulated
@builds("except")
@builds("catch")
def magic_internal_form(self, expr):

View File

@ -236,6 +236,11 @@
"NATIVE: test do"
(do))
(defn test-bare-try [] (try
(try (raise ValueError))
(except [ValueError])
(else (assert false))))
(defn test-exceptions []
"NATIVE: test Exceptions"