Skip to content

Commit 4db30f8

Browse files
authored
Support combined NumPyDoc params (#41)
NumPyDoc allows joining multiple parameters with shared type on one line. This pattern is quite common in the ecosystem so support this.
1 parent 07cb8c7 commit 4db30f8

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

src/docstub/_docstrings.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,32 @@ def _match_import(self, qualname, *, meta):
532532
return matched_qualname
533533

534534

535+
def _uncombine_numpydoc_params(params):
536+
"""Split combined NumPyDoc parameters.
537+
538+
NumPyDoc allows joining multiple parameters with shared type on one line.
539+
This function helps with iterating them one-by-one regardless.
540+
541+
Parameters
542+
----------
543+
params : list[numpydoc.docsrape.Parameter]
544+
545+
Yields
546+
------
547+
param : numpydoc.docscrape.Parameter
548+
"""
549+
for param in params:
550+
if "," in param.name:
551+
# Multiple parameters on one line, split and yield separately
552+
names = [p.strip() for p in param.name.split(",")]
553+
for name in names:
554+
# Uncombined parameter re-uses shared type and description
555+
uncombined = npds.Parameter(name=name, type=param.type, desc=param.desc)
556+
yield uncombined
557+
else:
558+
yield param
559+
560+
535561
class DocstringAnnotations:
536562
"""Collect annotations in a given docstring.
537563
@@ -793,7 +819,10 @@ def _section_annotations(self, name):
793819
Entries without annotations fall back to :class:`_typeshed.Incomplete`.
794820
"""
795821
annotated_params = {}
796-
for param in self.np_docstring[name]:
822+
823+
params = self.np_docstring[name]
824+
params = list(_uncombine_numpydoc_params(params))
825+
for param in params:
797826
param = self._handle_missing_whitespace(param) # noqa: PLW2901
798827

799828
if param.name in annotated_params:

tests/test_docstrings.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,3 +430,28 @@ def test_missing_whitespace(self, capsys):
430430
assert annotations.parameters["a"].value == "int"
431431
captured = capsys.readouterr()
432432
assert "Possibly missing whitespace" in captured.out
433+
434+
def test_combined_numpydoc_params(self):
435+
docstring = dedent(
436+
"""
437+
Parameters
438+
----------
439+
a, b, c : bool
440+
d, e :
441+
"""
442+
)
443+
transformer = DoctypeTransformer()
444+
annotations = DocstringAnnotations(docstring, transformer=transformer)
445+
assert len(annotations.parameters) == 5
446+
assert annotations.parameters["a"].value == "bool"
447+
assert annotations.parameters["b"].value == "bool"
448+
assert annotations.parameters["c"].value == "bool"
449+
450+
assert annotations.parameters["d"].value == "Incomplete"
451+
assert annotations.parameters["e"].value == "Incomplete"
452+
assert annotations.parameters["d"].imports == {
453+
KnownImport.typeshed_Incomplete()
454+
}
455+
assert annotations.parameters["e"].imports == {
456+
KnownImport.typeshed_Incomplete()
457+
}

0 commit comments

Comments
 (0)