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> * kirbyfan64 <kirbyfan64@users.noreply.github.com>
* Brendan Curran-Johnson <brendan@bcjbcj.ca> * Brendan Curran-Johnson <brendan@bcjbcj.ca>
* Ivan Kozik <ivan@ludios.org> * 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) handler_results += self._compile_catch_expression(e, name)
handlers.append(handler_results.stmts.pop()) handlers.append(handler_results.stmts.pop())
elif e[0] == HySymbol("else"): elif e[0] == HySymbol("else"):
if orelse: orelse = self.try_except_helper(e, HySymbol("else"), 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
elif e[0] == HySymbol("finally"): elif e[0] == HySymbol("finally"):
if finalbody: finalbody = self.try_except_helper(e, HySymbol("finally"),
raise HyTypeError( finalbody)
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
else: else:
raise HyTypeError(e, "Unknown expression in `try'") raise HyTypeError(e, "Unknown expression in `try'")
@ -768,8 +753,8 @@ class HyASTCompiler(object):
col_offset=expr.start_column, col_offset=expr.start_column,
type=None, type=None,
name=None, name=None,
body=[ast.Pass(lineno=expr.start_line, body=[ast.Raise(lineno=expr.start_line,
col_offset=expr.start_column)])] col_offset=expr.start_column)])]
ret = handler_results ret = handler_results
@ -809,6 +794,17 @@ class HyASTCompiler(object):
body=body, body=body,
orelse=orelse) + returnable 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("except")
@builds("catch") @builds("catch")
def magic_internal_form(self, expr): def magic_internal_form(self, expr):

View File

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