From c39ed6efbd6126599e5ff6a8180fef0b52086798 Mon Sep 17 00:00:00 2001 From: Cielquan Date: Sun, 31 May 2020 12:43:47 +0200 Subject: [PATCH 1/8] added config to log missing c/py coverage --- sphinx/ext/coverage.py | 49 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index e8157848f..a5defd894 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -22,6 +22,9 @@ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.locale import __ from sphinx.util import logging +from sphinx.util.console import ( # type: ignore + blue, darkblue, darkgreen, green, red, teal, turquoise +) from sphinx.util.inspect import safe_getattr logger = logging.getLogger(__name__) @@ -121,6 +124,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_print_missing_c_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 ') + darkgreen('c ') + + darkblue('api ') + '%-30s' % (name + " [%9s]" % typ) + + red(' - in file ') + filename) op.write('\n') def ignore_pyobj(self, full_name: str) -> bool: @@ -239,16 +250,46 @@ class CoverageBuilder(Builder): if undoc['funcs']: op.write('Functions:\n') op.writelines(' * %s\n' % x for x in undoc['funcs']) + if self.config.coverage_print_missing_py_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 ') + green('py ') + + teal('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_print_missing_py_items: + if self.app.quiet or self.app.warningiserror: + logger.warning(__('undocumented python class: %s :: %s'), + name, class_name) + else: + logger.info(red('undocumented ') + green('py ') + + blue('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_print_missing_py_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 ') + green('py ') + + turquoise('method ') + '%-30s' % + (class_name + '.' + meth) + + red(' - in module ') + name) op.write('\n') if failed: @@ -273,4 +314,6 @@ 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_print_missing_c_items', False, False) + app.add_config_value('coverage_print_missing_py_items', False, False) return {'version': sphinx.__display_version__, 'parallel_read_safe': True} From e6cf7c0922276bf26e0662680a6be8cf6f1e1ccf Mon Sep 17 00:00:00 2001 From: Cielquan Date: Sun, 31 May 2020 16:17:56 +0200 Subject: [PATCH 2/8] merged new config options into coverage_show_missing_items --- sphinx/ext/coverage.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index a5defd894..e8196bb4a 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -124,7 +124,7 @@ class CoverageBuilder(Builder): write_header(op, filename) for typ, name in sorted(undoc): op.write(' * %-50s [%9s]\n' % (name, typ)) - if self.config.coverage_print_missing_c_items: + 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) @@ -250,7 +250,7 @@ class CoverageBuilder(Builder): if undoc['funcs']: op.write('Functions:\n') op.writelines(' * %s\n' % x for x in undoc['funcs']) - if self.config.coverage_print_missing_py_items: + 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'), @@ -267,7 +267,7 @@ class CoverageBuilder(Builder): undoc['classes'].items()): if not methods: op.write(' * %s\n' % class_name) - if self.config.coverage_print_missing_py_items: + 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) @@ -278,7 +278,7 @@ class CoverageBuilder(Builder): else: op.write(' * %s -- missing methods:\n\n' % class_name) op.writelines(' - %s\n' % x for x in methods) - if self.config.coverage_print_missing_py_items: + if self.config.coverage_show_missing_items: if self.app.quiet or self.app.warningiserror: for meth in methods: logger.warning( @@ -314,6 +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_print_missing_c_items', False, False) - app.add_config_value('coverage_print_missing_py_items', False, False) + app.add_config_value('coverage_show_missing_items', False, False) return {'version': sphinx.__display_version__, 'parallel_read_safe': True} From baaa32c4a30cff751d0f1fd4b37c7f22582b9688 Mon Sep 17 00:00:00 2001 From: Cielquan Date: Sun, 31 May 2020 16:40:37 +0200 Subject: [PATCH 3/8] fixed line length --- sphinx/ext/coverage.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index e8196bb4a..064a2cb36 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -130,7 +130,8 @@ class CoverageBuilder(Builder): name, typ, filename) else: logger.info(red('undocumented ') + darkgreen('c ') + - darkblue('api ') + '%-30s' % (name + " [%9s]" % typ) + + darkblue('api ') + + '%-30s' % (name + " [%9s]" % typ) + red(' - in file ') + filename) op.write('\n') @@ -253,8 +254,9 @@ class CoverageBuilder(Builder): 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) + logger.warning( + __('undocumented python function: %s :: %s'), + name, func) else: for func in undoc['funcs']: logger.info(red('undocumented ') + green('py ') + @@ -269,8 +271,9 @@ class CoverageBuilder(Builder): 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) + logger.warning( + __('undocumented python class: %s :: %s'), + name, class_name) else: logger.info(red('undocumented ') + green('py ') + blue('class ') + '%-30s' % class_name + @@ -282,7 +285,8 @@ class CoverageBuilder(Builder): if self.app.quiet or self.app.warningiserror: for meth in methods: logger.warning( - __('undocumented python method: %s :: %s :: %s'), + __('undocumented python method:' + + ' %s :: %s :: %s'), name, class_name, meth) else: for meth in methods: From 754b48c8d66dd327289a83e9eea704c3e12e3377 Mon Sep 17 00:00:00 2001 From: Cielquan Date: Sun, 31 May 2020 16:49:02 +0200 Subject: [PATCH 4/8] reduced colors on info level --- sphinx/ext/coverage.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index 064a2cb36..3d186f0cb 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -129,8 +129,7 @@ class CoverageBuilder(Builder): logger.warning(__('undocumented c api: %s [%s] in file %s'), name, typ, filename) else: - logger.info(red('undocumented ') + darkgreen('c ') + - darkblue('api ') + + logger.info(red('undocumented ') + 'c ' + 'api ' + '%-30s' % (name + " [%9s]" % typ) + red(' - in file ') + filename) op.write('\n') @@ -259,9 +258,8 @@ class CoverageBuilder(Builder): name, func) else: for func in undoc['funcs']: - logger.info(red('undocumented ') + green('py ') + - teal('function ') + '%-30s' % func + - red(' - in module ') + name) + logger.info(red('undocumented ') + 'py ' + 'function ' + + '%-30s' % func + red(' - in module ') + name) op.write('\n') if undoc['classes']: op.write('Classes:\n') @@ -275,8 +273,8 @@ class CoverageBuilder(Builder): __('undocumented python class: %s :: %s'), name, class_name) else: - logger.info(red('undocumented ') + green('py ') + - blue('class ') + '%-30s' % class_name + + logger.info(red('undocumented ') + 'py ' + + 'class ' + '%-30s' % class_name + red(' - in module ') + name) else: op.write(' * %s -- missing methods:\n\n' % class_name) @@ -290,8 +288,8 @@ class CoverageBuilder(Builder): name, class_name, meth) else: for meth in methods: - logger.info(red('undocumented ') + green('py ') + - turquoise('method ') + '%-30s' % + logger.info(red('undocumented ') + 'py ' + + 'method ' + '%-30s' % (class_name + '.' + meth) + red(' - in module ') + name) op.write('\n') From d83f34794cdcb8b07d3f67e2ee7acf8f15295cf4 Mon Sep 17 00:00:00 2001 From: Cielquan Date: Sun, 31 May 2020 17:56:14 +0200 Subject: [PATCH 5/8] fixed color imports in coverage.py --- sphinx/ext/coverage.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index 3d186f0cb..536b3b9d2 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -22,9 +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 ( # type: ignore - blue, darkblue, darkgreen, green, red, teal, turquoise -) +from sphinx.util.console import red # type: ignore from sphinx.util.inspect import safe_getattr logger = logging.getLogger(__name__) From 42b755db2e8e2d6f0540e7208d190302f3ac611d Mon Sep 17 00:00:00 2001 From: Cielquan Date: Sun, 31 May 2020 18:38:21 +0200 Subject: [PATCH 6/8] added test for show_missing_items True --- tests/test_ext_coverage.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_ext_coverage.py b/tests/test_ext_coverage.py index 16f53112b..1ac828dc5 100644 --- a/tests/test_ext_coverage.py +++ b/tests/test_ext_coverage.py @@ -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,16 @@ 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() From cc1f15246c42556a94248a8e4abc2ee13695ea82 Mon Sep 17 00:00:00 2001 From: Cielquan Date: Fri, 5 Jun 2020 09:26:53 +0200 Subject: [PATCH 7/8] added test for show_missing_items True in quiet mode --- tests/test_ext_coverage.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_ext_coverage.py b/tests/test_ext_coverage.py index 1ac828dc5..033a1c1b1 100644 --- a/tests/test_ext_coverage.py +++ b/tests/test_ext_coverage.py @@ -81,3 +81,15 @@ def test_show_missing_items(app, status, warning): 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() From f33eb15b83deb37aac98cb6b7e51d82b8f36739b Mon Sep 17 00:00:00 2001 From: Christian Riedel Date: Fri, 5 Jun 2020 17:42:26 +0200 Subject: [PATCH 8/8] documented coverage_show_missing_items confval --- doc/usage/extensions/coverage.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/usage/extensions/coverage.rst b/doc/usage/extensions/coverage.rst index 46d31053c..8c8054d5f 100644 --- a/doc/usage/extensions/coverage.rst +++ b/doc/usage/extensions/coverage.rst @@ -51,4 +51,11 @@ should check: .. versionadded:: 1.1 -.. _Python regular expressions: https://docs.python.org/library/re \ No newline at end of file +.. 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