Skip to content

Commit c676969

Browse files
committed
Add numpydoc_validation_overrides option to Sphinx extension side.
1 parent c2e7ddc commit c676969

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

numpydoc/numpydoc.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,19 @@ def mangle_docstrings(app, what, name, obj, options, lines):
207207
# TODO: Currently, all validation checks are run and only those
208208
# selected via config are reported. It would be more efficient to
209209
# only run the selected checks.
210-
errors = validate(doc)["errors"]
210+
report = validate(doc)
211+
errors = [
212+
err
213+
for err in report["errors"]
214+
if not (
215+
(
216+
overrides := app.config.numpydoc_validation_overrides.get(
217+
err[0]
218+
)
219+
)
220+
and re.search(overrides, report["docstring"])
221+
)
222+
]
211223
if {err[0] for err in errors} & app.config.numpydoc_validation_checks:
212224
msg = (
213225
f"[numpydoc] Validation warnings while processing "
@@ -285,6 +297,7 @@ def setup(app, get_doc_object_=get_doc_object):
285297
app.add_config_value("numpydoc_xref_ignore", set(), True)
286298
app.add_config_value("numpydoc_validation_checks", set(), True)
287299
app.add_config_value("numpydoc_validation_exclude", set(), False)
300+
app.add_config_value("numpydoc_validation_overrides", dict(), False)
288301

289302
# Extra mangling domains
290303
app.add_domain(NumpyPythonDomain)
@@ -327,6 +340,11 @@ def update_config(app, config=None):
327340
)
328341
config.numpydoc_validation_excluder = exclude_expr
329342

343+
for check, patterns in config.numpydoc_validation_overrides.items():
344+
config.numpydoc_validation_overrides[check] = re.compile(
345+
r"|".join(exp for exp in patterns)
346+
)
347+
330348

331349
# ------------------------------------------------------------------------------
332350
# Docstring-mangling domains

numpydoc/tests/test_docscrape.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,7 @@ def __init__(self, a, b):
15761576
# numpydoc.update_config fails if this config option not present
15771577
self.numpydoc_validation_checks = set()
15781578
self.numpydoc_validation_exclude = set()
1579+
self.numpydoc_validation_overrides = dict()
15791580

15801581
xref_aliases_complete = deepcopy(DEFAULT_LINKS)
15811582
for key in xref_aliases:

numpydoc/tests/test_numpydoc.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class MockConfig:
2323
numpydoc_attributes_as_param_list = True
2424
numpydoc_validation_checks = set()
2525
numpydoc_validation_exclude = set()
26+
numpydoc_validation_overrides = dict()
2627

2728

2829
class MockBuilder:
@@ -212,6 +213,39 @@ def function_with_bad_docstring():
212213
assert warning.getvalue() == ""
213214

214215

216+
@pytest.mark.parametrize("overrides", [{}, {"SS02"}, {"SS02", "SS03"}])
217+
def test_mangle_docstrings_overrides(overrides):
218+
def process_something_noop_function():
219+
"""Process something."""
220+
221+
app = MockApp()
222+
app.config.numpydoc_validation_checks = {"all"}
223+
app.config.numpydoc_validation_overrides = {
224+
check: [r"^Process "] # overrides are regex on docstring content
225+
for check in overrides
226+
}
227+
update_config(app)
228+
229+
# Setup for catching warnings
230+
status, warning = StringIO(), StringIO()
231+
logging.setup(app, status, warning)
232+
233+
# Run mangle docstrings on process_something_noop_function
234+
mangle_docstrings(
235+
app,
236+
"function",
237+
process_something_noop_function.__name__,
238+
process_something_noop_function,
239+
None,
240+
process_something_noop_function.__doc__.split("\n"),
241+
)
242+
243+
findings = warning.getvalue()
244+
assert " EX01: " in findings # should always be there
245+
for check in overrides:
246+
assert f" {check}: " not in findings
247+
248+
215249
def test_update_config_invalid_validation_set():
216250
app = MockApp()
217251
# Results in {'a', 'l'} instead of {"all"}

0 commit comments

Comments
 (0)