From 3f9ae9122e077d0d2b5350fffe562262c75443fb Mon Sep 17 00:00:00 2001 From: Allison Kaptur Date: Tue, 15 Apr 2014 17:27:54 -0400 Subject: [PATCH] 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. --- AUTHORS | 1 + hy/compiler.py | 36 +++++++++++++++------------------- tests/native_tests/language.hy | 5 +++++ 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/AUTHORS b/AUTHORS index e5b61cf..847740c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -45,3 +45,4 @@ * kirbyfan64 * Brendan Curran-Johnson * Ivan Kozik +* Allison Kaptur diff --git a/hy/compiler.py b/hy/compiler.py index 2122ea9..032a49a 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -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): diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index ccf81c5..6995d5c 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -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"