diff --git a/flake8_docstrings_complete/__init__.py b/flake8_docstrings_complete/__init__.py index be14e87..0183576 100644 --- a/flake8_docstrings_complete/__init__.py +++ b/flake8_docstrings_complete/__init__.py @@ -299,7 +299,7 @@ def _skip_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> bool: """Check whether to skip a function. A function is skipped if it is a test function in a test file, if it is a fixture in a test - or fixture file or if it is a property. + or fixture file, if it is a property or if it is an overload. Args: node: The function to check @@ -321,6 +321,10 @@ def _skip_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> bool: if self._file_type in {types_.FileType.TEST, types_.FileType.FIXTURE}: return any(self._is_fixture_decorator(decorator) for decorator in node.decorator_list) + # Check for overload + if any(attrs.is_overload_decorator(decorator) for decorator in node.decorator_list): + return True + return False def visit_any_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None: diff --git a/flake8_docstrings_complete/attrs.py b/flake8_docstrings_complete/attrs.py index 88d88f3..a29a5ca 100644 --- a/flake8_docstrings_complete/attrs.py +++ b/flake8_docstrings_complete/attrs.py @@ -74,6 +74,31 @@ def is_property_decorator(node: ast.expr) -> bool: return False # pragma: nocover +def is_overload_decorator(node: ast.expr) -> bool: + """Determine whether an expression is an overload decorator. + + Args: + node: The node to check. + + Returns: + Whether the node is an overload decorator. + """ + if isinstance(node, ast.Name): + return node.id == "overload" + + # Handle call + if isinstance(node, ast.Call): + return is_overload_decorator(node=node.func) + + # Handle attr + if isinstance(node, ast.Attribute): + value = node.value + return node.attr == "overload" and isinstance(value, ast.Name) and value.id == "typing" + + # There is no valid syntax that gets to here + return False # pragma: nocover + + def _get_class_target_name(target: ast.expr) -> ast.Name | None: """Get the name of the target for an assignment on the class. diff --git a/tests/integration/test___init__.py b/tests/integration/test___init__.py index cfbd806..9b3264a 100644 --- a/tests/integration/test___init__.py +++ b/tests/integration/test___init__.py @@ -569,6 +569,32 @@ class Class1: "", id=f"{DUPLICATE_ATTR_CODE} disabled", ), + pytest.param( + """ +from typing import overload + + +@overload +def foo(): + ... +""", + "source.py", + "", + id="overload", + ), + pytest.param( + """ +import typing + + +@typing.overload +def foo(): + ... +""", + "source.py", + "", + id="typing.overload", + ), ], ) def test_pass(code: str, filename: str, extra_args: str, tmp_path: Path):