Enforce the standard order of try
elements
This commit is contained in:
parent
0d2749d5cd
commit
81d89c9d12
4
NEWS
4
NEWS
@ -8,6 +8,10 @@ Changes from 0.12.1
|
|||||||
* `defreader` has been renamed to `defsharp`; what were previously called
|
* `defreader` has been renamed to `defsharp`; what were previously called
|
||||||
"reader macros", which were never true reader macros, are now called
|
"reader macros", which were never true reader macros, are now called
|
||||||
"sharp macros"
|
"sharp macros"
|
||||||
|
* `try` now enforces the usual Python order for its elements (`else` must
|
||||||
|
follow all `except`s, and `finally` must come last). This is only a
|
||||||
|
syntactic change; the elements were already run in Python order even when
|
||||||
|
defined out of order.
|
||||||
* Importing or executing a Hy file automatically byte-compiles it, or loads
|
* Importing or executing a Hy file automatically byte-compiles it, or loads
|
||||||
a byte-compiled version if it exists and is up to date. This brings big
|
a byte-compiled version if it exists and is up to date. This brings big
|
||||||
speed boosts, even for one-liners, because Hy no longer needs to recompile
|
speed boosts, even for one-liners, because Hy no longer needs to recompile
|
||||||
|
@ -793,30 +793,29 @@ class HyASTCompiler(object):
|
|||||||
|
|
||||||
body = body.stmts
|
body = body.stmts
|
||||||
|
|
||||||
orelse = []
|
if not all(expr):
|
||||||
finalbody = []
|
raise HyTypeError(expr, "Empty list not allowed in `try'")
|
||||||
handlers = []
|
|
||||||
handler_results = Result()
|
handler_results = Result()
|
||||||
|
handlers = []
|
||||||
for e in expr:
|
while expr and expr[0][0] == HySymbol("except"):
|
||||||
if not len(e):
|
handler_results += self._compile_catch_expression(expr.pop(0),
|
||||||
raise HyTypeError(e, "Empty list not allowed in `try'")
|
name)
|
||||||
|
|
||||||
if e[0] == HySymbol("except"):
|
|
||||||
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"):
|
orelse = []
|
||||||
orelse = self.try_except_helper(e, HySymbol("else"), orelse)
|
if expr and expr[0][0] == HySymbol("else"):
|
||||||
elif e[0] == HySymbol("finally"):
|
orelse = self.try_except_helper(expr.pop(0), HySymbol("else"))
|
||||||
finalbody = self.try_except_helper(e, HySymbol("finally"),
|
finalbody = []
|
||||||
finalbody)
|
if expr and expr[0][0] == HySymbol("finally"):
|
||||||
else:
|
finalbody = self.try_except_helper(expr.pop(0), HySymbol("finally"))
|
||||||
raise HyTypeError(e, "Unknown expression in `try'")
|
if expr:
|
||||||
|
if expr[0][0] in ("except", "else", "finally"):
|
||||||
|
raise HyTypeError(expr, "Incorrect order of `except'/`else'/`finally' in `try'")
|
||||||
|
raise HyTypeError(expr, "Unknown expression in `try'")
|
||||||
|
|
||||||
# Using (else) without (except) is verboten!
|
# Using (else) without (except) is verboten!
|
||||||
if orelse and not handlers:
|
if orelse and not handlers:
|
||||||
raise HyTypeError(
|
raise HyTypeError(
|
||||||
e,
|
expr,
|
||||||
"`try' cannot have `else' without `except'")
|
"`try' cannot have `else' without `except'")
|
||||||
|
|
||||||
# (try) or (try BODY)
|
# (try) or (try BODY)
|
||||||
@ -868,16 +867,10 @@ class HyASTCompiler(object):
|
|||||||
body=body,
|
body=body,
|
||||||
orelse=orelse) + returnable
|
orelse=orelse) + returnable
|
||||||
|
|
||||||
def try_except_helper(self, hy_obj, symbol, accumulated):
|
def try_except_helper(self, hy_obj, symbol):
|
||||||
if accumulated:
|
x = self._compile_branch(hy_obj[1:])
|
||||||
raise HyTypeError(
|
x += x.expr_as_stmt()
|
||||||
hy_obj,
|
return x.stmts
|
||||||
"`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")
|
||||||
def magic_internal_form(self, expr):
|
def magic_internal_form(self, expr):
|
||||||
|
@ -116,12 +116,11 @@ def test_ast_good_try():
|
|||||||
can_compile("(try)")
|
can_compile("(try)")
|
||||||
can_compile("(try 1)")
|
can_compile("(try 1)")
|
||||||
can_compile("(try 1 (except) (else 1))")
|
can_compile("(try 1 (except) (else 1))")
|
||||||
can_compile("(try 1 (else 1) (except))")
|
|
||||||
can_compile("(try 1 (finally 1) (except))")
|
|
||||||
can_compile("(try 1 (finally 1))")
|
can_compile("(try 1 (finally 1))")
|
||||||
can_compile("(try 1 (except) (finally 1))")
|
can_compile("(try 1 (except) (finally 1))")
|
||||||
can_compile("(try 1 (except) (finally 1) (else 1))")
|
can_compile("(try 1 (except [x]) (except [y]) (finally 1))")
|
||||||
can_compile("(try 1 (except) (else 1) (finally 1))")
|
can_compile("(try 1 (except) (else 1) (finally 1))")
|
||||||
|
can_compile("(try 1 (except [x]) (except [y]) (else 1) (finally 1))")
|
||||||
|
|
||||||
|
|
||||||
def test_ast_bad_try():
|
def test_ast_bad_try():
|
||||||
@ -130,6 +129,9 @@ def test_ast_bad_try():
|
|||||||
cant_compile("(try 1 bla bla)")
|
cant_compile("(try 1 bla bla)")
|
||||||
cant_compile("(try (do) (else 1) (else 2))")
|
cant_compile("(try (do) (else 1) (else 2))")
|
||||||
cant_compile("(try 1 (else 1))")
|
cant_compile("(try 1 (else 1))")
|
||||||
|
cant_compile("(try 1 (else 1) (except))")
|
||||||
|
cant_compile("(try 1 (finally 1) (except))")
|
||||||
|
cant_compile("(try 1 (except) (finally 1) (else 1))")
|
||||||
|
|
||||||
|
|
||||||
def test_ast_good_except():
|
def test_ast_good_except():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user