Skip to content

Commit

Permalink
[python] do not generate = None for optional KwArgs/VarArgs argumen…
Browse files Browse the repository at this point in the history
…ts (closes HaxeFoundation#2980)

also disallow additional arguments after KwArgs/VarArgs
  • Loading branch information
Simn committed May 14, 2014
1 parent b529584 commit 15e7049
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 26 deletions.
55 changes: 29 additions & 26 deletions genpy.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1045,23 +1045,26 @@ module Printer = struct
let print_metadata (name,_,_) =
Printf.sprintf "@%s" name

let print_args args =
let print_args args p =
let had_value = ref false in
let had_var_args = ref false in
let sl = List.map (fun (v,cto) ->
if !had_var_args then error "Arguments after KwArgs/VarArgs are not allowed" p;
let name = handle_keywords v.v_name in
let arg_string = match follow v.v_type with
| TAbstract({a_path = ["python"],"KwArgs"},_) -> "**" ^ name
| TAbstract({a_path = ["python"],"VarArgs"},_) -> "*" ^ name
| _ -> name
in
let arg_value = match cto with
| None when !had_value -> " = None"
| None -> ""
| Some ct ->
had_value := true;
Printf.sprintf " = %s" (print_constant ct)
in
Printf.sprintf "%s%s" arg_string arg_value
match follow v.v_type with
| TAbstract({a_path = ["python"],"KwArgs"},_) ->
had_var_args := true;
"**" ^ name
| TAbstract({a_path = ["python"],"VarArgs"},_) ->
had_var_args := true;
"*" ^ name
| _ ->
name ^ match cto with
| None when !had_value -> " = None"
| None -> ""
| Some ct ->
had_value := true;
Printf.sprintf " = %s" (print_constant ct)
) args in
String.concat "," sl

Expand All @@ -1075,21 +1078,21 @@ module Printer = struct

and print_var pctx v eo =
match eo with
| Some {eexpr = TFunction tf} ->
print_function pctx tf (Some v.v_name)
| Some ({eexpr = TFunction tf} as e) ->
print_function pctx tf (Some v.v_name) e.epos
| _ ->
let s_init = match eo with
| None -> "None"
| Some e -> print_op_assign_right pctx e
in
Printf.sprintf "%s = %s" (handle_keywords v.v_name) s_init

and print_function pctx tf name =
and print_function pctx tf name p =
let s_name = match name with
| None -> pctx.pc_next_anon_func()
| Some s -> handle_keywords s
in
let s_args = print_args tf.tf_args in
let s_args = print_args tf.tf_args p in
let s_expr = print_expr {pctx with pc_indent = "\t" ^ pctx.pc_indent} tf.tf_expr in
Printf.sprintf "def %s(%s):\n%s\t%s" s_name s_args pctx.pc_indent s_expr

Expand Down Expand Up @@ -1261,7 +1264,7 @@ module Printer = struct
| TUnop(op,Prefix,e1) ->
Printf.sprintf "%s%s" (print_unop op) (print_expr pctx e1)
| TFunction tf ->
print_function pctx tf None
print_function pctx tf None e.epos
| TVar (v,eo) ->
print_var pctx v eo
| TBlock [] ->
Expand Down Expand Up @@ -1591,8 +1594,8 @@ module Generator = struct
let get_path mt =
Printer.print_base_type mt

let tfunc_str f pctx name =
Printer.print_function pctx f name
let tfunc_str f pctx name p =
Printer.print_function pctx f name p

let texpr_str e pctx =
Printer.print_expr pctx e
Expand Down Expand Up @@ -1730,7 +1733,7 @@ module Generator = struct
else
print ctx "%s%s = %s" indent field expr_string_2

let gen_func_expr ctx e c name metas extra_args indent stat =
let gen_func_expr ctx e c name metas extra_args indent stat p =
let pctx = Printer.create_context indent ctx.com.debug in
let e = match e.eexpr with
| TFunction(f) ->
Expand All @@ -1749,7 +1752,7 @@ module Generator = struct
let expr1 = transform_expr e in
let expr_string = match expr1.eexpr with
| TFunction f ->
tfunc_str f pctx (Some name)
tfunc_str f pctx (Some name) p
| _ ->
Printf.sprintf "%s = %s" name (texpr_str expr1 pctx)
in
Expand All @@ -1775,7 +1778,7 @@ module Generator = struct
end;
newline ctx;
newline ctx;
gen_func_expr ctx (match cf.cf_expr with None -> assert false | Some e -> e) c "__init__" py_metas ["self"] "\t" false
gen_func_expr ctx (match cf.cf_expr with None -> assert false | Some e -> e) c "__init__" py_metas ["self"] "\t" false cf.cf_pos

let gen_class_field ctx c p cf =
let field = handle_keywords cf.cf_name in
Expand All @@ -1788,7 +1791,7 @@ module Generator = struct
begin match cf.cf_kind with
| Method _ ->
let py_metas = filter_py_metas cf.cf_meta in
gen_func_expr ctx e c field py_metas ["self"] "\t" false;
gen_func_expr ctx e c field py_metas ["self"] "\t" false cf.cf_pos;

| _ ->
gen_expr ctx e (Printf.sprintf "# var %s" field) "\t";
Expand Down Expand Up @@ -1874,7 +1877,7 @@ module Generator = struct
let py_metas = filter_py_metas cf.cf_meta in
let e = match cf.cf_expr with Some e -> e | _ -> assert false in
newline ctx;
gen_func_expr ctx e c field py_metas [] "\t" true;
gen_func_expr ctx e c field py_metas [] "\t" true cf.cf_pos;
) methods;

!has_static_methods || !has_empty_static_vars
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/issues/Issue2980.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package unit.issues;

class Issue2980 extends Test {

#if python
function a(?args:python.KwArgs) {}
function b(?args:python.VarArgs) {}

function test() {
a();
b();
}
#end
}

0 comments on commit 15e7049

Please sign in to comment.