mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
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:
commit
d82c8a7890
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
1
tests/roots/test-nitpicky-warnings/conf.py
Normal file
1
tests/roots/test-nitpicky-warnings/conf.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
nitpicky = True
|
7
tests/roots/test-nitpicky-warnings/index.rst
Normal file
7
tests/roots/test-nitpicky-warnings/index.rst
Normal 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`
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user