diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | pylint/checkers/classes.py | 7 | ||||
-rw-r--r-- | pylint/checkers/utils.py | 10 | ||||
-rw-r--r-- | tests/functional/c/class_protocol_ellipsis.py | 44 |
4 files changed, 64 insertions, 1 deletions
@@ -68,6 +68,10 @@ Release date: TBA * Improve node information for ``invalid-name`` on function argument. +* Prevent return type checkers being called on functions with ellipses as body + + Closes #4736 + What's New in Pylint 2.11.1? ============================ diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py index 9e0a3b07f..14e0ef635 100644 --- a/pylint/checkers/classes.py +++ b/pylint/checkers/classes.py @@ -68,6 +68,7 @@ from pylint.checkers.utils import ( is_attr_protected, is_builtin_object, is_comprehension, + is_function_body_ellipsis, is_iterable, is_overload_stub, is_property_setter, @@ -2168,7 +2169,11 @@ class SpecialMethodsChecker(BaseChecker): inferred = _safe_infer_call_result(node, node) # Only want to check types that we are able to infer - if inferred and node.name in self._protocol_map: + if ( + inferred + and node.name in self._protocol_map + and not is_function_body_ellipsis(node) + ): self._protocol_map[node.name](node, inferred) if node.name in PYMETHODS: diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index 6e96b3a97..589b1c72c 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -1566,3 +1566,13 @@ def is_reassigned_after_current(node: nodes.NodeNG, varname: str) -> bool: a.name == varname and a.lineno > node.lineno for a in node.scope().nodes_of_class((nodes.AssignName, nodes.FunctionDef)) ) + + +def is_function_body_ellipsis(node: nodes.FunctionDef) -> bool: + """Checks whether a function body only consisst of a single Ellipsis""" + return ( + len(node.body) == 1 + and isinstance(node.body[0], nodes.Expr) + and isinstance(node.body[0].value, nodes.Const) + and node.body[0].value.value == Ellipsis + ) diff --git a/tests/functional/c/class_protocol_ellipsis.py b/tests/functional/c/class_protocol_ellipsis.py new file mode 100644 index 000000000..ef5d3b34e --- /dev/null +++ b/tests/functional/c/class_protocol_ellipsis.py @@ -0,0 +1,44 @@ +""""Tests for return type checkers for protocol methods with ellipsis function body""" +# pylint: disable=missing-class-docstring +from typing import Any, Iterator + + +class MyClass: + """The "invalid-*-returned" messages shouldn't be emitted for stub functions + Original issue: https://github.com/PyCQA/pylint/issues/4736""" + + def __len__(self) -> int: + ... + + def __hash__(self) -> int: + ... + + def __index__(self) -> int: + ... + + def __iter__(self) -> Iterator[Any]: + ... + + def __bool__(self) -> bool: + ... + + def __repr__(self) -> object: + ... + + def __str__(self) -> str: + ... + + def __bytes__(self) -> bytes: + ... + + def __length_hint__(self) -> int: + ... + + def __format__(self, format_spec: str) -> str: + ... + + def __getnewargs__(self) -> tuple: + ... + + def __getnewargs_ex__(self) -> tuple: + ... |