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