mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #7760 from Cielquan/feature/coverage_print_missing_as_warning
coverage ext - config to log missing coverage
This commit is contained in:
commit
07d19ebe02
@ -51,4 +51,11 @@ should check:
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
.. _Python regular expressions: https://docs.python.org/library/re
|
||||
.. conval:: coverage_show_missing_items
|
||||
|
||||
Print objects that are missing to standard output also.
|
||||
``False`` by default.
|
||||
|
||||
.. versionadded:: 3.1
|
||||
|
||||
.. _Python regular expressions: https://docs.python.org/library/re
|
||||
|
@ -22,6 +22,7 @@ from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.console import red # type: ignore
|
||||
from sphinx.util.inspect import safe_getattr
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -121,6 +122,14 @@ class CoverageBuilder(Builder):
|
||||
write_header(op, filename)
|
||||
for typ, name in sorted(undoc):
|
||||
op.write(' * %-50s [%9s]\n' % (name, typ))
|
||||
if self.config.coverage_show_missing_items:
|
||||
if self.app.quiet or self.app.warningiserror:
|
||||
logger.warning(__('undocumented c api: %s [%s] in file %s'),
|
||||
name, typ, filename)
|
||||
else:
|
||||
logger.info(red('undocumented ') + 'c ' + 'api ' +
|
||||
'%-30s' % (name + " [%9s]" % typ) +
|
||||
red(' - in file ') + filename)
|
||||
op.write('\n')
|
||||
|
||||
def ignore_pyobj(self, full_name: str) -> bool:
|
||||
@ -239,16 +248,48 @@ class CoverageBuilder(Builder):
|
||||
if undoc['funcs']:
|
||||
op.write('Functions:\n')
|
||||
op.writelines(' * %s\n' % x for x in undoc['funcs'])
|
||||
if self.config.coverage_show_missing_items:
|
||||
if self.app.quiet or self.app.warningiserror:
|
||||
for func in undoc['funcs']:
|
||||
logger.warning(
|
||||
__('undocumented python function: %s :: %s'),
|
||||
name, func)
|
||||
else:
|
||||
for func in undoc['funcs']:
|
||||
logger.info(red('undocumented ') + 'py ' + 'function ' +
|
||||
'%-30s' % func + red(' - in module ') + name)
|
||||
op.write('\n')
|
||||
if undoc['classes']:
|
||||
op.write('Classes:\n')
|
||||
for name, methods in sorted(
|
||||
for class_name, methods in sorted(
|
||||
undoc['classes'].items()):
|
||||
if not methods:
|
||||
op.write(' * %s\n' % name)
|
||||
op.write(' * %s\n' % class_name)
|
||||
if self.config.coverage_show_missing_items:
|
||||
if self.app.quiet or self.app.warningiserror:
|
||||
logger.warning(
|
||||
__('undocumented python class: %s :: %s'),
|
||||
name, class_name)
|
||||
else:
|
||||
logger.info(red('undocumented ') + 'py ' +
|
||||
'class ' + '%-30s' % class_name +
|
||||
red(' - in module ') + name)
|
||||
else:
|
||||
op.write(' * %s -- missing methods:\n\n' % name)
|
||||
op.write(' * %s -- missing methods:\n\n' % class_name)
|
||||
op.writelines(' - %s\n' % x for x in methods)
|
||||
if self.config.coverage_show_missing_items:
|
||||
if self.app.quiet or self.app.warningiserror:
|
||||
for meth in methods:
|
||||
logger.warning(
|
||||
__('undocumented python method:' +
|
||||
' %s :: %s :: %s'),
|
||||
name, class_name, meth)
|
||||
else:
|
||||
for meth in methods:
|
||||
logger.info(red('undocumented ') + 'py ' +
|
||||
'method ' + '%-30s' %
|
||||
(class_name + '.' + meth) +
|
||||
red(' - in module ') + name)
|
||||
op.write('\n')
|
||||
|
||||
if failed:
|
||||
@ -273,4 +314,5 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_config_value('coverage_ignore_c_items', {}, False)
|
||||
app.add_config_value('coverage_write_headline', True, False)
|
||||
app.add_config_value('coverage_skip_undoc_in_source', False, False)
|
||||
app.add_config_value('coverage_show_missing_items', False, False)
|
||||
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
|
||||
|
@ -28,6 +28,8 @@ def test_build(app, status, warning):
|
||||
|
||||
assert ' * mod -- No module named mod' # in the "failed import" section
|
||||
|
||||
assert "undocumented py" not in status.getvalue()
|
||||
|
||||
c_undoc = (app.outdir / 'c.txt').read_text()
|
||||
assert c_undoc.startswith('Undocumented C API elements\n'
|
||||
'===========================\n')
|
||||
@ -46,6 +48,8 @@ def test_build(app, status, warning):
|
||||
assert 'Class' in undoc_py['autodoc_target']['classes']
|
||||
assert 'undocmeth' in undoc_py['autodoc_target']['classes']['Class']
|
||||
|
||||
assert "undocumented c" not in status.getvalue()
|
||||
|
||||
|
||||
@pytest.mark.sphinx('coverage', testroot='ext-coverage')
|
||||
def test_coverage_ignore_pyobjects(app, status, warning):
|
||||
@ -64,3 +68,28 @@ Classes:
|
||||
|
||||
'''
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.sphinx('coverage', confoverrides={'coverage_show_missing_items': True})
|
||||
def test_show_missing_items(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
assert "undocumented" in status.getvalue()
|
||||
|
||||
assert "py function raises" in status.getvalue()
|
||||
assert "py class Base" in status.getvalue()
|
||||
assert "py method Class.roger" in status.getvalue()
|
||||
|
||||
assert "c api Py_SphinxTest [ function]" in status.getvalue()
|
||||
|
||||
|
||||
@pytest.mark.sphinx('coverage', confoverrides={'coverage_show_missing_items': True})
|
||||
def test_show_missing_items_quiet(app, status, warning):
|
||||
app.quiet = True
|
||||
app.builder.build_all()
|
||||
|
||||
assert "undocumented python function: autodoc_target :: raises" in warning.getvalue()
|
||||
assert "undocumented python class: autodoc_target :: Base" in warning.getvalue()
|
||||
assert "undocumented python method: autodoc_target :: Class :: roger" in warning.getvalue()
|
||||
|
||||
assert "undocumented c api: Py_SphinxTest [function]" in warning.getvalue()
|
||||
|
Loading…
Reference in New Issue
Block a user