Parse the docstring to extract the Args section and return it as a dictionary. The docstring is expected to be in the format: Args: arg1 (type): Description of arg1. arg2 (type): Description of arg2. # This function will also return the remai
(docstring, max_indent_level=0, return_intro=False)
| 2615 | |
| 2616 | |
| 2617 | def parse_docstring(docstring, max_indent_level=0, return_intro=False): |
| 2618 | """ |
| 2619 | Parse the docstring to extract the Args section and return it as a dictionary. |
| 2620 | The docstring is expected to be in the format: |
| 2621 | Args: |
| 2622 | arg1 (type): |
| 2623 | Description of arg1. |
| 2624 | arg2 (type): |
| 2625 | Description of arg2. |
| 2626 | |
| 2627 | # This function will also return the remaining part of the docstring after the Args section. |
| 2628 | Returns:/Example: |
| 2629 | ... |
| 2630 | """ |
| 2631 | match = _re_example_or_return.search(docstring) |
| 2632 | if match: |
| 2633 | remainder_docstring = docstring[match.start() :] |
| 2634 | docstring = docstring[: match.start()] |
| 2635 | else: |
| 2636 | remainder_docstring = "" |
| 2637 | |
| 2638 | args_match = _re_args_section.search(docstring) |
| 2639 | # still try to find args description in the docstring, if args are not preceded by "Args:" |
| 2640 | docstring_intro = None |
| 2641 | if args_match: |
| 2642 | docstring_intro = docstring[: args_match.start()] |
| 2643 | if docstring_intro.split("\n")[-1].strip() == '"""': |
| 2644 | docstring_intro = "\n".join(docstring_intro.split("\n")[:-1]) |
| 2645 | if docstring_intro.split("\n")[0].strip() == 'r"""' or docstring_intro.split("\n")[0].strip() == '"""': |
| 2646 | docstring_intro = "\n".join(docstring_intro.split("\n")[1:]) |
| 2647 | if docstring_intro.strip() == "": |
| 2648 | docstring_intro = None |
| 2649 | args_section = args_match.group(1).lstrip("\n") if args_match else docstring |
| 2650 | if args_section.split("\n")[-1].strip() == '"""': |
| 2651 | args_section = "\n".join(args_section.split("\n")[:-1]) |
| 2652 | if args_section.split("\n")[0].strip() == 'r"""' or args_section.split("\n")[0].strip() == '"""': |
| 2653 | args_section = "\n".join(args_section.split("\n")[1:]) |
| 2654 | args_section = set_min_indent(args_section, 0) |
| 2655 | params = {} |
| 2656 | if args_section: |
| 2657 | # Use the pre-compiled pattern (max_indent_level is always 0 at all call |
| 2658 | # sites; if a non-zero value is ever needed, compile a fresh pattern). |
| 2659 | if max_indent_level == 0: |
| 2660 | param_pattern = _re_param |
| 2661 | else: |
| 2662 | param_pattern = re.compile( |
| 2663 | # |--- Group 1 ---|| Group 2 ||- Group 3 -||---------- Group 4 ----------| |
| 2664 | rf"^\s{{0,{max_indent_level}}}(\w+)\s*\(\s*([^, \)]*)(\s*.*?)\s*\)\s*:\s*((?:(?!\n^\s{{0,{max_indent_level}}}\w+\s*\().)*)", |
| 2665 | re.DOTALL | re.MULTILINE, |
| 2666 | ) |
| 2667 | for match in param_pattern.finditer(args_section): |
| 2668 | param_name = match.group(1) |
| 2669 | param_type = match.group(2) |
| 2670 | additional_info = match.group(3) |
| 2671 | optional = "optional" in additional_info |
| 2672 | shape = parse_shape(additional_info) |
| 2673 | default = parse_default(additional_info) |
| 2674 | param_description = match.group(4).strip() |
no test coverage detected