Repository: econchick/interrogate

Issue:
"exclude" does not exclude files if passed in via args
### Environment
<!-- Please include if you've confirmed one version of something works while another one does not -->
- `interrogate` version(s) (`interrogate --version`:
- Operating System(s):
- Python version(s):

### Description of the bug

I'm planning on using interrogate as part of our CI/CD process. Thus I will run the following for a PR, only checking files that have changed:
```
interrogate -c pyproject.toml -vv $(gh pr view NUMBER --json files --jq '.files | map(select(.path | endswith(".py"))) | .[].path')
``` 

`pyproject.toml` contains `exclude` definitions which are not adhered to if files are passed into via args.


### What you expected to happen
```
[tool.interrogate]
exclude = ["test.py"]
```

```
interrogate -c pyproject.tom -vv test.py
E: No Python files found to interrogate
```

### How to reproduce (as minimally and precisely as possible)
<!-- If applicable, add screenshots to help explain your problem. -->

```
touch test.py
echo "[tool.interrogate]\nexclude = [\"test.py\"]" > pyproject.toml
interrogate -c pyproject.toml -vv test.py
```


### Anthing else we need to know?
<!-- Add any other context about the problem here. -->

Hints from issue comments:
@jimrybarski: See https://github.com/econchick/interrogate/pull/159

Solution patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index aeb5a41..903a47a 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -3,41 +3,38 @@ ci:
   autoupdate_schedule: monthly
 
 repos:
-  - repo: local
+  - repo: https://github.com/econchick/interrogate
+    rev: 1.5.0
     hooks:
       - id: interrogate
-        name: interrogate
-        language: system
-        entry: interrogate
-        types: [python]
         exclude: ^(docs/conf.py|setup.py|tests/functional/sample)
         args: [--config=pyproject.toml]
 
   - repo: https://github.com/psf/black
-    rev: 23.7.0
+    rev: 24.3.0
     hooks:
       - id: black
 
   - repo: https://github.com/asottile/pyupgrade
-    rev: v3.10.1
+    rev: v3.15.2
     hooks:
       - id: pyupgrade
         args: [--py38-plus]
 
   - repo: https://github.com/pycqa/isort
-    rev: 5.12.0
+    rev: 5.13.2
     hooks:
       - id: isort
         additional_dependencies: [toml]
 
   - repo: https://github.com/pycqa/flake8
-    rev: 6.1.0
+    rev: 7.0.0
     hooks:
       - id: flake8
         exclude: ^(tests/functional/sample)
 
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.4.0
+    rev: v4.5.0
     hooks:
       - id: trailing-whitespace
       - id: end-of-file-fixer
diff --git a/README.rst b/README.rst
index 9e1df1a..a5a4e9b 100644
--- a/README.rst
+++ b/README.rst
@@ -322,6 +322,7 @@ Or use it with `pre-commit <https://pre-commit.com/>`_:
         hooks:
           - id: interrogate
             args: [--quiet, --fail-under=95]
+            pass_filenames: false  # needed if excluding files with pyproject.toml or setup.cfg
 
 Use it within your code directly:
 
@@ -359,6 +360,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.*"]
@@ -391,6 +393,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.*
@@ -498,6 +501,10 @@ To view all options available, run ``interrogate --help``:
 
       -C, --ignore-nested-classes     Ignore nested classes.  [default: False]
 
+      -O, --ignore-overloaded-functions
+                                      Ignore `@typing.overload`-decorated functions.
+                                      [default: False]
+
       -p, --ignore-private            Ignore private classes, methods, and
                                       functions starting with two underscores.
                                       [default: False]
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 6642eb7..83bb0d7 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -9,12 +9,13 @@ Changelog
 Added
 ^^^^^
 
-- Support for Python 3.11 & 3.12.
+* Add ``--ignore-overloaded-functions`` flag to ignore overload decorators (`#97 <https://github.com/econchick/interrogate/issues/97>`_) – thank you `ErwinJunge <https://github.com/econchick/interrogate/pull/98>`_ (via `#167 <https://github.com/econchick/interrogate/pull/167>`_) and `zackyancey <https://github.com/econchick/interrogate/pull/160>`_.
+* Support for Python 3.11 & 3.12.
 
 Removed
 ^^^^^^^
 
-- Support for Python 3.6 & 3.7.
+* Support for Python 3.6 & 3.7.
 
 .. short-log
 
diff --git a/docs/index.rst b/docs/index.rst
index 3cc8dfc..d83833c 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -68,6 +68,10 @@ Command Line Options
 
     Ignore nested classes.  [default: ``False``]
 
+.. option:: -O, --ignore-overloaded-functions
+
+    Ignore `@typing.overload`-decorated functions.  [default: ``False``]
+
 .. option:: -p, --ignore-private
 
     Ignore private classes, methods, and functions starting with two underscores.  [default: ``False``]
diff --git a/pyproject.toml b/pyproject.toml
index 9f69331..d0a57dd 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,5 +1,5 @@
 [build-system]
-requires = ["setuptools>=40.6.0", "wheel"]
+requires = ["setuptools>=40.6.0"]
 build-backend = "setuptools.build_meta"
 
 [tool.check-wheel-contents]
diff --git a/src/interrogate/cli.py b/src/interrogate/cli.py
index 6e447f4..121aac5 100644
--- a/src/interrogate/cli.py
+++ b/src/interrogate/cli.py
@@ -116,6 +116,14 @@ from interrogate import utils
     show_default=True,
     help="Ignore nested classes.",
 )
+@click.option(
+    "-O",
+    "--ignore-overloaded-functions",
+    is_flag=True,
+    default=False,
+    show_default=True,
+    help="Ignore `@typing.overload`-decorated functions.",
+)
 @click.option(
     "-p",
     "--ignore-private",
@@ -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.
@@ -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"],
diff --git a/src/interrogate/config.py b/src/interrogate/config.py
index c2f7546..5e6e99a 100644
--- a/src/interrogate/config.py
+++ b/src/interrogate/config.py
@@ -39,6 +39,8 @@ 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 `@typing.overload`-decorated
+        functions.
     """
 
     color = attr.ib(default=False)
@@ -54,6 +56,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)
 
diff --git a/src/interrogate/visit.py b/src/interrogate/visit.py
index c89d5ac..cc883e6 100644
--- a/src/interrogate/visit.py
+++ b/src/interrogate/visit.py
@@ -180,6 +180,26 @@ class CoverageVisitor(ast.NodeVisitor):
                     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__"
@@ -192,6 +212,7 @@ class CoverageVisitor(ast.NodeVisitor):
         )
         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
@@ -201,6 +222,8 @@ class CoverageVisitor(ast.NodeVisitor):
             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)
 


Test patch:
diff --git a/tests/functional/fixtures/expected_detailed.txt b/tests/functional/fixtures/expected_detailed.txt
index ac3aa99..4e5df7f 100644
--- a/tests/functional/fixtures/expected_detailed.txt
+++ b/tests/functional/fixtures/expected_detailed.txt
@@ -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 (L78)                                           |   COVERED |
+|     top_level_func.inner_func (L81)                              |   COVERED |
+|   Bar (L86)                                                      |   COVERED |
+|     Bar.method_bar (L89)                                         |   COVERED |
+|       Bar.method_bar.InnerBar (L92)                              |   COVERED |
+|   _SemiprivateClass (L98)                                        |   COVERED |
+|   __PrivateClass (L104)                                          |   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 (L53)                                    |    MISSED |
+|     Foo.module_overload (L55)                                    |   COVERED |
+|     Foo.simple_overload (L60)                                    |    MISSED |
+|     Foo.simple_overload (L63)                                    |    MISSED |
+|     Foo.simple_overload (L65)                                    |   COVERED |
+|   documented_top_level_func (L70)                                |   COVERED |
+|     documented_top_level_func.documented_inner_func (L73)        |   COVERED |
+|   undocumented_top_level_func (L78)                              |    MISSED |
+|     undocumented_top_level_func.undocumented_inner_func (L79)    |    MISSED |
+|   Bar (L83)                                                      |    MISSED |
+|     Bar.method_bar (L84)                                         |    MISSED |
+|       Bar.method_bar.InnerBar (L85)                              |    MISSED |
+|   _SemiprivateClass (L89)                                        |    MISSED |
+|   __PrivateClass (L93)                                           |    MISSED |
 |------------------------------------------------------------------|-----------|
 | child_sample/__init__.py (module)                                |    MISSED |
 |------------------------------------------------------------------|-----------|
diff --git a/tests/functional/fixtures/expected_detailed_no_module.txt b/tests/functional/fixtures/expected_detailed_no_module.txt
index 5bf7dd7..e34d031 100644
--- a/tests/functional/fixtures/expected_detailed_no_module.txt
+++ b/tests/functional/fixtures/expected_detailed_no_module.txt
@@ -2,46 +2,58 @@
 | Name                                                             |    Status |
 |------------------------------------------------------------------|-----------|
 | full.py                                                          |           |
-|   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 (L78)                                           |   COVERED |
+|     top_level_func.inner_func (L81)                              |   COVERED |
+|   Bar (L86)                                                      |   COVERED |
+|     Bar.method_bar (L89)                                         |   COVERED |
+|       Bar.method_bar.InnerBar (L92)                              |   COVERED |
+|   _SemiprivateClass (L98)                                        |   COVERED |
+|   __PrivateClass (L104)                                          |   COVERED |
 |------------------------------------------------------------------|-----------|
 | partial.py                                                       |           |
-|   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 (L53)                                    |    MISSED |
+|     Foo.module_overload (L55)                                    |   COVERED |
+|     Foo.simple_overload (L60)                                    |    MISSED |
+|     Foo.simple_overload (L63)                                    |    MISSED |
+|     Foo.simple_overload (L65)                                    |   COVERED |
+|   documented_top_level_func (L70)                                |   COVERED |
+|     documented_top_level_func.documented_inner_func (L73)        |   COVERED |
+|   undocumented_top_level_func (L78)                              |    MISSED |
+|     undocumented_top_level_func.undocumented_inner_func (L79)    |    MISSED |
+|   Bar (L83)                                                      |    MISSED |
+|     Bar.method_bar (L84)                                         |    MISSED |
+|       Bar.method_bar.InnerBar (L85)                              |    MISSED |
+|   _SemiprivateClass (L89)                                        |    MISSED |
+|   __PrivateClass (L93)                                           |    MISSED |
 |------------------------------------------------------------------|-----------|
 | child_sample/child_sample_module.py                              |           |
 |   ChildFoo (L5)                                                  |    MISSED |
diff --git a/tests/functional/fixtures/expected_detailed_single_file.txt b/tests/functional/fixtures/expected_detailed_single_file.txt
index 635a0c8..ffa74e0 100644
--- a/tests/functional/fixtures/expected_detailed_single_file.txt
+++ b/tests/functional/fixtures/expected_detailed_single_file.txt
@@ -2,29 +2,35 @@
 | Name                                                |                 Status |
 |-----------------------------------------------------|------------------------|
 | 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 (L78)                              |                COVERED |
+|     top_level_func.inner_func (L81)                 |                COVERED |
+|   Bar (L86)                                         |                COVERED |
+|     Bar.method_bar (L89)                            |                COVERED |
+|       Bar.method_bar.InnerBar (L92)                 |                COVERED |
+|   _SemiprivateClass (L98)                           |                COVERED |
+|   __PrivateClass (L104)                             |                COVERED |
 |-----------------------------------------------------|------------------------|
 
 ----------------------------------- Summary ------------------------------------
 | Name             |        Total |        Miss |        Cover |        Cover% |
 |------------------|--------------|-------------|--------------|---------------|
-| full.py          |           18 |           0 |           18 |          100% |
+| full.py          |           24 |           0 |           24 |          100% |
 |------------------|--------------|-------------|--------------|---------------|
-| TOTAL            |           18 |           0 |           18 |        100.0% |
+| TOTAL            |           24 |           0 |           24 |        100.0% |
 --------------- RESULT: PASSED (minimum: 80.0%, actual: 100.0%) ----------------
diff --git a/tests/functional/fixtures/expected_detailed_skip_covered.txt b/tests/functional/fixtures/expected_detailed_skip_covered.txt
index 8715070..1f9cd5c 100644
--- a/tests/functional/fixtures/expected_detailed_skip_covered.txt
+++ b/tests/functional/fixtures/expected_detailed_skip_covered.txt
@@ -4,27 +4,33 @@
 | empty.py (module)                                                |    MISSED |
 |------------------------------------------------------------------|-----------|
 | 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 (L53)                                    |    MISSED |
+|     Foo.module_overload (L55)                                    |   COVERED |
+|     Foo.simple_overload (L60)                                    |    MISSED |
+|     Foo.simple_overload (L63)                                    |    MISSED |
+|     Foo.simple_overload (L65)                                    |   COVERED |
+|   documented_top_level_func (L70)                                |   COVERED |
+|     documented_top_level_func.documented_inner_func (L73)        |   COVERED |
+|   undocumented_top_level_func (L78)                              |    MISSED |
+|     undocumented_top_level_func.undocumented_inner_func (L79)    |    MISSED |
+|   Bar (L83)                                                      |    MISSED |
+|     Bar.method_bar (L84)                                         |    MISSED |
+|       Bar.method_bar.InnerBar (L85)                              |    MISSED |
+|   _SemiprivateClass (L89)                                        |    MISSED |
+|   __PrivateClass (L93)                                           |    MISSED |
 |------------------------------------------------------------------|-----------|
 | child_sample/__init__.py (module)                                |    MISSED |
 |------------------------------------------------------------------|-----------|
diff --git a/tests/functional/fixtures/expected_no_verbosity.txt b/tests/functional/fixtures/expected_no_verbosity.txt
index 05cfdf8..d071062 100644
--- a/tests/functional/fixtures/expected_no_verbosity.txt
+++ b/tests/functional/fixtures/expected_no_verbosity.txt
@@ -1 +1 @@
-RESULT: FAILED (minimum: 80.0%, actual: 46.4%)
+RESULT: FAILED (minimum: 80.0%, actual: 50.0%)
diff --git a/tests/functional/fixtures/expected_summary.txt b/tests/functional/fixtures/expected_summary.txt
index bc5d37a..195bbe5 100644
--- a/tests/functional/fixtures/expected_summary.txt
+++ b/tests/functional/fixtures/expected_summary.txt
@@ -2,9 +2,9 @@
 |------------------------------------------|--------|-------|--------|---------|
 | __init__.py                              |      1 |     0 |      1 |    100% |
 | empty.py                                 |      1 |     1 |      0 |      0% |
-| full.py                                  |     18 |     0 |     18 |    100% |
-| partial.py                               |     22 |    15 |      7 |     32% |
+| full.py                                  |     24 |     0 |     24 |    100% |
+| partial.py                               |     28 |    19 |      9 |     32% |
 | child_sample/__init__.py                 |      1 |     1 |      0 |      0% |
 | child_sample/child_sample_module.py      |     13 |    13 |      0 |      0% |
 |------------------------------------------|--------|-------|--------|---------|
-| TOTAL                                    |     56 |    30 |     26 |   46.4% |
+| TOTAL                                    |     68 |    34 |     34 |   50.0% |
diff --git a/tests/functional/fixtures/expected_summary_no_module.txt b/tests/functional/fixtures/expected_summary_no_module.txt
index 9267f16..aba814b 100644
--- a/tests/functional/fixtures/expected_summary_no_module.txt
+++ b/tests/functional/fixtures/expected_summary_no_module.txt
@@ -1,9 +1,9 @@
 ----------------------------------- Summary ------------------------------------
 | Name                                     |  Total |  Miss |  Cover |  Cover% |
 |------------------------------------------|--------|-------|--------|---------|
-| full.py                                  |     17 |     0 |     17 |    100% |
-| partial.py                               |     21 |    15 |      6 |     29% |
+| full.py                                  |     23 |     0 |     23 |    100% |
+| partial.py                               |     27 |    19 |      8 |     30% |
 | child_sample/child_sample_module.py      |     12 |    12 |      0 |      0% |
 |------------------------------------------|--------|-------|--------|---------|
-| TOTAL                                    |     50 |    27 |     23 |   46.0% |
----------------- RESULT: FAILED (minimum: 80.0%, actual: 46.0%) ----------------
+| TOTAL                                    |     62 |    31 |     31 |   50.0% |
+---------------- RESULT: FAILED (minimum: 80.0%, actual: 50.0%) ----------------
diff --git a/tests/functional/fixtures/expected_summary_skip_covered.txt b/tests/functional/fixtures/expected_summary_skip_covered.txt
index f0b25ed..f8f8c22 100644
--- a/tests/functional/fixtures/expected_summary_skip_covered.txt
+++ b/tests/functional/fixtures/expected_summary_skip_covered.txt
@@ -1,10 +1,10 @@
 | Name                                     |  Total |  Miss |  Cover |  Cover% |
 |------------------------------------------|--------|-------|--------|---------|
 | empty.py                                 |      1 |     1 |      0 |      0% |
-| partial.py                               |     22 |    15 |      7 |     32% |
+| partial.py                               |     28 |    19 |      9 |     32% |
 | child_sample/__init__.py                 |      1 |     1 |      0 |      0% |
 | child_sample/child_sample_module.py      |     13 |    13 |      0 |      0% |
 |------------------------------------------|--------|-------|--------|---------|
-| TOTAL                                    |     56 |    30 |     26 |   46.4% |
+| TOTAL                                    |     68 |    34 |     34 |   50.0% |
 |------------------------------------------------------------------------------|
 |               (2 of 6 files omitted due to complete coverage)                |
diff --git a/tests/functional/fixtures/expected_summary_skip_covered_all.txt b/tests/functional/fixtures/expected_summary_skip_covered_all.txt
index 63b9823..01acd68 100644
--- a/tests/functional/fixtures/expected_summary_skip_covered_all.txt
+++ b/tests/functional/fixtures/expected_summary_skip_covered_all.txt
@@ -1,5 +1,5 @@
 | Name             |        Total |        Miss |        Cover |        Cover% |
 |------------------|--------------|-------------|--------------|---------------|
-| TOTAL            |           18 |           0 |           18 |        100.0% |
+| TOTAL            |           24 |           0 |           24 |        100.0% |
 |------------------------------------------------------------------------------|
 |                (1 of 1 file omitted due to complete coverage)                |
diff --git a/tests/functional/fixtures/windows/expected_detailed.txt b/tests/functional/fixtures/windows/expected_detailed.txt
index b9b04eb..3fd5e6e 100644
--- a/tests/functional/fixtures/windows/expected_detailed.txt
+++ b/tests/functional/fixtures/windows/expected_detailed.txt
@@ -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 (L78)                                          |   COVERED |
+|     top_level_func.inner_func (L81)                             |   COVERED |
+|   Bar (L86)                                                     |   COVERED |
+|     Bar.method_bar (L89)                                        |   COVERED |
+|       Bar.method_bar.InnerBar (L92)                             |   COVERED |
+|   _SemiprivateClass (L98)                                       |   COVERED |
+|   __PrivateClass (L104)                                         |   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 (L53)                                   |    MISSED |
+|     Foo.module_overload (L55)                                   |   COVERED |
+|     Foo.simple_overload (L60)                                   |    MISSED |
+|     Foo.simple_overload (L63)                                   |    MISSED |
+|     Foo.simple_overload (L65)                                   |   COVERED |
+|   documented_top_level_func (L70)                               |   COVERED |
+|     documented_top_level_func.documented_inner_func (L73)       |   COVERED |
+|   undocumented_top_level_func (L78)                             |    MISSED |
+|     undocumented_top_level_func.undocumented_inner_func (L79)   |    MISSED |
+|   Bar (L83)                                                     |    MISSED |
+|     Bar.method_bar (L84)                                        |    MISSED |
+|       Bar.method_bar.InnerBar (L85)                             |    MISSED |
+|   _SemiprivateClass (L89)                                       |    MISSED |
+|   __PrivateClass (L93)                                          |    MISSED |
 |-----------------------------------------------------------------|-----------|
 | child_sample\__init__.py (module)                               |    MISSED |
 |-----------------------------------------------------------------|-----------|
diff --git a/tests/functional/fixtures/windows/expected_detailed_no_module.txt b/tests/functional/fixtures/windows/expected_detailed_no_module.txt
index 2a85a9d..f247654 100644
--- a/tests/functional/fixtures/windows/expected_detailed_no_module.txt
+++ b/tests/functional/fixtures/windows/expected_detailed_no_module.txt
@@ -2,46 +2,58 @@
 | Name                                                            |    Status |
 |-----------------------------------------------------------------|-----------|
 | full.py                                                         |           |
-|   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 (L78)                                          |   COVERED |
+|     top_level_func.inner_func (L81)                             |   COVERED |
+|   Bar (L86)                                                     |   COVERED |
+|     Bar.method_bar (L89)                                        |   COVERED |
+|       Bar.method_bar.InnerBar (L92)                             |   COVERED |
+|   _SemiprivateClass (L98)                                       |   COVERED |
+|   __PrivateClass (L104)                                         |   COVERED |
 |-----------------------------------------------------------------|-----------|
 | partial.py                                                      |           |
-|   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 (L53)                                   |    MISSED |
+|     Foo.module_overload (L55)                                   |   COVERED |
+|     Foo.simple_overload (L60)                                   |    MISSED |
+|     Foo.simple_overload (L63)                                   |    MISSED |
+|     Foo.simple_overload (L65)                                   |   COVERED |
+|   documented_top_level_func (L70)                               |   COVERED |
+|     documented_top_level_func.documented_inner_func (L73)       |   COVERED |
+|   undocumented_top_level_func (L78)                             |    MISSED |
+|     undocumented_top_level_func.undocumented_inner_func (L79)   |    MISSED |
+|   Bar (L83)                                                     |    MISSED |
+|     Bar.method_bar (L84)                                        |    MISSED |
+|       Bar.method_bar.InnerBar (L85)                             |    MISSED |
+|   _SemiprivateClass (L89)                                       |    MISSED |
+|   __PrivateClass (L93)                                          |    MISSED |
 |-----------------------------------------------------------------|-----------|
 | child_sample\child_sample_module.py                             |           |
 |   ChildFoo (L5)                                                 |    MISSED |
@@ -57,3 +69,13 @@
 |   _ChildBaz (L34)                                               |    MISSED |
 |   __ChildBla (L38)                                              |    MISSED |
 |-----------------------------------------------------------------|-----------|
+
+----------------------------------- Summary -----------------------------------
+| Name                                    |  Total |  Miss |  Cover |  Cover% |
+|-----------------------------------------|--------|-------|--------|---------|
+| full.py                                 |     23 |     0 |     23 |    100% |
+| partial.py                              |     27 |    19 |      8 |     30% |
+| child_sample\child_sample_module.py     |     12 |    12 |      0 |      0% |
+|-----------------------------------------|--------|-------|--------|---------|
+| TOTAL                                   |     62 |    31 |     31 |   50.0% |
+--------------- RESULT: FAILED (minimum: 80.0%, actual: 50.0%) ----------------
diff --git a/tests/functional/fixtures/windows/expected_detailed_single_file.txt b/tests/functional/fixtures/windows/expected_detailed_single_file.txt
index 79091cd..4c2996c 100644
--- a/tests/functional/fixtures/windows/expected_detailed_single_file.txt
+++ b/tests/functional/fixtures/windows/expected_detailed_single_file.txt
@@ -2,29 +2,35 @@
 | Name                                               |                 Status |
 |----------------------------------------------------|------------------------|
 | 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 (L78)                             |                COVERED |
+|     top_level_func.inner_func (L81)                |                COVERED |
+|   Bar (L86)                                        |                COVERED |
+|     Bar.method_bar (L89)                           |                COVERED |
+|       Bar.method_bar.InnerBar (L92)                |                COVERED |
+|   _SemiprivateClass (L98)                          |                COVERED |
+|   __PrivateClass (L104)                            |                COVERED |
 |----------------------------------------------------|------------------------|
 
 ----------------------------------- Summary -----------------------------------
 | Name            |        Total |        Miss |        Cover |        Cover% |
 |-----------------|--------------|-------------|--------------|---------------|
-| full.py         |           18 |           0 |           18 |          100% |
+| full.py         |           24 |           0 |           24 |          100% |
 |-----------------|--------------|-------------|--------------|---------------|
-| TOTAL           |           18 |           0 |           18 |        100.0% |
+| TOTAL           |           24 |           0 |           24 |        100.0% |
 --------------- RESULT: PASSED (minimum: 80.0%, actual: 100.0%) ---------------
diff --git a/tests/functional/fixtures/windows/expected_detailed_skip_covered.txt b/tests/functional/fixtures/windows/expected_detailed_skip_covered.txt
index a19a141..47fdd51 100644
--- a/tests/functional/fixtures/windows/expected_detailed_skip_covered.txt
+++ b/tests/functional/fixtures/windows/expected_detailed_skip_covered.txt
@@ -4,27 +4,33 @@
 | empty.py (module)                                               |    MISSED |
 |-----------------------------------------------------------------|-----------|
 | 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 (L53)                                   |    MISSED |
+|     Foo.module_overload (L55)                                   |   COVERED |
+|     Foo.simple_overload (L60)                                   |    MISSED |
+|     Foo.simple_overload (L63)                                   |    MISSED |
+|     Foo.simple_overload (L65)                                   |   COVERED |
+|   documented_top_level_func (L70)                               |   COVERED |
+|     documented_top_level_func.documented_inner_func (L73)       |   COVERED |
+|   undocumented_top_level_func (L78)                             |    MISSED |
+|     undocumented_top_level_func.undocumented_inner_func (L79)   |    MISSED |
+|   Bar (L83)                                                     |    MISSED |
+|     Bar.method_bar (L84)                                        |    MISSED |
+|       Bar.method_bar.InnerBar (L85)                             |    MISSED |
+|   _SemiprivateClass (L89)                                       |    MISSED |
+|   __PrivateClass (L93)                                          |    MISSED |
 |-----------------------------------------------------------------|-----------|
 | child_sample\__init__.py (module)                               |    MISSED |
 |-----------------------------------------------------------------|-----------|
diff --git a/tests/functional/fixtures/windows/expected_no_verbosity.txt b/tests/functional/fixtures/windows/expected_no_verbosity.txt
index 05cfdf8..d071062 100644
--- a/tests/functional/fixtures/windows/expected_no_verbosity.txt
+++ b/tests/functional/fixtures/windows/expected_no_verbosity.txt
@@ -1 +1 @@
-RESULT: FAILED (minimum: 80.0%, actual: 46.4%)
+RESULT: FAILED (minimum: 80.0%, actual: 50.0%)
diff --git a/tests/functional/fixtures/windows/expected_summary.txt b/tests/functional/fixtures/windows/expected_summary.txt
index 8d38fc5..bb991b6 100644
--- a/tests/functional/fixtures/windows/expected_summary.txt
+++ b/tests/functional/fixtures/windows/expected_summary.txt
@@ -2,9 +2,9 @@
 |-----------------------------------------|--------|-------|--------|---------|
 | __init__.py                             |      1 |     0 |      1 |    100% |
 | empty.py                                |      1 |     1 |      0 |      0% |
-| full.py                                 |     18 |     0 |     18 |    100% |
-| partial.py                              |     22 |    15 |      7 |     32% |
+| full.py                                 |     24 |     0 |     24 |    100% |
+| partial.py                              |     28 |    19 |      9 |     32% |
 | child_sample\__init__.py                |      1 |     1 |      0 |      0% |
 | child_sample\child_sample_module.py     |     13 |    13 |      0 |      0% |
 |-----------------------------------------|--------|-------|--------|---------|
-| TOTAL                                   |     56 |    30 |     26 |   46.4% |
+| TOTAL                                   |     68 |    34 |     34 |   50.0% |
diff --git a/tests/functional/fixtures/windows/expected_summary_no_module.txt b/tests/functional/fixtures/windows/expected_summary_no_module.txt
index bef00fa..137371f 100644
--- a/tests/functional/fixtures/windows/expected_summary_no_module.txt
+++ b/tests/functional/fixtures/windows/expected_summary_no_module.txt
@@ -1,9 +1,7 @@
 ----------------------------------- Summary -----------------------------------
 | Name                                    |  Total |  Miss |  Cover |  Cover% |
 |-----------------------------------------|--------|-------|--------|---------|
-| full.py                                 |     17 |     0 |     17 |    100% |
-| partial.py                              |     21 |    15 |      6 |     29% |
+| full.py                                 |     23 |     0 |     23 |    100% |
+| partial.py                              |     27 |    19 |      8 |     30% |
 | child_sample\child_sample_module.py     |     12 |    12 |      0 |      0% |
 |-----------------------------------------|--------|-------|--------|---------|
-| TOTAL                                   |     50 |    27 |     23 |   46.0% |
---------------- RESULT: FAILED (minimum: 80.0%, actual: 46.0%) ----------------
diff --git a/tests/functional/fixtures/windows/expected_summary_skip_covered.txt b/tests/functional/fixtures/windows/expected_summary_skip_covered.txt
index 05d18b6..a5fa1f1 100644
--- a/tests/functional/fixtures/windows/expected_summary_skip_covered.txt
+++ b/tests/functional/fixtures/windows/expected_summary_skip_covered.txt
@@ -1,8 +1,8 @@
 | Name                                    |  Total |  Miss |  Cover |  Cover% |
 |-----------------------------------------|--------|-------|--------|---------|
 | empty.py                                |      1 |     1 |      0 |      0% |
-| partial.py                              |     22 |    15 |      7 |     32% |
+| partial.py                              |     28 |    19 |      9 |     32% |
 | child_sample\__init__.py                |      1 |     1 |      0 |      0% |
 | child_sample\child_sample_module.py     |     13 |    13 |      0 |      0% |
 |-----------------------------------------|--------|-------|--------|---------|
-| TOTAL                                   |     56 |    30 |     26 |   46.4% |
+| TOTAL                                   |     68 |    34 |     34 |   50.0% |
diff --git a/tests/functional/fixtures/windows/expected_summary_skip_covered_all.txt b/tests/functional/fixtures/windows/expected_summary_skip_covered_all.txt
index b492f18..ac2b8dc 100644
--- a/tests/functional/fixtures/windows/expected_summary_skip_covered_all.txt
+++ b/tests/functional/fixtures/windows/expected_summary_skip_covered_all.txt
@@ -1,5 +1,7 @@
+----------------------------------- Summary -----------------------------------
 | Name            |        Total |        Miss |        Cover |        Cover% |
 |-----------------|--------------|-------------|--------------|---------------|
-| TOTAL           |           18 |           0 |           18 |        100.0% |
+| TOTAL           |           24 |           0 |           24 |        100.0% |
 |-----------------------------------------------------------------------------|
 |               (1 of 1 file omitted due to complete coverage)                |
+--------------- RESULT: PASSED (minimum: 80.0%, actual: 100.0%) ---------------
diff --git a/tests/functional/sample/full.py b/tests/functional/sample/full.py
index 8bec0d2..4f6f57a 100644
--- a/tests/functional/sample/full.py
+++ b/tests/functional/sample/full.py
@@ -1,5 +1,8 @@
 # Copyright 2020 Lynn Root
 """Sample module-level docs"""
+import typing
+
+from typing import overload
 
 
 class Foo:
@@ -43,6 +46,34 @@ class Foo:
         """this method has a set property decorator"""
         pass
 
+    @typing.overload
+    def module_overload(a: None) -> None:
+        """overloaded method"""
+        ...
+
+    @typing.overload
+    def module_overload(a: int) -> int:
+        """overloaded method"""
+        ...
+
+    def module_overload(a):
+        """overloaded method implementation"""
+        pass
+
+    @overload
+    def simple_overload(a: None) -> None:
+        """overloaded method"""
+        ...
+
+    @overload
+    def simple_overload(a: int) -> int:
+        """overloaded method"""
+        ...
+
+    def simple_overload(a):
+        """overloaded method implementation"""
+        pass
+
 
 def top_level_func():
     """A top level function"""
diff --git a/tests/functional/sample/partial.py b/tests/functional/sample/partial.py
index 106c665..f31d5f4 100644
--- a/tests/functional/sample/partial.py
+++ b/tests/functional/sample/partial.py
@@ -1,5 +1,8 @@
 # Copyright 2020 Lynn Root
 """Sample module-level docs"""
+import typing
+
+from typing import overload
 
 
 class Foo:
@@ -43,6 +46,26 @@ class Foo:
     def a_prop(self, x):
         pass
 
+    @typing.overload
+    def module_overload(a: None) -> None: ...
+
+    @typing.overload
+    def module_overload(a: int) -> int: ...
+
+    def module_overload(a):
+        """overloaded method implementation"""
+        pass
+
+    @overload
+    def simple_overload(a: None) -> None: ...
+
+    @overload
+    def simple_overload(a: int) -> int: ...
+
+    def simple_overload(a):
+        """overloaded method implementation"""
+        pass
+
 
 def documented_top_level_func():
     """A documented top level function"""
diff --git a/tests/functional/test_cli.py b/tests/functional/test_cli.py
index 4bd475d..355d924 100644
--- a/tests/functional/test_cli.py
+++ b/tests/functional/test_cli.py
@@ -33,7 +33,7 @@ def test_run_no_paths(runner, monkeypatch, tmpdir):
 
     result = runner.invoke(cli.main, [])
 
-    assert "actual: 46.4%" in result.output
+    assert "actual: 50.0%" in result.output
     assert 1 == result.exit_code
 
 
@@ -41,37 +41,39 @@ def test_run_no_paths(runner, monkeypatch, tmpdir):
     "flags,exp_result,exp_exit_code",
     (
         # no flags
-        ([], 46.4, 1),
+        ([], 50.0, 1),
         # ignore init module
-        (["-I"], 46.3, 1),
+        (["-I"], 50.0, 1),
         # ignore module docs
-        (["-M"], 46.0, 1),
+        (["-M"], 50.0, 1),
         # ignore semiprivate docs
-        (["-s"], 46.9, 1),
+        (["-s"], 50.8, 1),
         # ignore private docs
-        (["-p"], 48.0, 1),
+        (["-p"], 51.6, 1),
         # ignore property getter/setter decorators
-        (["-P"], 46.2, 1),
+        (["-P"], 50.0, 1),
         # ignore property setter decorators
-        (["-S"], 46.3, 1),
+        (["-S"], 50.0, 1),
         # ignore magic method docs
-        (["-m"], 46.2, 1),
+        (["-m"], 50.0, 1),
         # ignore init method docs
-        (["-i"], 45.3, 1),
+        (["-i"], 49.2, 1),
         # ignore nested funcs
-        (["-n"], 45.3, 1),
+        (["-n"], 49.2, 1),
         # ignore nested classes
-        (["-C"], 47.2, 1),
+        (["-C"], 50.8, 1),
+        # ignore @typing.overload-decorated functions
+        (["-O"], 50.0, 1),
         # ignore regex
-        (["-r", "^get$"], 46.2, 1),
+        (["-r", "^get$"], 50.0, 1),
         # whitelist regex
         (["-w", "^get$"], 50.0, 1),
         # exclude file
-        (["-e", os.path.join(SAMPLE_DIR, "partial.py")], 55.9, 1),
+        (["-e", os.path.join(SAMPLE_DIR, "partial.py")], 62.5, 1),
         # exclude file which doesn't exist
-        (["-e", os.path.join(SAMPLE_DIR, "does.not.exist")], 46.4, 1),
+        (["-e", os.path.join(SAMPLE_DIR, "does.not.exist")], 50.0, 1),
         # fail under
-        (["-f", "40"], 46.4, 0),
+        (["-f", "40"], 50.0, 0),
     ),
 )
 def test_run_shortflags(flags, exp_result, exp_exit_code, runner):
@@ -87,20 +89,21 @@ def test_run_shortflags(flags, exp_result, exp_exit_code, runner):
 @pytest.mark.parametrize(
     "flags,exp_result,exp_exit_code",
     (
-        (["--ignore-init-module"], 46.3, 1),
-        (["--ignore-module"], 46.0, 1),
-        (["--ignore-semiprivate"], 46.9, 1),
-        (["--ignore-private"], 48.0, 1),
-        (["--ignore-property-decorators"], 46.2, 1),
-        (["--ignore-setters"], 46.3, 1),
-        (["--ignore-magic"], 46.2, 1),
-        (["--ignore-init-method"], 45.3, 1),
-        (["--ignore-nested-functions"], 45.3, 1),
-        (["--ignore-nested-classes"], 47.2, 1),
-        (["--ignore-regex", "^get$"], 46.2, 1),
+        (["--ignore-init-module"], 50.0, 1),
+        (["--ignore-module"], 50.0, 1),
+        (["--ignore-semiprivate"], 50.8, 1),
+        (["--ignore-private"], 51.6, 1),
+        (["--ignore-property-decorators"], 50.0, 1),
+        (["--ignore-setters"], 50.0, 1),
+        (["--ignore-magic"], 50.0, 1),
+        (["--ignore-init-method"], 49.2, 1),
+        (["--ignore-nested-functions"], 49.2, 1),
+        (["--ignore-nested-classes"], 50.8, 1),
+        (["--ignore-overloaded-functions"], 50.0, 1),
+        (["--ignore-regex", "^get$"], 50.0, 1),
         (["--whitelist-regex", "^get$"], 50.0, 1),
-        (["--exclude", os.path.join(SAMPLE_DIR, "partial.py")], 55.9, 1),
-        (["--fail-under", "40"], 46.4, 0),
+        (["--exclude", os.path.join(SAMPLE_DIR, "partial.py")], 62.5, 1),
+        (["--fail-under", "40"], 50.0, 0),
     ),
 )
 def test_run_longflags(flags, exp_result, exp_exit_code, runner):
@@ -116,9 +119,9 @@ def test_run_longflags(flags, exp_result, exp_exit_code, runner):
 @pytest.mark.parametrize(
     "flags,exp_result,exp_exit_code",
     (
-        (["-i", "-I", "-r" "^method_foo$"], 45.8, 1),
-        (["-s", "-p", "-M"], 48.6, 1),
-        (["-m", "-f", "45"], 46.2, 0),
+        (["-i", "-I", "-r" "^method_foo$"], 50.0, 1),
+        (["-s", "-p", "-M"], 53.1, 1),
+        (["-m", "-f", "45"], 50.0, 0),
     ),
 )
 def test_run_multiple_flags(flags, exp_result, exp_exit_code, runner):
diff --git a/tests/functional/test_coverage.py b/tests/functional/test_coverage.py
index 2a88a71..d40abe4 100644
--- a/tests/functional/test_coverage.py
+++ b/tests/functional/test_coverage.py
@@ -44,22 +44,36 @@ def patch_term_width(monkeypatch):
                 SAMPLE_DIR,
             ],
             {},
-            (56, 26, 30, "46.4"),
+            (68, 34, 34, "50.0"),
         ),
-        ([os.path.join(SAMPLE_DIR, "partial.py")], {}, (22, 7, 15, "31.8")),
+        ([os.path.join(SAMPLE_DIR, "partial.py")], {}, (28, 9, 19, "32.1")),
         (
             [
                 os.path.join(SAMPLE_DIR, "full.py"),
             ],
             {"ignore_nested_functions": True},
-            (17, 17, 0, "100.0"),
+            (23, 23, 0, "100.0"),
         ),
         (
             [
                 os.path.join(SAMPLE_DIR, "partial.py"),
             ],
             {"ignore_nested_functions": True},
-            (20, 6, 14, "30.0"),
+            (26, 8, 18, "30.8"),
+        ),
+        (
+            [
+                os.path.join(SAMPLE_DIR, "full.py"),
+            ],
+            {"ignore_overloaded_functions": True},
+            (20, 20, 0, "100.0"),
+        ),
+        (
+            [
+                os.path.join(SAMPLE_DIR, "partial.py"),
+            ],
+            {"ignore_overloaded_functions": True},
+            (24, 9, 15, "37.5"),
         ),
     ),
 )