summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Mueller <30130371+cdce8p@users.noreply.github.com>2021-03-26 23:27:09 +0100
committerPierre Sassoulas <pierre.sassoulas@gmail.com>2021-03-27 21:29:52 +0100
commitd242db40b06f4a7c4dbe85ee1398955fdd0d3690 (patch)
treef83875129ae84aec41d41c294537632b82f2fb15
parent5d5f65727829240ffcb84b7be8c5d1e4dcefa0ed (diff)
downloadpylint-git-d242db40b06f4a7c4dbe85ee1398955fdd0d3690.tar.gz
Use value.qname() to check if class is subscriptable PEP585
-rw-r--r--ChangeLog2
-rw-r--r--pylint/checkers/utils.py81
-rw-r--r--tests/functional/p/postponed_evaluation_pep585.py18
-rw-r--r--tests/functional/p/postponed_evaluation_pep585.txt1
-rw-r--r--tests/functional/p/postponed_evaluation_pep585_py39.py18
-rw-r--r--tests/functional/p/postponed_evaluation_pep585_py39.txt1
6 files changed, 77 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog
index c6914c618..bc0060406 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -75,6 +75,8 @@ Release date: TBA
Closes #3763, #4238
+* Improve check if class is subscriptable PEP585
+
What's New in Pylint 2.7.2?
===========================
diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py
index 37abc3a87..ef9ff68d2 100644
--- a/pylint/checkers/utils.py
+++ b/pylint/checkers/utils.py
@@ -231,44 +231,44 @@ PYMETHODS = set(SPECIAL_METHODS_PARAMS)
SUBSCRIPTABLE_CLASSES_PEP585 = frozenset(
(
- "tuple",
- "list",
- "dict",
- "set",
- "frozenset",
- "type",
- "deque", # collections
- "defaultdict",
- "OrderedDict",
- "Counter",
- "ChainMap",
- "Awaitable", # collections.abc
- "Coroutine",
- "AsyncIterable",
- "AsyncIterator",
- "AsyncGenerator",
- "Iterable",
- "Iterator",
- "Generator",
- "Reversible",
- "Container",
- "Collection",
- "Callable",
- "Set # typing.AbstractSet",
- "MutableSet",
- "Mapping",
- "MutableMapping",
- "Sequence",
- "MutableSequence",
- "ByteString",
- "MappingView",
- "KeysView",
- "ItemsView",
- "ValuesView",
- "AbstractContextManager", # contextlib
- "AbstractAsyncContextManager",
- "Pattern", # re
- "Match",
+ "builtins.tuple",
+ "builtins.list",
+ "builtins.dict",
+ "builtins.set",
+ "builtins.frozenset",
+ "builtins.type",
+ "collections.deque",
+ "collections.defaultdict",
+ "collections.OrderedDict",
+ "collections.Counter",
+ "collections.ChainMap",
+ "_collections_abc.Awaitable",
+ "_collections_abc.Coroutine",
+ "_collections_abc.AsyncIterable",
+ "_collections_abc.AsyncIterator",
+ "_collections_abc.AsyncGenerator",
+ "_collections_abc.Iterable",
+ "_collections_abc.Iterator",
+ "_collections_abc.Generator",
+ "_collections_abc.Reversible",
+ "_collections_abc.Container",
+ "_collections_abc.Collection",
+ "_collections_abc.Callable",
+ "_collections_abc.Set # typing.AbstractSet",
+ "_collections_abc.MutableSet",
+ "_collections_abc.Mapping",
+ "_collections_abc.MutableMapping",
+ "_collections_abc.Sequence",
+ "_collections_abc.MutableSequence",
+ "_collections_abc.ByteString",
+ "_collections_abc.MappingView",
+ "_collections_abc.KeysView",
+ "_collections_abc.ItemsView",
+ "_collections_abc.ValuesView",
+ "contextlib.AbstractContextManager",
+ "contextlib.AbstractAsyncContextManager",
+ "re.Pattern",
+ "re.Match",
)
)
@@ -1353,11 +1353,8 @@ def is_class_subscriptable_pep585_with_postponed_evaluation_enabled(
parent_node = parent_node.parent
if isinstance(parent_node, astroid.Module):
return False
- if value.name in SUBSCRIPTABLE_CLASSES_PEP585:
+ if value.qname() in SUBSCRIPTABLE_CLASSES_PEP585:
return True
- for name in value.basenames:
- if name in SUBSCRIPTABLE_CLASSES_PEP585:
- return True
return False
diff --git a/tests/functional/p/postponed_evaluation_pep585.py b/tests/functional/p/postponed_evaluation_pep585.py
index 73072f308..e007a4a5f 100644
--- a/tests/functional/p/postponed_evaluation_pep585.py
+++ b/tests/functional/p/postponed_evaluation_pep585.py
@@ -3,7 +3,7 @@
This check requires Python 3.7 or 3.8!
Testing with 3.8 only, to support TypedDict.
"""
-# pylint: disable=missing-docstring,unused-argument,unused-import,too-few-public-methods,invalid-name,inherit-non-class,unsupported-binary-operation
+# pylint: disable=missing-docstring,unused-argument,unused-import,too-few-public-methods,invalid-name,inherit-non-class,unsupported-binary-operation,wrong-import-position,ungrouped-imports
from __future__ import annotations
import collections
import dataclasses
@@ -99,3 +99,19 @@ Alias4 = Tuple[list[int]] # [unsubscriptable-object]
Alias5 = Dict[str, list[int]] # [unsubscriptable-object]
Alias6 = int | list[int] # [unsubscriptable-object]
Alias7 = list[list[int]] # [unsubscriptable-object,unsubscriptable-object]
+
+
+import collections.abc
+import contextlib
+import re
+
+class OrderedDict:
+ pass
+
+var12: OrderedDict[str, int] # [unsubscriptable-object]
+var13: list[int]
+var14: collections.OrderedDict[str, int]
+var15: collections.Counter[int]
+var16: collections.abc.Iterable[int]
+var17: contextlib.AbstractContextManager[int]
+var18: re.Pattern[str]
diff --git a/tests/functional/p/postponed_evaluation_pep585.txt b/tests/functional/p/postponed_evaluation_pep585.txt
index 8fbec8077..12c524491 100644
--- a/tests/functional/p/postponed_evaluation_pep585.txt
+++ b/tests/functional/p/postponed_evaluation_pep585.txt
@@ -13,3 +13,4 @@ unsubscriptable-object:99:19::Value 'list' is unsubscriptable
unsubscriptable-object:100:15::Value 'list' is unsubscriptable
unsubscriptable-object:101:9::Value 'list' is unsubscriptable
unsubscriptable-object:101:14::Value 'list' is unsubscriptable
+unsubscriptable-object:111:7::Value 'OrderedDict' is unsubscriptable
diff --git a/tests/functional/p/postponed_evaluation_pep585_py39.py b/tests/functional/p/postponed_evaluation_pep585_py39.py
index 5c7261605..387c2273c 100644
--- a/tests/functional/p/postponed_evaluation_pep585_py39.py
+++ b/tests/functional/p/postponed_evaluation_pep585_py39.py
@@ -1,5 +1,5 @@
"""Test PEP 585 works as expected, starting with Python 3.9"""
-# pylint: disable=missing-docstring,unused-argument,unused-import,too-few-public-methods,invalid-name,inherit-non-class,unsupported-binary-operation
+# pylint: disable=missing-docstring,unused-argument,unused-import,too-few-public-methods,invalid-name,inherit-non-class,unsupported-binary-operation,wrong-import-position,ungrouped-imports
import collections
import dataclasses
import typing
@@ -94,3 +94,19 @@ Alias4 = Tuple[list[int]]
Alias5 = Dict[str, list[int]]
Alias6 = int | list[int]
Alias7 = list[list[int]]
+
+
+import collections.abc
+import contextlib
+import re
+
+class OrderedDict:
+ pass
+
+var12: OrderedDict[str, int] # [unsubscriptable-object]
+var13: list[int]
+var14: collections.OrderedDict[str, int]
+var15: collections.Counter[int]
+var16: collections.abc.Iterable[int]
+var17: contextlib.AbstractContextManager[int]
+var18: re.Pattern[str]
diff --git a/tests/functional/p/postponed_evaluation_pep585_py39.txt b/tests/functional/p/postponed_evaluation_pep585_py39.txt
new file mode 100644
index 000000000..e0d0010a2
--- /dev/null
+++ b/tests/functional/p/postponed_evaluation_pep585_py39.txt
@@ -0,0 +1 @@
+unsubscriptable-object:106:7::Value 'OrderedDict' is unsubscriptable