summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>2021-08-31 12:27:19 +0200
committerGitHub <noreply@github.com>2021-08-31 12:27:19 +0200
commite1da3c03d2b91f56b0977480856c2a2a6501758a (patch)
treeee0f709ac536d71923c3119e9c5cfdb1db1a0c3a
parent8b778cd5d5a6220b6fc1d6a80e30066ebcabd43e (diff)
downloadpylint-git-e1da3c03d2b91f56b0977480856c2a2a6501758a.tar.gz
Fix false positive ``protected-access`` in typing (#4937)
* Fix false positive ``protected-access`` in typing Class functions can return protected members which can then be passed as arguments to other functions. When using type hints in function definitions these raised a message which they shouldn't do.
-rw-r--r--ChangeLog2
-rw-r--r--doc/whatsnew/2.10.rst3
-rw-r--r--doc/whatsnew/2.11.rst10
-rw-r--r--pylint/checkers/classes.py8
-rw-r--r--tests/functional/a/access/access_to_protected_members_typing.py32
-rw-r--r--tests/functional/a/access/access_to_protected_members_typing.rc2
-rw-r--r--tests/functional/a/access/access_to_protected_members_typing.txt0
7 files changed, 50 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index c0d6cb3a7..043639dc5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -43,6 +43,8 @@ Release date: TBA
Closes #4936
+* Fix false positive for ``protected-access`` if a protected member is used in type hints of function definitions
+
What's New in Pylint 2.10.3?
============================
diff --git a/doc/whatsnew/2.10.rst b/doc/whatsnew/2.10.rst
index 09fc52870..85cba1c3f 100644
--- a/doc/whatsnew/2.10.rst
+++ b/doc/whatsnew/2.10.rst
@@ -82,9 +82,6 @@ Other Changes
* ``consider-using-with`` is no longer triggered if a context manager is returned from a function.
-* Fix false positive for ``consider-using-with`` if a context manager is assigned to a
- variable in different paths of control flow (e. g. if-else clause).
-
* pylint does not crash with a traceback anymore when a file is problematic. It
creates a template text file for opening an issue on the bug tracker instead.
The linting can go on for other non problematic files instead of being impossible.
diff --git a/doc/whatsnew/2.11.rst b/doc/whatsnew/2.11.rst
index c2333911f..8524c0a90 100644
--- a/doc/whatsnew/2.11.rst
+++ b/doc/whatsnew/2.11.rst
@@ -20,13 +20,11 @@ New checkers
Extensions
==========
-
* Added new extension ``SetMembershipChecker`` with ``use-set-for-membership`` check:
Emitted when using an in-place defined ``list`` or ``tuple`` to do a membership test. ``sets`` are better optimized for that.
Closes #4776
-
* ``CodeStyleChecker``
* Added ``consider-using-assignment-expr``: Emitted when an assignment is directly followed by an if statement
@@ -40,8 +38,16 @@ Other Changes
* Added ``py-version`` config key (if ``[MASTER]`` section). Used for version dependant checks.
Will default to whatever Python version pylint is executed with.
+
* The ``invalid-name`` message is now more detailed when using multiple naming style regexes.
+* Fix false positive for ``consider-using-with`` if a context manager is assigned to a
+ variable in different paths of control flow (e. g. if-else clause).
+
+ Closes #4751
+
* Fix false positive for ``function-redefined`` for simple type annotations
Closes #4936
+
+* Fix false positive for ``protected-access`` if a protected member is used in type hints of function definitions
diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py
index 3b18b7e00..0b37a9f53 100644
--- a/pylint/checkers/classes.py
+++ b/pylint/checkers/classes.py
@@ -52,7 +52,7 @@ from typing import List, Pattern, cast
import astroid
from astroid import nodes
-from pylint.checkers import BaseChecker
+from pylint.checkers import BaseChecker, utils
from pylint.checkers.utils import (
PYMETHODS,
SPECIAL_METHODS_PARAMS,
@@ -1563,7 +1563,7 @@ a metaclass class method.",
if any(method_name == member.name for member in parent_class.mymethods()):
self.add_message(msg, node=node.targets[0])
- def _check_protected_attribute_access(self, node):
+ def _check_protected_attribute_access(self, node: nodes.Attribute):
"""Given an attribute access node (set or get), check if attribute
access is legitimate. Call _check_first_attr with node before calling
this method. Valid cases are:
@@ -1586,6 +1586,10 @@ a metaclass class method.",
# through the class object or through super
callee = node.expr.as_string()
+ # Typing annotations in funciton definitions can include protected members
+ if utils.is_node_in_type_annotation_context(node):
+ return
+
# We are not in a class, no remaining valid case
if klass is None:
self.add_message("protected-access", node=node, args=attrname)
diff --git a/tests/functional/a/access/access_to_protected_members_typing.py b/tests/functional/a/access/access_to_protected_members_typing.py
new file mode 100644
index 000000000..4e5eee4c6
--- /dev/null
+++ b/tests/functional/a/access/access_to_protected_members_typing.py
@@ -0,0 +1,32 @@
+# pylint: disable=too-few-public-methods, invalid-name
+"""Test typing with a protected member"""
+from __future__ import annotations
+
+
+class MyClass:
+ """Class with protected members."""
+
+ class _Inner_Class:
+ """Inner class with protected members."""
+
+ def __init__(self) -> None:
+ self.data = 1
+
+ def return_data(self) -> int:
+ """Return data"""
+ return self.data
+
+ def return_private_class(self) -> MyClass._Inner_Class:
+ """Doing nothing."""
+ return self._Inner_Class()
+
+
+def access_protected_class(data: MyClass._Inner_Class) -> int:
+ """Function that always receives a protected class."""
+ return data.return_data() + 1
+
+
+def pass_protected_class() -> None:
+ """Function that passes a protected class to another function."""
+ data_value = access_protected_class(MyClass().return_private_class())
+ print(data_value)
diff --git a/tests/functional/a/access/access_to_protected_members_typing.rc b/tests/functional/a/access/access_to_protected_members_typing.rc
new file mode 100644
index 000000000..a17bb22da
--- /dev/null
+++ b/tests/functional/a/access/access_to_protected_members_typing.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.7
diff --git a/tests/functional/a/access/access_to_protected_members_typing.txt b/tests/functional/a/access/access_to_protected_members_typing.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/functional/a/access/access_to_protected_members_typing.txt