summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>2021-10-06 23:19:33 +0200
committerGitHub <noreply@github.com>2021-10-06 23:19:33 +0200
commit8843fc90ef9a8a81c6304fef89988c73730da332 (patch)
tree2eaee254ae121b4eb19d98933a4654bdb7ee5692
parentf963868f6b46d31ef7ae1bd1196eafe50bc4bad7 (diff)
downloadpylint-git-8843fc90ef9a8a81c6304fef89988c73730da332.tar.gz
Fix return type checkers calls on ellipses functions (#5107)
Closes #4736
-rw-r--r--ChangeLog4
-rw-r--r--pylint/checkers/classes.py7
-rw-r--r--pylint/checkers/utils.py10
-rw-r--r--tests/functional/c/class_protocol_ellipsis.py44
4 files changed, 64 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index a4a650fd6..58c79a53b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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:
+ ...