Check that compiler error are user always user friendly
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
de85940114
commit
4e202aa1a5
@ -419,13 +419,14 @@ class HyASTCompiler(object):
|
|||||||
|
|
||||||
if isinstance(expr, HyLambdaListKeyword):
|
if isinstance(expr, HyLambdaListKeyword):
|
||||||
if expr not in expr._valid_types:
|
if expr not in expr._valid_types:
|
||||||
raise HyCompileError("{0} is not a valid "
|
raise HyTypeError(expr, "{0} is not a valid "
|
||||||
"lambda-keyword.".format(repr(expr)))
|
"lambda-keyword.".format(repr(expr)))
|
||||||
if expr == "&rest" and lambda_keyword is None:
|
if expr == "&rest" and lambda_keyword is None:
|
||||||
lambda_keyword = expr
|
lambda_keyword = expr
|
||||||
elif expr == "&optional":
|
elif expr == "&optional":
|
||||||
if len(defaults) > 0:
|
if len(defaults) > 0:
|
||||||
raise HyCompileError("There can only be &optional "
|
raise HyTypeError(expr,
|
||||||
|
"There can only be &optional "
|
||||||
"arguments or one &key argument")
|
"arguments or one &key argument")
|
||||||
lambda_keyword = expr
|
lambda_keyword = expr
|
||||||
elif expr == "&key":
|
elif expr == "&key":
|
||||||
@ -433,7 +434,8 @@ class HyASTCompiler(object):
|
|||||||
elif expr == "&kwargs":
|
elif expr == "&kwargs":
|
||||||
lambda_keyword = expr
|
lambda_keyword = expr
|
||||||
else:
|
else:
|
||||||
raise HyCompileError("{0} is in an invalid "
|
raise HyTypeError(expr,
|
||||||
|
"{0} is in an invalid "
|
||||||
"position.".format(repr(expr)))
|
"position.".format(repr(expr)))
|
||||||
# we don't actually care about this token, so we set
|
# we don't actually care about this token, so we set
|
||||||
# our state and continue to the next token...
|
# our state and continue to the next token...
|
||||||
@ -443,16 +445,19 @@ class HyASTCompiler(object):
|
|||||||
args.append(expr)
|
args.append(expr)
|
||||||
elif lambda_keyword == "&rest":
|
elif lambda_keyword == "&rest":
|
||||||
if varargs:
|
if varargs:
|
||||||
raise HyCompileError("There can only be one "
|
raise HyTypeError(expr,
|
||||||
|
"There can only be one "
|
||||||
"&rest argument")
|
"&rest argument")
|
||||||
varargs = str(expr)
|
varargs = str(expr)
|
||||||
elif lambda_keyword == "&key":
|
elif lambda_keyword == "&key":
|
||||||
if type(expr) != HyDict:
|
if type(expr) != HyDict:
|
||||||
raise TypeError("There can only be one &key "
|
raise HyTypeError(expr,
|
||||||
|
"There can only be one &key "
|
||||||
"argument")
|
"argument")
|
||||||
else:
|
else:
|
||||||
if len(defaults) > 0:
|
if len(defaults) > 0:
|
||||||
raise HyCompileError("There can only be &optional "
|
raise HyTypeError(expr,
|
||||||
|
"There can only be &optional "
|
||||||
"arguments or one &key argument")
|
"arguments or one &key argument")
|
||||||
# As you can see, Python has a funny way of
|
# As you can see, Python has a funny way of
|
||||||
# defining keyword arguments.
|
# defining keyword arguments.
|
||||||
@ -463,7 +468,8 @@ class HyASTCompiler(object):
|
|||||||
elif lambda_keyword == "&optional":
|
elif lambda_keyword == "&optional":
|
||||||
if isinstance(expr, HyList):
|
if isinstance(expr, HyList):
|
||||||
if not len(expr) == 2:
|
if not len(expr) == 2:
|
||||||
raise TypeError("optional args should be bare names "
|
raise HyTypeError(expr,
|
||||||
|
"optional args should be bare names "
|
||||||
"or 2-item lists")
|
"or 2-item lists")
|
||||||
k, v = expr
|
k, v = expr
|
||||||
else:
|
else:
|
||||||
@ -474,7 +480,8 @@ class HyASTCompiler(object):
|
|||||||
defaults.append(ret.force_expr)
|
defaults.append(ret.force_expr)
|
||||||
elif lambda_keyword == "&kwargs":
|
elif lambda_keyword == "&kwargs":
|
||||||
if kwargs:
|
if kwargs:
|
||||||
raise HyCompileError("There can only be one "
|
raise HyTypeError(expr,
|
||||||
|
"There can only be one "
|
||||||
"&kwargs argument")
|
"&kwargs argument")
|
||||||
kwargs = str(expr)
|
kwargs = str(expr)
|
||||||
|
|
||||||
@ -760,7 +767,8 @@ class HyASTCompiler(object):
|
|||||||
@builds("except")
|
@builds("except")
|
||||||
@builds("catch")
|
@builds("catch")
|
||||||
def magic_internal_form(self, expr):
|
def magic_internal_form(self, expr):
|
||||||
raise TypeError("Error: `%s' can't be used like that." % (expr[0]))
|
raise HyTypeError(expr,
|
||||||
|
"Error: `%s' can't be used like that." % (expr[0]))
|
||||||
|
|
||||||
def _compile_catch_expression(self, expr, var):
|
def _compile_catch_expression(self, expr, var):
|
||||||
catch = expr.pop(0) # catch
|
catch = expr.pop(0) # catch
|
||||||
@ -792,6 +800,9 @@ class HyASTCompiler(object):
|
|||||||
# let's pop variable and use it as name
|
# let's pop variable and use it as name
|
||||||
if len(exceptions) == 2:
|
if len(exceptions) == 2:
|
||||||
name = exceptions.pop(0)
|
name = exceptions.pop(0)
|
||||||
|
if not isinstance(name, HySymbol):
|
||||||
|
raise HyTypeError(exceptions,
|
||||||
|
"Exception storage target name must be a symbol.")
|
||||||
if sys.version_info[0] >= 3:
|
if sys.version_info[0] >= 3:
|
||||||
# Python3 features a change where the Exception handler
|
# Python3 features a change where the Exception handler
|
||||||
# moved the name from a Name() to a pure Python String type.
|
# moved the name from a Name() to a pure Python String type.
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from hy import HyString
|
from hy import HyString
|
||||||
from hy.compiler import hy_compile, HyCompileError
|
from hy.compiler import hy_compile, HyCompileError, HyTypeError
|
||||||
from hy.lex import tokenize
|
from hy.lex import tokenize
|
||||||
|
|
||||||
import ast
|
import ast
|
||||||
@ -43,8 +43,11 @@ def cant_compile(expr):
|
|||||||
try:
|
try:
|
||||||
hy_compile(expr)
|
hy_compile(expr)
|
||||||
assert False
|
assert False
|
||||||
except HyCompileError:
|
except HyCompileError as e:
|
||||||
pass
|
# Anything that can't be compiled should raise a user friendly
|
||||||
|
# error, otherwise it's a compiler bug.
|
||||||
|
assert isinstance(e.exception, HyTypeError)
|
||||||
|
assert e.traceback
|
||||||
|
|
||||||
|
|
||||||
def test_ast_bad_type():
|
def test_ast_bad_type():
|
||||||
|
Loading…
Reference in New Issue
Block a user