Skip to content

Commit 0cc031c

Browse files
committed
refine use of numpydoc parser
1 parent 00eaa24 commit 0cc031c

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

control/tests/docstrings_test.py

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

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

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

278285
# Look for functions marked as deprecated in doc string
279-
if ".. deprecated::" in docstring:
286+
doc_extended = "\n".join(doc["Extended Summary"])
287+
if ".. deprecated::" in doc_extended:
280288
# Make sure a FutureWarning is issued
281289
if not re.search("FutureWarning", source):
282290
_fail(f"{name} deprecated but does not issue FutureWarning")
@@ -382,6 +390,9 @@ def test_deprecated_functions(module, prefix):
382390
for cls in class_args.keys()])
383391
def test_iosys_primary_classes(cls, fcn, args):
384392
docstring = inspect.getdoc(cls)
393+
with warnings.catch_warnings():
394+
warnings.simplefilter('ignore') # debug via sphinx, not here
395+
doc = npd.FunctionDoc(cls)
385396

386397
# Make sure the typical arguments are there
387398
for argname in args + std_class_attributes + class_attributes[cls]:
@@ -391,7 +402,8 @@ def test_iosys_primary_classes(cls, fcn, args):
391402
if re.search(
392403
r"created.*(with|by|using).*the[\s]*"
393404
f":func:`~control\\..*{fcn.__name__}`"
394-
r"[\s]factory[\s]function", docstring, re.DOTALL) is None:
405+
r"[\s]factory[\s]function", "\n".join(doc["Extended Summary"]),
406+
re.DOTALL) is None:
395407
_fail(
396408
f"{cls.__name__} does not reference factory function "
397409
f"{fcn.__name__}")
@@ -631,7 +643,7 @@ def simple_function(arg1, arg2, opt1=None, **kwargs):
631643
doc_returns + doc_ret_nospace, Failed, "missing Parameters section"),
632644
(doc_header, None, ""),
633645
(doc_header + "\n.. deprecated::", None, ""),
634-
(doc_header + "\n simple_function() is deprecated",
646+
(doc_header + "\n\n simple_function() is deprecated",
635647
UserWarning, "deprecated, but not numpydoc compliant"),
636648
])
637649
def test_check_parameter_docs(docstring, exception, match):

0 commit comments

Comments
 (0)