Merge branch 'master' into pr/182

This commit is contained in:
Paul Tagliamonte 2013-05-17 11:09:37 -04:00
commit c0fd41620f
3 changed files with 50 additions and 24 deletions

View File

@ -97,7 +97,7 @@ def builds(_type):
unpythonic_chars = ["-"]
really_ok = ["-"]
if True in (x in str_type(_type) for x in unpythonic_chars):
if any(x in unpythonic_chars for x in str_type(_type)):
if _type not in really_ok:
raise TypeError("`build' needs to be *post* translated strings, "
"Mr. / Mrs. Hypser. -- `%s' sucks." % (_type))
@ -419,22 +419,24 @@ class HyASTCompiler(object):
if isinstance(expr, HyLambdaListKeyword):
if expr not in expr._valid_types:
raise HyCompileError("{0} is not a valid "
"lambda-keyword.".format(repr(expr)))
raise HyTypeError(expr, "{0} is not a valid "
"lambda-keyword.".format(repr(expr)))
if expr == "&rest" and lambda_keyword is None:
lambda_keyword = expr
elif expr == "&optional":
if len(defaults) > 0:
raise HyCompileError("There can only be &optional "
"arguments or one &key argument")
raise HyTypeError(expr,
"There can only be &optional "
"arguments or one &key argument")
lambda_keyword = expr
elif expr == "&key":
lambda_keyword = expr
elif expr == "&kwargs":
lambda_keyword = expr
else:
raise HyCompileError("{0} is in an invalid "
"position.".format(repr(expr)))
raise HyTypeError(expr,
"{0} is in an invalid "
"position.".format(repr(expr)))
# we don't actually care about this token, so we set
# our state and continue to the next token...
continue
@ -443,17 +445,20 @@ class HyASTCompiler(object):
args.append(expr)
elif lambda_keyword == "&rest":
if varargs:
raise HyCompileError("There can only be one "
"&rest argument")
raise HyTypeError(expr,
"There can only be one "
"&rest argument")
varargs = str(expr)
elif lambda_keyword == "&key":
if type(expr) != HyDict:
raise TypeError("There can only be one &key "
"argument")
raise HyTypeError(expr,
"There can only be one &key "
"argument")
else:
if len(defaults) > 0:
raise HyCompileError("There can only be &optional "
"arguments or one &key argument")
raise HyTypeError(expr,
"There can only be &optional "
"arguments or one &key argument")
# As you can see, Python has a funny way of
# defining keyword arguments.
it = iter(expr)
@ -464,8 +469,9 @@ class HyASTCompiler(object):
elif lambda_keyword == "&optional":
if isinstance(expr, HyList):
if not len(expr) == 2:
raise TypeError("optional args should be bare names "
"or 2-item lists")
raise HyTypeError(expr,
"optional args should be bare names "
"or 2-item lists")
k, v = expr
else:
k = expr
@ -475,8 +481,9 @@ class HyASTCompiler(object):
defaults.append(ret.force_expr)
elif lambda_keyword == "&kwargs":
if kwargs:
raise HyCompileError("There can only be one "
"&kwargs argument")
raise HyTypeError(expr,
"There can only be one "
"&kwargs argument")
kwargs = str(expr)
return ret, args, defaults, varargs, kwargs
@ -761,7 +768,8 @@ class HyASTCompiler(object):
@builds("except")
@builds("catch")
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):
catch = expr.pop(0) # catch
@ -793,6 +801,11 @@ class HyASTCompiler(object):
# let's pop variable and use it as name
if len(exceptions) == 2:
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:
# Python3 features a change where the Exception handler
# moved the name from a Name() to a pure Python String type.

View File

@ -22,7 +22,7 @@
from __future__ import unicode_literals
from hy import HyString
from hy.compiler import hy_compile, HyCompileError
from hy.compiler import hy_compile, HyCompileError, HyTypeError
from hy.lex import tokenize
import ast
@ -43,8 +43,11 @@ def cant_compile(expr):
try:
hy_compile(expr)
assert False
except HyCompileError:
pass
except HyCompileError as e:
# 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():

View File

@ -27,11 +27,21 @@ if sys.version_info[0] <= 2 and sys.version_info[1] <= 6:
else:
import unittest
from hy import compiler
from hy.models.expression import HyExpression
from hy.models.list import HyList
from hy.models.symbol import HySymbol
from hy.compiler import HyASTCompiler
class CompilerTest(unittest.TestCase):
def test_builds_with_dash(self):
self.assert_(callable(compiler.builds("foobar")))
self.assert_(callable(compiler.builds("foo_bar")))
self.assert_(callable(compiler.builds("-")))
self.assertRaisesRegexp(TypeError,
"\*post\* translated strings",
compiler.builds, "foobar-with-dash-")
class HyASTCompilerTest(unittest.TestCase):
@ -46,7 +56,7 @@ class HyASTCompilerTest(unittest.TestCase):
return h
def setUp(self):
self.c = HyASTCompiler()
self.c = compiler.HyASTCompiler()
def test_fn_compiler_empty_function(self):
ret = self.c.compile_function_def(