# HG changeset patch # User Emmanuel Gil Peyrot # Date 1465695448 -3600 # Node ID 1a815946c2e541a7233631bdea9d6a5a2872a8a8 # Parent d9838e8b3ec5b6b87f62bab39b7c34d4a2e133a7 Implement keywords in expr::Call, and add some tests. diff --git a/src/ast_convert.rs b/src/ast_convert.rs --- a/src/ast_convert.rs +++ b/src/ast_convert.rs @@ -1,4 +1,4 @@ -use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension}; +use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension, keyword}; use cpython::{Python, PyObject}; use cpython::ObjectProtocol; //for call method @@ -168,6 +168,21 @@ fn parse_comprehension(py: Python, ast: comprehension {target: target, iter: iter, ifs: ifs} } +fn parse_keyword(py: Python, ast: PyObject) -> keyword { + let arg = ast.getattr(py, "arg").unwrap(); + let value = ast.getattr(py, "value").unwrap(); + + let arg = if arg == py.None() { + None + } else { + let arg = get_str(py, arg); + Some(arg) + }; + let value = parse_expr(py, value); + + keyword {arg: arg, value: value} +} + fn parse_operator(py: Python, ast: PyObject) -> operator { let builtins_module = py.import("builtins").unwrap(); let isinstance = builtins_module.get(py, "isinstance").unwrap(); @@ -320,16 +335,9 @@ fn parse_expr(py: Python, ast: PyObject) let func = parse_expr(py, func); let args = parse_list(py, args, parse_expr); + let keywords = parse_list(py, keywords, parse_keyword); - /* - let mut kwargs = vec!(); - for arg in keywords.iter(py).unwrap() { - let arg = arg.unwrap(); - kwargs.push(parse_expr(py, arg)); - } - */ - - expr::Call(Box::new(func), args, vec!()) + expr::Call(Box::new(func), args, keywords) } else if is_instance(&ast, &compare_type) { let left = ast.getattr(py, "left").unwrap(); let ops = ast.getattr(py, "ops").unwrap(); diff --git a/src/ast_dump.rs b/src/ast_dump.rs --- a/src/ast_dump.rs +++ b/src/ast_dump.rs @@ -59,6 +59,14 @@ impl cmpop { } } +fn args_to_strings(args: Vec) -> Vec { + let mut arguments = vec!(); + for arg in args { + arguments.push(arg.to_string()); + } + arguments +} + fn args_to_string(args: Vec) -> String { let mut arguments = vec!(); for arg in args { @@ -67,15 +75,21 @@ fn args_to_string(args: Vec) -> St arguments.join(", ") } -fn kwargs_to_string(kwargs: Vec) -> String { - let mut arguments = vec!(); - for arg in kwargs { - match arg.arg { - Some(arg) => arguments.push(arg), - None => arguments.push("**kwarg".to_string()) +impl keyword { + fn to_string(&self) -> String { + match self.arg.clone() { + Some(arg) => format!("{}={}", arg, self.value.to_string()), + None => format!("**{}", self.value.to_string()) } } - arguments.join(", ") +} + +fn kwargs_to_strings(kwargs: Vec) -> Vec { + let mut arguments = vec!(); + for kwarg in kwargs { + arguments.push(kwarg.to_string()); + } + arguments } fn arguments_to_string(args: arguments) -> String { @@ -146,7 +160,14 @@ impl expr { arguments.join(" ") }), - expr::Call(func, args, keywords) => format!("{}({}{})", func.to_string(), args_to_string(args), kwargs_to_string(keywords)), + expr::Call(func, args, keywords) => format!("{}({})", func.to_string(), { + let mut arguments = vec!(); + let args = args_to_strings(args); + let keywords = kwargs_to_strings(keywords); + arguments.extend(args); + arguments.extend(keywords); + arguments.join(", ") + }), expr::Num(n) => format!("{}", n), expr::Str(s) => format!("\"{}\"", s), expr::NameConstant(name) => format!("{}", name), diff --git a/tests/test_parse_files/test_call.py b/tests/test_parse_files/test_call.py --- a/tests/test_parse_files/test_call.py +++ b/tests/test_parse_files/test_call.py @@ -1,1 +1,5 @@ -func(1, b) +func() +func(1) +func(1, a) +func(b=2, c=3) +func(a, b, c=3, d=4, **kwargs)