Implemented &key and added tests
This commit is contained in:
parent
263d7af0fc
commit
1080a457b1
@ -189,11 +189,12 @@ class HyASTCompiler(object):
|
||||
return ret
|
||||
|
||||
def _parse_lambda_list(self, exprs):
|
||||
""" Return FunctionDef parameter values from lambda list."""
|
||||
exprs.reverse()
|
||||
args = []
|
||||
keywords = []
|
||||
defaults = []
|
||||
varargs = None
|
||||
kwargs = {}
|
||||
kwargs = None
|
||||
lambda_keyword = None
|
||||
|
||||
while exprs:
|
||||
@ -227,25 +228,30 @@ class HyASTCompiler(object):
|
||||
varargs = str(expr)
|
||||
elif lambda_keyword == "&key":
|
||||
if type(expr) != HyDict:
|
||||
raise TypeError("FOOBAR")
|
||||
raise TypeError("There can only be one &key "
|
||||
"argument")
|
||||
else:
|
||||
if len(keywords) > 0:
|
||||
if len(defaults) > 0:
|
||||
raise HyCompileError("There can only be "
|
||||
"one &key argument")
|
||||
keywords = [ast.keyword(arg=ast_str(k),
|
||||
value=self.compile(v),
|
||||
lineno=expr.start_line,
|
||||
col_offset=expr.start_column)
|
||||
for k, v in expr.items()]
|
||||
# As you can see, Python has a funny way of
|
||||
# defining keyword arguments.
|
||||
for k in expr.keys():
|
||||
args.append(k)
|
||||
for v in expr.values():
|
||||
defaults.append(self.compile(v))
|
||||
elif lambda_keyword == "&optional":
|
||||
# not implemented yet.
|
||||
pass
|
||||
elif lambda_keyword == "&kwargs":
|
||||
if kwargs:
|
||||
raise HyCompileError("There can only be one "
|
||||
"&kwargs argument")
|
||||
kwargs = str(expr)
|
||||
|
||||
if not kwargs:
|
||||
kwargs = None
|
||||
return args, keywords, varargs, kwargs
|
||||
return args, defaults, varargs, kwargs
|
||||
|
||||
@builds(list)
|
||||
def compile_raw_list(self, entries):
|
||||
@ -1103,7 +1109,7 @@ class HyASTCompiler(object):
|
||||
expression.start_line,
|
||||
expression.start_column)
|
||||
|
||||
args, keywords, stararg, kwargs = self._parse_lambda_list(sig)
|
||||
args, defaults, stararg, kwargs = self._parse_lambda_list(sig)
|
||||
|
||||
ret = ast.FunctionDef(
|
||||
name=name,
|
||||
@ -1120,8 +1126,8 @@ class HyASTCompiler(object):
|
||||
vararg=stararg,
|
||||
kwarg=kwargs,
|
||||
kwonlyargs=[],
|
||||
kw_defaults=keywords,
|
||||
defaults=[]),
|
||||
kw_defaults=[],
|
||||
defaults=defaults),
|
||||
body=body,
|
||||
decorator_list=[])
|
||||
|
||||
|
@ -334,14 +334,25 @@ def test_ast_tuple():
|
||||
assert type(code) == ast.Tuple
|
||||
|
||||
|
||||
def test_lambda_list_keywords():
|
||||
def test_lambda_list_keywords_rest():
|
||||
""" Ensure we can compile functions with lambda list keywords."""
|
||||
hy_compile(tokenize("(fn (x &rest xs) (print xs))"))
|
||||
cant_compile("(fn (x &rest xs &rest ys) (print xs))")
|
||||
|
||||
def test_lambda_list_keywords_optional():
|
||||
""" Ensure we can compile functions with &optional."""
|
||||
hy_compile(tokenize("(fn (x &optional (foo True)) foo)"))
|
||||
def test_lambda_list_keywords_key():
|
||||
""" Ensure we can compile functions with &key."""
|
||||
hy_compile(tokenize("(fn (x &key {foo True}) (list x foo))"))
|
||||
cant_compile("(fn (x &key {bar \"baz\"} &key {foo 42}) (list x bar foo))")
|
||||
|
||||
def test_lambda_list_keywords_kwargs():
|
||||
""" Ensure we can compile functions with &kwargs."""
|
||||
hy_compile(tokenize("(fn (x &kwargs kw) (list x kw))"))
|
||||
cant_compile("(fn (x &kwargs xs &kwargs ys) (list x xs ys))")
|
||||
|
||||
def test_lambda_list_keywords_mixed():
|
||||
""" Ensure we can mix them up."""
|
||||
hy_compile(tokenize("(fn (x &rest xs &kwargs kw) (list x xs kw))"))
|
||||
cant_compile("(fn (x &rest xs &key {bar \"baz\"}))")
|
||||
|
||||
def test_ast_unicode_strings():
|
||||
"""Ensure we handle unicode strings correctly"""
|
||||
|
@ -616,3 +616,8 @@
|
||||
(assert (= (dirname "/some/path") "/some"))
|
||||
(assert (= op.dirname dirname))
|
||||
(assert (= dn dirname)))
|
||||
|
||||
(defn test-lambda-keyword-lists []
|
||||
"NATIVE: test lambda keyword lists"
|
||||
(defn foo (x &rest xs &kwargs kw) [x xs kw])
|
||||
(assert (= (foo 10 20 30) [10, (20, 30), {}])))
|
||||
|
Loading…
Reference in New Issue
Block a user