Merge pull request #9131 from RuRo/feature/glob-nitpick-ignore

Ignore nitpick warnings with regular expressions using `nitpick_ignore_regex`
This commit is contained in:
Takeshi KOMIYA 2021-05-05 23:43:46 +09:00 committed by GitHub
commit d82c8a7890
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 1 deletions

View File

@ -419,6 +419,20 @@ General configuration
.. versionadded:: 1.1 .. versionadded:: 1.1
.. confval:: nitpick_ignore_regex
An extended version of :confval:`nitpick_ignore`, which instead interprets
the ``type`` and ``target`` strings as regular expressions. Note, that the
regular expression must match the whole string (as if the ``^`` and ``$``
markers were inserted).
For example, ``(r'py:.*', r'foo.*bar\.B.*')`` will ignore nitpicky warnings
for all python entities that start with ``'foo'`` and have ``'bar.B'`` in
them, such as ``('py:const', 'foo_package.bar.BAZ_VALUE')`` or
``('py:class', 'food.bar.Barman')``.
.. versionadded:: 4.1
.. confval:: numfig .. confval:: numfig
If true, figures, tables and code-blocks are automatically numbered if they If true, figures, tables and code-blocks are automatically numbered if they

View File

@ -131,6 +131,7 @@ class Config:
'manpages_url': (None, 'env', []), 'manpages_url': (None, 'env', []),
'nitpicky': (False, None, []), 'nitpicky': (False, None, []),
'nitpick_ignore': ([], None, []), 'nitpick_ignore': ([], None, []),
'nitpick_ignore_regex': ([], None, []),
'numfig': (False, 'env', []), 'numfig': (False, 'env', []),
'numfig_secnum_depth': (1, 'env', []), 'numfig_secnum_depth': (1, 'env', []),
'numfig_format': ({}, 'env', []), # will be initialized in init_numfig_format() 'numfig_format': ({}, 'env', []), # will be initialized in init_numfig_format()

View File

@ -8,6 +8,7 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
import re
from typing import Any, Dict, List, Optional, Tuple, Type, cast from typing import Any, Dict, List, Optional, Tuple, Type, cast
from docutils import nodes from docutils import nodes
@ -171,14 +172,27 @@ class ReferencesResolver(SphinxPostTransform):
warn = node.get('refwarn') warn = node.get('refwarn')
if self.config.nitpicky: if self.config.nitpicky:
warn = True warn = True
dtype = '%s:%s' % (domain.name, typ) if domain else typ
if self.config.nitpick_ignore: if self.config.nitpick_ignore:
dtype = '%s:%s' % (domain.name, typ) if domain else typ
if (dtype, target) in self.config.nitpick_ignore: if (dtype, target) in self.config.nitpick_ignore:
warn = False warn = False
# for "std" types also try without domain name # for "std" types also try without domain name
if (not domain or domain.name == 'std') and \ if (not domain or domain.name == 'std') and \
(typ, target) in self.config.nitpick_ignore: (typ, target) in self.config.nitpick_ignore:
warn = False warn = False
if self.config.nitpick_ignore_regex:
def matches_ignore(entry_type: str, entry_target: str) -> bool:
for ignore_type, ignore_target in self.config.nitpick_ignore_regex:
if re.fullmatch(ignore_type, entry_type) and \
re.fullmatch(ignore_target, entry_target):
return True
return False
if matches_ignore(dtype, target):
warn = False
# for "std" types also try without domain name
if (not domain or domain.name == 'std') and \
matches_ignore(typ, target):
warn = False
if not warn: if not warn:
return return

View File

@ -0,0 +1 @@
nitpicky = True

View File

@ -0,0 +1,7 @@
test-nitpicky-warnings
======================
:py:const:`prefix.anything.postfix`
:py:class:`prefix.anything`
:py:class:`anything.postfix`
:js:class:`prefix.anything.postfix`

View File

@ -311,3 +311,77 @@ def test_check_enum_for_list_failed(logger):
config.init_values() config.init_values()
check_confval_types(None, config) check_confval_types(None, config)
assert logger.warning.called assert logger.warning.called
nitpick_warnings = [
"WARNING: py:const reference target not found: prefix.anything.postfix",
"WARNING: py:class reference target not found: prefix.anything",
"WARNING: py:class reference target not found: anything.postfix",
"WARNING: js:class reference target not found: prefix.anything.postfix",
]
@pytest.mark.sphinx(testroot='nitpicky-warnings')
def test_nitpick_base(app, status, warning):
app.builder.build_all()
warning = warning.getvalue().strip().split('\n')
assert len(warning) == len(nitpick_warnings)
for actual, expected in zip(warning, nitpick_warnings):
assert expected in actual
@pytest.mark.sphinx(testroot='nitpicky-warnings', confoverrides={
'nitpick_ignore': [
('py:const', 'prefix.anything.postfix'),
('py:class', 'prefix.anything'),
('py:class', 'anything.postfix'),
('js:class', 'prefix.anything.postfix'),
],
})
def test_nitpick_ignore(app, status, warning):
app.builder.build_all()
assert not len(warning.getvalue().strip())
@pytest.mark.sphinx(testroot='nitpicky-warnings', confoverrides={
'nitpick_ignore_regex': [
(r'py:.*', r'.*postfix'),
(r'.*:class', r'prefix.*'),
]
})
def test_nitpick_ignore_regex1(app, status, warning):
app.builder.build_all()
assert not len(warning.getvalue().strip())
@pytest.mark.sphinx(testroot='nitpicky-warnings', confoverrides={
'nitpick_ignore_regex': [
(r'py:.*', r'prefix.*'),
(r'.*:class', r'.*postfix'),
]
})
def test_nitpick_ignore_regex2(app, status, warning):
app.builder.build_all()
assert not len(warning.getvalue().strip())
@pytest.mark.sphinx(testroot='nitpicky-warnings', confoverrides={
'nitpick_ignore_regex': [
# None of these should match
(r'py:', r'.*'),
(r':class', r'.*'),
(r'', r'.*'),
(r'.*', r'anything'),
(r'.*', r'prefix'),
(r'.*', r'postfix'),
(r'.*', r''),
]
})
def test_nitpick_ignore_regex_fullmatch(app, status, warning):
app.builder.build_all()
warning = warning.getvalue().strip().split('\n')
assert len(warning) == len(nitpick_warnings)
for actual, expected in zip(warning, nitpick_warnings):
assert expected in actual