From eda78eb81c27da7b473049d69071d7a4b866cb69 Mon Sep 17 00:00:00 2001 From: Rob Day Date: Sun, 17 Sep 2017 20:52:42 +0100 Subject: [PATCH] Allow multiple expressions in a try --- NEWS | 1 + hy/compiler.py | 10 ++++++++-- tests/native_tests/language.hy | 26 +++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 4842f24..1ab7dc8 100644 --- a/NEWS +++ b/NEWS @@ -51,6 +51,7 @@ Changes from 0.13.0 a for loop * `else` clauses in `for` and `while` are recognized more reliably * Argument destructuring no longer interferes with function docstrings. + * Multiple expressions are now allowed in `try` [ Misc. Improvements ] * `read`, `read_str`, and `eval` are exposed and documented as top-level diff --git a/hy/compiler.py b/hy/compiler.py index ccd28e4..9fe6265 100755 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -843,8 +843,14 @@ class HyASTCompiler(object): expr = copy.deepcopy(expr) expr.pop(0) # try - # (try something…) - body = self.compile(expr.pop(0) if expr else []) + # (try something somethingelse…) + body = Result() + # Check against HyExpression and HySymbol to avoid incorrectly + # matching [except ...] or ("except" ...) + while expr and not (isinstance(expr[0], HyExpression) + and isinstance(expr[0][0], HySymbol) + and expr[0][0] in ("except", "else", "finally")): + body += self.compile(expr.pop(0)) var = self.get_anon_var() name = asty.Name(expr, id=ast_str(var), ctx=ast.Store()) diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index 42f27cb..703e083 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -515,10 +515,16 @@ (try (do) (except [IOError]) (except)) + ; test that multiple expressions in a try get evaluated + (setv value 0) + (try (+= value 1) (+= value 2) (except [IOError]) (except)) + (assert (= value 3)) + ;; Test correct (raise) (setv passed False) (try (try + (do) (raise IndexError) (except [IndexError] (raise))) (except [IndexError] @@ -650,7 +656,25 @@ (setv x 45)) (else (setv x 44))) (except)) - (assert (= x 0))) + (assert (= x 0)) + + ; test that [except ...] and ("except" ...) aren't treated like (except ...), + ; and that the code there is evaluated normally + (setv x 0) + (try + (+= x 1) + ("except" [IOError] (+= x 1)) + (except)) + + (assert (= x 2)) + + (setv x 0) + (try + (+= x 1) + [except [IOError] (+= x 1)] + (except)) + + (assert (= x 2))) (defn test-earmuffs [] "NATIVE: Test earmuffs"