mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #3926: Add `autodoc_warningiserror
to suppress the behavior of
-W
` option
This commit is contained in:
parent
bb79a0c4d0
commit
bfd71cd77b
3
CHANGES
3
CHANGES
@ -13,6 +13,9 @@ Deprecated
|
||||
Features added
|
||||
--------------
|
||||
|
||||
* #3926: Add ``autodoc_warningiserror`` to suppress the behavior of ``-W``
|
||||
option during importing target modules on autodoc
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
|
@ -386,6 +386,13 @@ There are also new config values that you can set:
|
||||
This config value only requires to declare the top-level modules that
|
||||
should be mocked.
|
||||
|
||||
.. confval:: autodoc_warningiserror
|
||||
|
||||
This value controls the behavior of :option:`sphinx-build -W` during
|
||||
importing modules.
|
||||
If ``False`` is given, autodoc forcely suppresses the error if the imported
|
||||
module emits warnings. By default, ``True``.
|
||||
|
||||
Docstring preprocessing
|
||||
-----------------------
|
||||
|
||||
|
@ -654,7 +654,8 @@ class Documenter(object):
|
||||
logger.debug('[autodoc] import %s', self.modname)
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings("ignore", category=ImportWarning)
|
||||
__import__(self.modname)
|
||||
with logging.skip_warningiserror(not self.env.config.autodoc_warningiserror):
|
||||
__import__(self.modname)
|
||||
parent = None
|
||||
obj = self.module = sys.modules[self.modname]
|
||||
logger.debug('[autodoc] => %r', obj)
|
||||
@ -1883,6 +1884,7 @@ def setup(app):
|
||||
app.add_config_value('autodoc_default_flags', [], True)
|
||||
app.add_config_value('autodoc_docstring_signature', True, True)
|
||||
app.add_config_value('autodoc_mock_imports', [], True)
|
||||
app.add_config_value('autodoc_warningiserror', True, True)
|
||||
app.add_event('autodoc-process-docstring')
|
||||
app.add_event('autodoc-process-signature')
|
||||
app.add_event('autodoc-skip-member')
|
||||
|
@ -249,6 +249,27 @@ def pending_logging():
|
||||
memhandler.flushTo(logger)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def skip_warningiserror(skip=True):
|
||||
# type: (bool) -> Generator
|
||||
"""contextmanager to skip WarningIsErrorFilter for a while."""
|
||||
logger = logging.getLogger()
|
||||
|
||||
if skip is False:
|
||||
yield
|
||||
else:
|
||||
try:
|
||||
disabler = DisableWarningIsErrorFilter()
|
||||
for handler in logger.handlers:
|
||||
# use internal method; filters.insert() directly to install disabler
|
||||
# before WarningIsErrorFilter
|
||||
handler.filters.insert(0, disabler)
|
||||
yield
|
||||
finally:
|
||||
for handler in logger.handlers:
|
||||
handler.removeFilter(disabler)
|
||||
|
||||
|
||||
class LogCollector(object):
|
||||
def __init__(self):
|
||||
# type: () -> None
|
||||
@ -330,7 +351,10 @@ class WarningIsErrorFilter(logging.Filter):
|
||||
|
||||
def filter(self, record):
|
||||
# type: (logging.LogRecord) -> bool
|
||||
if self.app.warningiserror:
|
||||
if getattr(record, 'skip_warningsiserror', False):
|
||||
# disabled by DisableWarningIsErrorFilter
|
||||
return True
|
||||
elif self.app.warningiserror:
|
||||
location = getattr(record, 'location', '')
|
||||
if location:
|
||||
raise SphinxWarning(location + ":" + record.msg % record.args)
|
||||
@ -340,6 +364,15 @@ class WarningIsErrorFilter(logging.Filter):
|
||||
return True
|
||||
|
||||
|
||||
class DisableWarningIsErrorFilter(logging.Filter):
|
||||
"""Disable WarningIsErrorFilter if this filter installed."""
|
||||
|
||||
def filter(self, record):
|
||||
# type: (logging.LogRecord) -> bool
|
||||
record.skip_warningsiserror = True # type: ignore
|
||||
return True
|
||||
|
||||
|
||||
class WarningLogRecordTranslator(logging.Filter):
|
||||
"""Converts a log record to one Sphinx expects
|
||||
|
||||
|
@ -272,3 +272,27 @@ def test_output_with_unencodable_char(app, status, warning):
|
||||
status.seek(0)
|
||||
logger.info(u"unicode \u206d...")
|
||||
assert status.getvalue() == "unicode ?...\n"
|
||||
|
||||
|
||||
def test_skip_warningiserror(app, status, warning):
|
||||
logging.setup(app, status, warning)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
app.warningiserror = True
|
||||
with logging.skip_warningiserror():
|
||||
logger.warning('message')
|
||||
|
||||
# if False, warning raises SphinxWarning exception
|
||||
with pytest.raises(SphinxWarning):
|
||||
with logging.skip_warningiserror(False):
|
||||
logger.warning('message')
|
||||
|
||||
# It also works during pending_warnings.
|
||||
with logging.pending_warnings():
|
||||
with logging.skip_warningiserror():
|
||||
logger.warning('message')
|
||||
|
||||
with pytest.raises(SphinxWarning):
|
||||
with logging.pending_warnings():
|
||||
with logging.skip_warningiserror(False):
|
||||
logger.warning('message')
|
||||
|
Loading…
Reference in New Issue
Block a user