*args and **kwargs no longer have own args in Python 3.5

Python 3.5's PEP 448 ("Additional Unpacking Generalizations") allows the
iterable- and dictionary- unpacking operators to be used more than once;
the implementation (see https://hg.python.org/cpython/rev/a65f685ba8c0)
gets rid of the optional `starargs` and `kwargs` arguments to `ast.Call`
and `ast.ClassDef`, instead using `ast.Starred` and `ast.keyword`
objects inside of the normal `args` and `keywords` lists,
respectively. This commit allows Hy's `apply` to work correctly with
this revised AST when running under Python 3.5.
This commit is contained in:
Zack M. Davis 2015-05-05 23:31:11 -07:00
parent 685688f04c
commit fb98bf58c4
2 changed files with 24 additions and 5 deletions

View File

@ -1554,12 +1554,28 @@ class HyASTCompiler(object):
stargs = expr.pop(0) stargs = expr.pop(0)
if stargs is not None: if stargs is not None:
stargs = self.compile(stargs) stargs = self.compile(stargs)
ret.expr.starargs = stargs.force_expr if PY35:
stargs_expr = stargs.force_expr
ret.expr.args.append(
ast.Starred(stargs_expr, ast.Load(),
lineno=stargs_expr.lineno,
col_offset=stargs_expr.col_offset)
)
else:
ret.expr.starargs = stargs.force_expr
ret = stargs + ret ret = stargs + ret
if expr: if expr:
kwargs = self.compile(expr.pop(0)) kwargs = self.compile(expr.pop(0))
ret.expr.kwargs = kwargs.force_expr if PY35:
kwargs_expr = kwargs.force_expr
ret.expr.keywords.append(
ast.keyword(None, kwargs_expr,
lineno=kwargs_expr.lineno,
col_offset=kwargs_expr.col_offset)
)
else:
ret.expr.kwargs = kwargs.force_expr
ret = kwargs + ret ret = kwargs + ret
return ret return ret

View File

@ -4,7 +4,7 @@
[operator [or_]]) [operator [or_]])
(import sys) (import sys)
(import [hy._compat [PY33 PY34]]) (import [hy._compat [PY33 PY34 PY35]])
(defn test-sys-argv [] (defn test-sys-argv []
"NATIVE: test sys.argv" "NATIVE: test sys.argv"
@ -1047,8 +1047,11 @@
(defn test-disassemble [] (defn test-disassemble []
"NATIVE: Test the disassemble function" "NATIVE: Test the disassemble function"
(assert (= (disassemble '(do (leaky) (leaky) (macros))) (if PY35
"Module(\n body=[\n Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[], starargs=None, kwargs=None)),\n Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[], starargs=None, kwargs=None)),\n Expr(value=Call(func=Name(id='macros'), args=[], keywords=[], starargs=None, kwargs=None))])")) (assert (= (disassemble '(do (leaky) (leaky) (macros)))
"Module(\n body=[Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[])),\n Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[])),\n Expr(value=Call(func=Name(id='macros'), args=[], keywords=[]))])"))
(assert (= (disassemble '(do (leaky) (leaky) (macros)))
"Module(\n body=[\n Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[], starargs=None, kwargs=None)),\n Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[], starargs=None, kwargs=None)),\n Expr(value=Call(func=Name(id='macros'), args=[], keywords=[], starargs=None, kwargs=None))])")))
(assert (= (disassemble '(do (leaky) (leaky) (macros)) true) (assert (= (disassemble '(do (leaky) (leaky) (macros)) true)
"leaky()\nleaky()\nmacros()"))) "leaky()\nleaky()\nmacros()")))