diff --git a/fire/docstrings.py b/fire/docstrings.py index 2adfe5ec..af15a8ae 100644 --- a/fire/docstrings.py +++ b/fire/docstrings.py @@ -597,6 +597,14 @@ def _google_section_permitted(line_info, state): """ if state.section.indentation is None: # We're not in a section yet. return True + if state.section.format == Formats.NUMPY: + colon_index = line_info.remaining.find(':') + if colon_index > 0 and line_info.remaining[colon_index - 1].isspace(): + # Numpy-style parameter lines have a space before the colon (e.g. + # "argument : int"), unlike Google section headers (e.g. "Args:"). Such + # a line is a parameter, not a new section, even if the parameter's name + # matches a section title (e.g. an argument named "argument"). + return False return (line_info.indentation <= state.section.indentation or line_info.indentation < state.section.line1_indentation) diff --git a/fire/docstrings_test.py b/fire/docstrings_test.py index ce516944..a21154c6 100644 --- a/fire/docstrings_test.py +++ b/fire/docstrings_test.py @@ -258,6 +258,28 @@ def test_numpy_format_multiline_arg_description(self): ) self.assertEqual(expected_docstring_info, docstring_info) + def test_numpy_format_arg_name_matches_section_title(self): + docstring = """Run. + + Parameters + ---------- + executable : + Executable to run + argument : + Positional argument to the executable + """ + docstring_info = docstrings.parse(docstring) + expected_docstring_info = DocstringInfo( + summary='Run.', + args=[ + ArgInfo(name='executable', type='', + description='Executable to run'), + ArgInfo(name='argument', type='', + description='Positional argument to the executable'), + ], + ) + self.assertEqual(expected_docstring_info, docstring_info) + def test_multisection_docstring(self): docstring = """Docstring summary.