Merge branch 'jd/catch' of git://github.com/jd/hy into pr-73
This commit is contained in:
commit
70fd991ef1
@ -1,4 +1,7 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
#
|
||||||
# Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>
|
# Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>
|
||||||
|
# Copyright (c) 2013 Julien Danjou <julien@danjou.info>
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
# copy of this software and associated documentation files (the "Software"),
|
# copy of this software and associated documentation files (the "Software"),
|
||||||
@ -191,29 +194,77 @@ class HyASTCompiler(object):
|
|||||||
orelse=[])
|
orelse=[])
|
||||||
|
|
||||||
@builds("catch")
|
@builds("catch")
|
||||||
@checkargs(min=2)
|
|
||||||
def compile_catch_expression(self, expr):
|
def compile_catch_expression(self, expr):
|
||||||
expr.pop(0) # catch
|
expr.pop(0) # catch
|
||||||
_type = self.compile(expr.pop(0))
|
|
||||||
name = expr.pop(0)
|
|
||||||
|
|
||||||
if sys.version_info[0] >= 3:
|
try:
|
||||||
# Python3 features a change where the Exception handler
|
exceptions = expr.pop(0)
|
||||||
# moved the name from a Name() to a pure Python String type.
|
except IndexError:
|
||||||
#
|
exceptions = []
|
||||||
# We'll just make sure it's a pure "string", and let it work
|
# exceptions catch should be either:
|
||||||
# it's magic.
|
# [[list of exceptions]]
|
||||||
name = ast_str(name)
|
# or
|
||||||
|
# [variable [list of exceptions]]
|
||||||
|
# or
|
||||||
|
# [variable exception]
|
||||||
|
# or
|
||||||
|
# [exception]
|
||||||
|
# or
|
||||||
|
# []
|
||||||
|
if len(exceptions) > 2:
|
||||||
|
raise TypeError("`catch' exceptions list is too long")
|
||||||
|
|
||||||
|
# [variable [list of exceptions]]
|
||||||
|
# let's pop variable and use it as name
|
||||||
|
if len(exceptions) == 2:
|
||||||
|
name = exceptions.pop(0)
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
# Python3 features a change where the Exception handler
|
||||||
|
# moved the name from a Name() to a pure Python String type.
|
||||||
|
#
|
||||||
|
# We'll just make sure it's a pure "string", and let it work
|
||||||
|
# it's magic.
|
||||||
|
name = ast_str(name)
|
||||||
|
else:
|
||||||
|
# Python2 requires an ast.Name, set to ctx Store.
|
||||||
|
name = self._storeize(self.compile(name))
|
||||||
else:
|
else:
|
||||||
# Python2 requires an ast.Name, set to ctx Store.
|
name = None
|
||||||
name = self._storeize(self.compile(name))
|
|
||||||
|
try:
|
||||||
|
exceptions_list = exceptions.pop(0)
|
||||||
|
except IndexError:
|
||||||
|
exceptions_list = []
|
||||||
|
|
||||||
|
if isinstance(exceptions_list, list):
|
||||||
|
if len(exceptions_list):
|
||||||
|
# [FooBar BarFoo] → catch Foobar and BarFoo exceptions
|
||||||
|
_type = ast.Tuple(elts=[self.compile(x)
|
||||||
|
for x in exceptions_list],
|
||||||
|
lineno=expr.start_line,
|
||||||
|
col_offset=expr.start_column,
|
||||||
|
ctx=ast.Load())
|
||||||
|
else:
|
||||||
|
# [] → all exceptions catched
|
||||||
|
_type = None
|
||||||
|
elif isinstance(exceptions_list, HySymbol):
|
||||||
|
_type = self.compile(exceptions_list)
|
||||||
|
else:
|
||||||
|
raise TypeError("`catch' needs a valid exception list to catch")
|
||||||
|
|
||||||
|
if len(expr) == 0:
|
||||||
|
# No body
|
||||||
|
body = [ast.Pass(lineno=expr.start_line,
|
||||||
|
col_offset=expr.start_column)]
|
||||||
|
else:
|
||||||
|
body = self._code_branch([self.compile(x) for x in expr])
|
||||||
|
|
||||||
return ast.ExceptHandler(
|
return ast.ExceptHandler(
|
||||||
lineno=expr.start_line,
|
lineno=expr.start_line,
|
||||||
col_offset=expr.start_column,
|
col_offset=expr.start_column,
|
||||||
type=_type,
|
type=_type,
|
||||||
name=name,
|
name=name,
|
||||||
body=self._code_branch([self.compile(x) for x in expr]))
|
body=body)
|
||||||
|
|
||||||
def _code_branch(self, branch):
|
def _code_branch(self, branch):
|
||||||
if isinstance(branch, list):
|
if isinstance(branch, list):
|
||||||
|
@ -116,13 +116,20 @@ def test_ast_bad_try():
|
|||||||
|
|
||||||
def test_ast_good_catch():
|
def test_ast_good_catch():
|
||||||
"Make sure AST can compile valid catch"
|
"Make sure AST can compile valid catch"
|
||||||
hy_compile(tokenize("(catch 1 2)"))
|
hy_compile(tokenize("(catch)"))
|
||||||
|
hy_compile(tokenize("(catch [])"))
|
||||||
|
hy_compile(tokenize("(catch [Foobar])"))
|
||||||
|
# hy_compile(tokenize("(catch [[]])"))
|
||||||
|
# hy_compile(tokenize("(catch [x FooBar])"))
|
||||||
|
# hy_compile(tokenize("(catch [x [FooBar BarFoo]])"))
|
||||||
|
# hy_compile(tokenize("(catch [x [FooBar BarFoo]])"))
|
||||||
|
|
||||||
|
|
||||||
def test_ast_bad_catch():
|
def test_ast_bad_catch():
|
||||||
"Make sure AST can't compile invalid catch"
|
"Make sure AST can't compile invalid catch"
|
||||||
cant_compile("(catch)")
|
|
||||||
cant_compile("(catch 1)")
|
cant_compile("(catch 1)")
|
||||||
|
cant_compile("(catch [1 3])")
|
||||||
|
cant_compile("(catch [x [FooBar] BarBar]])")
|
||||||
|
|
||||||
|
|
||||||
def test_ast_good_assert():
|
def test_ast_good_assert():
|
||||||
|
@ -164,8 +164,56 @@
|
|||||||
"NATIVE: test Exceptions"
|
"NATIVE: test Exceptions"
|
||||||
(try
|
(try
|
||||||
(throw (KeyError))
|
(throw (KeyError))
|
||||||
(catch IOError e (assert (= 2 1)))
|
(catch [[IOError]] (assert false))
|
||||||
(catch KeyError e (+ 1 1) (assert (= 1 1)))))
|
(catch [e [KeyError]] (assert e)))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(get [1] 3)
|
||||||
|
(catch [IndexError] (assert true))
|
||||||
|
(catch [IndexError] (pass)))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(print foobar42ofthebaz)
|
||||||
|
(catch [IndexError] (assert false))
|
||||||
|
(catch [NameError] (pass)))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(get [1] 3)
|
||||||
|
(catch [e IndexError] (assert (isinstance e IndexError))))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(get [1] 3)
|
||||||
|
(catch [e [IndexError NameError]] (assert (isinstance e IndexError))))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(print foobar42ofthebaz)
|
||||||
|
(catch [e [IndexError NameError]] (assert (isinstance e NameError))))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(print foobar42)
|
||||||
|
(catch [[IndexError NameError]] (pass)))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(get [1] 3)
|
||||||
|
(catch [[IndexError NameError]] (pass)))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(print foobar42ofthebaz)
|
||||||
|
(catch))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(print foobar42ofthebaz)
|
||||||
|
(catch []))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(print foobar42ofthebaz)
|
||||||
|
(catch [] (pass)))
|
||||||
|
|
||||||
|
(try
|
||||||
|
(print foobar42ofthebaz)
|
||||||
|
(catch []
|
||||||
|
(setv foobar42ofthebaz 42)
|
||||||
|
(assert (= foobar42ofthebaz 42)))))
|
||||||
|
|
||||||
(defn test-earmuffs []
|
(defn test-earmuffs []
|
||||||
"NATIVE: Test earmuffs"
|
"NATIVE: Test earmuffs"
|
||||||
@ -327,7 +375,7 @@
|
|||||||
6))
|
6))
|
||||||
(try
|
(try
|
||||||
(assert (= x 42)) ; This ain't true
|
(assert (= x 42)) ; This ain't true
|
||||||
(catch NameError e (assert e)))
|
(catch [e [NameError]] (assert e)))
|
||||||
(assert (= y 123)))
|
(assert (= y 123)))
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user