Skip to content

Commit

Permalink
Add --ignore-overloaded-functions flag to ignore overload decorators
Browse files Browse the repository at this point in the history
  • Loading branch information
ErwinJunge committed Dec 17, 2021
1 parent 8dbe125 commit 633aad2
Show file tree
Hide file tree
Showing 20 changed files with 332 additions and 163 deletions.
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ Configure within your ``pyproject.toml`` (``interrogate`` will automatically det
ignore-nested-functions = false
ignore-nested-classes = true
ignore-setters = false
ignore-overloaded-functions = false
fail-under = 95
exclude = ["setup.py", "docs", "build"]
ignore-regex = ["^get$", "^mock_.*", ".*BaseClass.*"]
Expand Down Expand Up @@ -391,6 +392,7 @@ Or configure within your ``setup.cfg`` (``interrogate`` will automatically detec
ignore-nested-functions = false
ignore-nested-classes = true
ignore-setters = false
ignore-overloaded-functions = false
fail-under = 95
exclude = setup.py,docs,build
ignore-regex = ^get$,^mock_.*,.*BaseClass.*
Expand Down Expand Up @@ -498,6 +500,10 @@ To view all options available, run ``interrogate --help``:
-C, --ignore-nested-classes Ignore nested classes. [default: False]
-O, --ignore-overloaded-functions
Ignore overloaded functions.
[default: False]
-p, --ignore-private Ignore private classes, methods, and
functions starting with two underscores.
[default: False]
Expand Down
9 changes: 9 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ Changelog

.. short-log
1.6.0 (UNRELEASED)
------------------

Added
^^^^^

* Add ``--ignore-overloaded-functions`` flag to ignore overload decorators (`#97 <https://github.com/econchick/interrogate/issues/97>`_).


1.5.0 (2021-09-10)
------------------

Expand Down
4 changes: 4 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ Command Line Options

Ignore nested classes. [default: ``False``]

.. option:: -O, --ignore-overloaded-functions

Ignore overloaded functions. [default: ``False``]

.. option:: -p, --ignore-private

Ignore private classes, methods, and functions starting with two underscores. [default: ``False``]
Expand Down
10 changes: 10 additions & 0 deletions src/interrogate/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@
show_default=True,
help="Ignore nested classes.",
)
@click.option(
"-O",
"--ignore-overloaded-functions",
is_flag=True,
default=False,
show_default=True,
help="Ignore overloaded functions.",
)
@click.option(
"-p",
"--ignore-private",
Expand Down Expand Up @@ -301,6 +309,7 @@ def main(ctx, paths, **kwargs):
.. versionadded:: 1.4.0 ``--ignore-setters``
.. versionadded:: 1.5.0 ``--omit-covered-files``
.. versionadded:: 1.5.0 ``--badge-style``
.. versionadded:: 1.6.0 ``--ignore-overloaded-functions``
.. versionchanged:: 1.3.1 only generate badge if results change from
an existing badge.
Expand Down Expand Up @@ -339,6 +348,7 @@ def main(ctx, paths, **kwargs):
ignore_init_module=kwargs["ignore_init_module"],
ignore_nested_classes=kwargs["ignore_nested_classes"],
ignore_nested_functions=kwargs["ignore_nested_functions"],
ignore_overloaded_functions=kwargs["ignore_overloaded_functions"],
ignore_property_setters=kwargs["ignore_setters"],
ignore_property_decorators=kwargs["ignore_property_decorators"],
include_regex=kwargs["whitelist_regex"],
Expand Down
2 changes: 2 additions & 0 deletions src/interrogate/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class InterrogateConfig:
function names to include.
:param bool omit_covered_files: Omit reporting files that have 100%
documentation coverage.
:param bool ignore_overloaded_functions: Ignore overloaded functions.
"""

color = attr.ib(default=False)
Expand All @@ -54,6 +55,7 @@ class InterrogateConfig:
ignore_nested_functions = attr.ib(default=False)
ignore_property_setters = attr.ib(default=False)
ignore_property_decorators = attr.ib(default=False)
ignore_overloaded_functions = attr.ib(default=False)
include_regex = attr.ib(default=False)
omit_covered_files = attr.ib(default=False)

Expand Down
26 changes: 26 additions & 0 deletions src/interrogate/visit.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,29 @@ def _has_setters(self, node):
return True
return False

def _has_overload_decorator(self, node):
"""Detect if node has a typing.overload decorator."""
if not hasattr(node, "decorator_list"):
return False

for dec in node.decorator_list:
if (
hasattr(dec, "attr")
and hasattr(dec, "value")
and hasattr(dec.value, "id")
and dec.value.id == "typing"
and dec.attr == "overload"
):
# @typing.overload decorator
return True
if (
hasattr(dec, "id")
and dec.id == "overload"
):
# @overload decorator
return True
return False

def _is_func_ignored(self, node):
"""Should the AST visitor ignore this func/method node."""
is_init = node.name == "__init__"
Expand All @@ -202,6 +225,7 @@ def _is_func_ignored(self, node):
)
has_property_decorators = self._has_property_decorators(node)
has_setters = self._has_setters(node)
has_overload = self._has_overload_decorator(node)

if self.config.ignore_init_method and is_init:
return True
Expand All @@ -211,6 +235,8 @@ def _is_func_ignored(self, node):
return True
if self.config.ignore_property_setters and has_setters:
return True
if self.config.ignore_overloaded_functions and has_overload:
return True

return self._is_ignored_common(node)

Expand Down
6 changes: 3 additions & 3 deletions tests/functional/fixtures/expected_badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 49 additions & 37 deletions tests/functional/fixtures/expected_detailed.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,58 @@
| empty.py (module) | MISSED |
|------------------------------------------------------------------|-----------|
| full.py (module) | COVERED |
| Foo (L5) | COVERED |
| Foo.__init__ (L8) | COVERED |
| Foo.__str__ (L12) | COVERED |
| Foo._semiprivate (L16) | COVERED |
| Foo.__private (L20) | COVERED |
| Foo.method_foo (L24) | COVERED |
| Foo.get (L28) | COVERED |
| Foo.get (L32) | COVERED |
| Foo.prop (L37) | COVERED |
| Foo.prop (L42) | COVERED |
| top_level_func (L47) | COVERED |
| top_level_func.inner_func (L50) | COVERED |
| Bar (L55) | COVERED |
| Bar.method_bar (L58) | COVERED |
| Bar.method_bar.InnerBar (L61) | COVERED |
| _SemiprivateClass (L67) | COVERED |
| __PrivateClass (L73) | COVERED |
| Foo (L8) | COVERED |
| Foo.__init__ (L11) | COVERED |
| Foo.__str__ (L15) | COVERED |
| Foo._semiprivate (L19) | COVERED |
| Foo.__private (L23) | COVERED |
| Foo.method_foo (L27) | COVERED |
| Foo.get (L31) | COVERED |
| Foo.get (L35) | COVERED |
| Foo.prop (L40) | COVERED |
| Foo.prop (L45) | COVERED |
| Foo.module_overload (L50) | COVERED |
| Foo.module_overload (L55) | COVERED |
| Foo.module_overload (L59) | COVERED |
| Foo.simple_overload (L64) | COVERED |
| Foo.simple_overload (L69) | COVERED |
| Foo.simple_overload (L73) | COVERED |
| top_level_func (L79) | COVERED |
| top_level_func.inner_func (L82) | COVERED |
| Bar (L87) | COVERED |
| Bar.method_bar (L90) | COVERED |
| Bar.method_bar.InnerBar (L93) | COVERED |
| _SemiprivateClass (L99) | COVERED |
| __PrivateClass (L105) | COVERED |
|------------------------------------------------------------------|-----------|
| partial.py (module) | COVERED |
| Foo (L5) | COVERED |
| Foo.__init__ (L8) | COVERED |
| Foo.__str__ (L12) | COVERED |
| Foo.__repr__ (L16) | MISSED |
| Foo._semiprivate_documented (L19) | COVERED |
| Foo._semiprivate_undocumented (L23) | MISSED |
| Foo.__private (L26) | MISSED |
| Foo.method_foo (L29) | MISSED |
| Foo.get (L32) | MISSED |
| Foo (L8) | COVERED |
| Foo.__init__ (L11) | COVERED |
| Foo.__str__ (L15) | COVERED |
| Foo.__repr__ (L19) | MISSED |
| Foo._semiprivate_documented (L22) | COVERED |
| Foo._semiprivate_undocumented (L26) | MISSED |
| Foo.__private (L29) | MISSED |
| Foo.method_foo (L32) | MISSED |
| Foo.get (L35) | MISSED |
| Foo.a_prop (L39) | MISSED |
| Foo.a_prop (L43) | MISSED |
| documented_top_level_func (L47) | COVERED |
| documented_top_level_func.documented_inner_func (L50) | COVERED |
| undocumented_top_level_func (L55) | MISSED |
| undocumented_top_level_func.undocumented_inner_func (L56) | MISSED |
| Bar (L60) | MISSED |
| Bar.method_bar (L61) | MISSED |
| Bar.method_bar.InnerBar (L62) | MISSED |
| _SemiprivateClass (L66) | MISSED |
| __PrivateClass (L70) | MISSED |
| Foo.get (L38) | MISSED |
| Foo.a_prop (L42) | MISSED |
| Foo.a_prop (L46) | MISSED |
| Foo.module_overload (L50) | MISSED |
| Foo.module_overload (L54) | MISSED |
| Foo.module_overload (L57) | COVERED |
| Foo.simple_overload (L62) | MISSED |
| Foo.simple_overload (L66) | MISSED |
| Foo.simple_overload (L69) | COVERED |
| documented_top_level_func (L74) | COVERED |
| documented_top_level_func.documented_inner_func (L77) | COVERED |
| undocumented_top_level_func (L82) | MISSED |
| undocumented_top_level_func.undocumented_inner_func (L83) | MISSED |
| Bar (L87) | MISSED |
| Bar.method_bar (L88) | MISSED |
| Bar.method_bar.InnerBar (L89) | MISSED |
| _SemiprivateClass (L93) | MISSED |
| __PrivateClass (L97) | MISSED |
|------------------------------------------------------------------|-----------|
| child_sample/__init__.py (module) | MISSED |
|------------------------------------------------------------------|-----------|
Expand Down
Loading

0 comments on commit 633aad2

Please sign in to comment.