Skip to content

Commit a9812f5

Browse files
[Doc Generation] Support parsing posonlyargs when get function signature (#7578)
1 parent de289cb commit a9812f5

File tree

1 file changed

+57
-34
lines changed

1 file changed

+57
-34
lines changed

docs/api/gen_doc.py

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ def parse_module_file(mod):
319319
)
320320
if isinstance(node, ast.FunctionDef):
321321
api_info_dict[obj_id]["args"] = (
322-
gen_functions_args_str(node)
322+
gen_function_args_string(node)
323323
)
324324
elif isinstance(node, ast.ClassDef):
325325
for n in node.body:
@@ -328,7 +328,7 @@ def parse_module_file(mod):
328328
and n.name == "__init__"
329329
):
330330
api_info_dict[obj_id]["args"] = (
331-
gen_functions_args_str(n)
331+
gen_function_args_string(n)
332332
)
333333
break
334334
else:
@@ -361,39 +361,62 @@ def parse_module_file(mod):
361361
logger.debug("%s omitted", obj_full_name)
362362

363363

364-
def gen_functions_args_str(node):
365-
str_args_list = []
366-
if isinstance(node, ast.FunctionDef):
367-
# 'args', 'defaults', 'kw_defaults', 'kwarg', 'kwonlyargs', 'posonlyargs', 'vararg'
368-
for arg in node.args.args:
369-
if not arg.arg == "self":
370-
str_args_list.append(arg.arg)
364+
def gen_function_args_string(fn_node: ast.FunctionDef) -> str:
365+
def _gen_default_value_string(default_node: ast.expr) -> str:
366+
if isinstance(default_node, ast.Constant):
367+
default_value = default_node.value
368+
if isinstance(default_value, str):
369+
return f"'{default_value}'"
370+
return str(default_value)
371+
elif isinstance(default_node, ast.Name):
372+
return default_node.id
373+
return "..."
371374

372-
defarg_ind_start = len(str_args_list) - len(node.args.defaults)
373-
for defarg_ind in range(len(node.args.defaults)):
374-
if isinstance(node.args.defaults[defarg_ind], ast.Name):
375-
str_args_list[defarg_ind_start + defarg_ind] += "=" + str(
376-
node.args.defaults[defarg_ind].id
377-
)
378-
elif isinstance(node.args.defaults[defarg_ind], ast.Constant):
379-
defarg_val = str(node.args.defaults[defarg_ind].value)
380-
if isinstance(node.args.defaults[defarg_ind].value, str):
381-
defarg_val = f"'{defarg_val}'"
382-
str_args_list[defarg_ind_start + defarg_ind] += "=" + defarg_val
383-
if node.args.vararg is not None:
384-
str_args_list.append("*" + node.args.vararg.arg)
385-
if len(node.args.kwonlyargs) > 0:
386-
if node.args.vararg is None:
387-
str_args_list.append("*")
388-
for kwoarg, d in zip(node.args.kwonlyargs, node.args.kw_defaults):
389-
if isinstance(d, ast.Constant):
390-
str_args_list.append(f"{kwoarg.arg}={d.value}")
391-
elif isinstance(d, ast.Name):
392-
str_args_list.append(f"{kwoarg.arg}={d.id}")
393-
if node.args.kwarg is not None:
394-
str_args_list.append("**" + node.args.kwarg.arg)
395-
396-
return ", ".join(str_args_list)
375+
def _is_self_arg(arg: ast.arg) -> bool:
376+
return arg.arg == "self"
377+
378+
if not isinstance(fn_node, ast.FunctionDef):
379+
logger.warning(
380+
"The provided node %s is not a FunctionDef.", ast.unparse(fn_node)
381+
)
382+
return ""
383+
arg_list = []
384+
posonlyargs_count = len(fn_node.args.posonlyargs)
385+
# posonlyargs and args
386+
defaults_start_index = (
387+
len(fn_node.args.args)
388+
+ len(fn_node.args.posonlyargs)
389+
- len(fn_node.args.defaults)
390+
)
391+
for i, arg in enumerate(fn_node.args.posonlyargs + fn_node.args.args):
392+
if _is_self_arg(arg) and i == 0:
393+
continue
394+
if i == posonlyargs_count and posonlyargs_count > 0:
395+
arg_list.append("/")
396+
if i >= defaults_start_index:
397+
default_value_str = _gen_default_value_string(
398+
fn_node.args.defaults[i - defaults_start_index]
399+
)
400+
arg_list.append(f"{arg.arg}={default_value_str}")
401+
else:
402+
arg_list.append(arg.arg)
403+
# vararg
404+
if fn_node.args.vararg:
405+
arg_list.append(f"*{fn_node.args.vararg.arg}")
406+
# kwonlyargs
407+
if fn_node.args.kwonlyargs:
408+
arg_list.append("*")
409+
for i, kwonlyarg in enumerate(fn_node.args.kwonlyargs):
410+
kwdefault = fn_node.args.kw_defaults[i]
411+
if kwdefault is None:
412+
arg_list.append(kwonlyarg.arg)
413+
else:
414+
default_value_str = _gen_default_value_string(kwdefault)
415+
arg_list.append(f"{kwonlyarg.arg}={default_value_str}")
416+
# kwarg
417+
if fn_node.args.kwarg:
418+
arg_list.append(f"**{fn_node.args.kwarg.arg}")
419+
return ", ".join(arg_list)
397420

398421

399422
# step 2 fill field : `display`

0 commit comments

Comments
 (0)