Skip to content

Commit d366472

Browse files
committed
refine use of numpydoc parser
1 parent edc453f commit d366472

1 file changed

Lines changed: 19 additions & 7 deletions

File tree

control/tests/docstrings_test.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,19 @@ def test_parameter_docs(module, prefix):
137137
if obj.__doc__ is None:
138138
_warn(f"{module.__name__}.{name} is missing docstring", 2)
139139
continue
140+
elif doc is None:
141+
_fail(f"{module.__name__}.{name} docstring not parseable", 2)
140142
else:
141-
# TODO: use doc from above
142143
docstring = inspect.getdoc(obj)
143144
source = inspect.getsource(obj)
144145

145146
# Skip deprecated functions
146-
if ".. deprecated::" in docstring:
147+
doc_extended = "\n".join(doc["Extended Summary"])
148+
if ".. deprecated::" in doc_extended:
147149
_info(" [deprecated]", 2)
148150
continue
149-
elif re.search(name + r"(\(\))? is deprecated", docstring) or \
150-
"function is deprecated" in docstring:
151+
elif re.search(name + r"(\(\))? is deprecated", doc_extended) or \
152+
"function is deprecated" in doc_extended:
151153
_info(" [deprecated, but not numpydoc compliant]", 2)
152154
_warn(f"{name} deprecated, but not numpydoc compliant", 0)
153155
continue
@@ -258,6 +260,11 @@ def test_deprecated_functions(module, prefix):
258260
# Check member functions within the class
259261
test_deprecated_functions(obj, prefix + name + '.')
260262

263+
# Parse the docstring using numpydoc
264+
with warnings.catch_warnings():
265+
warnings.simplefilter('ignore') # debug via sphinx, not here
266+
doc = None if obj is None else npd.FunctionDoc(obj)
267+
261268
if inspect.isfunction(obj):
262269
# Skip anything that is inherited, hidden, or checked
263270
if inspect.isclass(module) and name not in module.__dict__ \
@@ -275,7 +282,8 @@ def test_deprecated_functions(module, prefix):
275282
source = inspect.getsource(obj)
276283

277284
# Look for functions marked as deprecated in doc string
278-
if ".. deprecated::" in docstring:
285+
doc_extended = "\n".join(doc["Extended Summary"])
286+
if ".. deprecated::" in doc_extended:
279287
# Make sure a FutureWarning is issued
280288
if not re.search("FutureWarning", source):
281289
_fail(f"{name} deprecated but does not issue FutureWarning")
@@ -380,6 +388,9 @@ def test_deprecated_functions(module, prefix):
380388
for cls in class_args.keys()])
381389
def test_iosys_primary_classes(cls, fcn, args):
382390
docstring = inspect.getdoc(cls)
391+
with warnings.catch_warnings():
392+
warnings.simplefilter('ignore') # debug via sphinx, not here
393+
doc = npd.FunctionDoc(cls)
383394

384395
# Make sure the typical arguments are there
385396
for argname in args + std_class_attributes + class_attributes[cls]:
@@ -389,7 +400,8 @@ def test_iosys_primary_classes(cls, fcn, args):
389400
if re.search(
390401
r"created.*(with|by|using).*the[\s]*"
391402
f":func:`~control\\..*{fcn.__name__}`"
392-
r"[\s]factory[\s]function", docstring, re.DOTALL) is None:
403+
r"[\s]factory[\s]function", "\n".join(doc["Extended Summary"]),
404+
re.DOTALL) is None:
393405
_fail(
394406
f"{cls.__name__} does not reference factory function "
395407
f"{fcn.__name__}")
@@ -629,7 +641,7 @@ def simple_function(arg1, arg2, opt1=None, **kwargs):
629641
doc_returns + doc_ret_nospace, Failed, "missing Parameters section"),
630642
(doc_header, None, ""),
631643
(doc_header + "\n.. deprecated::", None, ""),
632-
(doc_header + "\n simple_function() is deprecated",
644+
(doc_header + "\n\n simple_function() is deprecated",
633645
UserWarning, "deprecated, but not numpydoc compliant"),
634646
])
635647
def test_check_parameter_docs(docstring, exception, match):

0 commit comments

Comments
 (0)