Skip to content

Commit c39de6a

Browse files
MichaelCG8copybara-github
authored andcommitted
issue-261 Fixed missing parts of argument descriptions for Google and Numpy style docstrings.
482bb9d by Michael Garbutt <michael.c.garbutt@gmail.com>: COPYBARA_INTEGRATE_REVIEW=#262 from MichaelCG8:issue-261-bugfix-multi-line-docstring-parameter-descriptions 482bb9d PiperOrigin-RevId: 353248737 Change-Id: I3033200c69c5aba0ce9bb819574f37248e32c1cb
1 parent 629d91c commit c39de6a

2 files changed

Lines changed: 63 additions & 6 deletions

File tree

fire/docstrings.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -307,19 +307,20 @@ def _is_arg_name(name):
307307
"""Returns whether name is a valid arg name.
308308
309309
This is used to prevent multiple words (plaintext) from being misinterpreted
310-
as an argument name. So if ":" appears in the middle of a line in a docstring,
311-
we don't accidentally interpret the first half of that line as a single arg
312-
name.
310+
as an argument name. Any line that doesn't match the pattern for a valid
311+
argument is treated as not being an argument.
313312
314313
Args:
315314
name: The name of the potential arg.
316315
Returns:
317316
True if name looks like an arg name, False otherwise.
318317
"""
319318
name = name.strip()
320-
return (name
321-
and ' ' not in name
322-
and ':' not in name)
319+
# arg_pattern is a letter or underscore followed by
320+
# zero or more letters, numbers, or underscores.
321+
arg_pattern = r'^[a-zA-Z_]\w*$'
322+
re.match(arg_pattern, name)
323+
return re.match(arg_pattern, name) is not None
323324

324325

325326
def _as_arg_name_and_type(text):
@@ -402,6 +403,7 @@ def _consume_google_args_line(line_info, state):
402403
arg = _get_or_create_arg_by_name(state, arg_name)
403404
arg.type.lines.append(type_str)
404405
arg.description.lines.append(second.strip())
406+
state.current_arg = arg
405407
else:
406408
if state.current_arg:
407409
state.current_arg.description.lines.append(split_line[0])

fire/docstrings_test.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,32 @@ def test_google_format_typed_args_and_returns(self):
144144
)
145145
self.assertEqual(expected_docstring_info, docstring_info)
146146

147+
def test_google_format_multiline_arg_description(self):
148+
docstring = """Docstring summary.
149+
150+
This is a longer description of the docstring. It spans multiple lines, as
151+
is allowed.
152+
153+
Args:
154+
param1 (int): The first parameter.
155+
param2 (str): The second parameter. This has a lot of text, enough to
156+
cover two lines.
157+
"""
158+
docstring_info = docstrings.parse(docstring)
159+
expected_docstring_info = DocstringInfo(
160+
summary='Docstring summary.',
161+
description='This is a longer description of the docstring. It spans '
162+
'multiple lines, as\nis allowed.',
163+
args=[
164+
ArgInfo(name='param1', type='int',
165+
description='The first parameter.'),
166+
ArgInfo(name='param2', type='str',
167+
description='The second parameter. This has a lot of text, '
168+
'enough to cover two lines.'),
169+
],
170+
)
171+
self.assertEqual(expected_docstring_info, docstring_info)
172+
147173
def test_rst_format_typed_args_and_returns(self):
148174
docstring = """Docstring summary.
149175
@@ -207,6 +233,35 @@ def test_numpy_format_typed_args_and_returns(self):
207233
)
208234
self.assertEqual(expected_docstring_info, docstring_info)
209235

236+
def test_numpy_format_multiline_arg_description(self):
237+
docstring = """Docstring summary.
238+
239+
This is a longer description of the docstring. It spans across multiple
240+
lines.
241+
242+
Parameters
243+
----------
244+
param1 : int
245+
The first parameter.
246+
param2 : str
247+
The second parameter. This has a lot of text, enough to cover two
248+
lines.
249+
"""
250+
docstring_info = docstrings.parse(docstring)
251+
expected_docstring_info = DocstringInfo(
252+
summary='Docstring summary.',
253+
description='This is a longer description of the docstring. It spans '
254+
'across multiple\nlines.',
255+
args=[
256+
ArgInfo(name='param1', type='int',
257+
description='The first parameter.'),
258+
ArgInfo(name='param2', type='str',
259+
description='The second parameter. This has a lot of text, '
260+
'enough to cover two lines.'),
261+
],
262+
)
263+
self.assertEqual(expected_docstring_info, docstring_info)
264+
210265
def test_multisection_docstring(self):
211266
docstring = """Docstring summary.
212267

0 commit comments

Comments
 (0)