diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml index 92ae83f9fd..664f6f1d2f 100644 --- a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml @@ -81,11 +81,11 @@ body: label: Pylint version description: >- Please copy and paste the result of `pylint --version` or specify the range of - version affected. + versions affected. placeholder: | - pylint 2.9.6 - astroid 2.6.5 - Python 3.8.10 (default, Jun 2 2021, 10:49:15) [GCC 9.4.0] + pylint 3.3.0 + astroid 3.3.0 + Python 3.12.0 (v3.12.0:0fb18b02c8, Oct 2 2023, 09:45:56) render: shell validations: required: true diff --git a/.github/workflows/primer-test.yaml b/.github/workflows/primer-test.yaml index 764131fe4c..ed235fd923 100644 --- a/.github/workflows/primer-test.yaml +++ b/.github/workflows/primer-test.yaml @@ -30,7 +30,7 @@ jobs: timeout-minutes: 5 strategy: matrix: - python-version: [3.8, 3.9, "3.10", "3.11", "3.12"] + python-version: [3.9, "3.10", "3.11", "3.12"] outputs: python-key: ${{ steps.generate-python-key.outputs.key }} steps: @@ -72,7 +72,7 @@ jobs: needs: prepare-tests-linux strategy: matrix: - python-version: [3.8, 3.9, "3.10", "3.11", "3.12"] + python-version: [3.9, "3.10", "3.11", "3.12"] steps: - name: Check out code from GitHub uses: actions/checkout@v4.1.7 diff --git a/.github/workflows/primer_run_main.yaml b/.github/workflows/primer_run_main.yaml index 24c3204c2f..abb8c70e82 100644 --- a/.github/workflows/primer_run_main.yaml +++ b/.github/workflows/primer_run_main.yaml @@ -29,7 +29,7 @@ jobs: timeout-minutes: 45 strategy: matrix: - python-version: ["3.8", "3.12"] + python-version: ["3.9", "3.12"] batches: [4] batchIdx: [0, 1, 2, 3] steps: diff --git a/.github/workflows/primer_run_pr.yaml b/.github/workflows/primer_run_pr.yaml index 23c05eaf61..514e0f525a 100644 --- a/.github/workflows/primer_run_pr.yaml +++ b/.github/workflows/primer_run_pr.yaml @@ -38,7 +38,7 @@ jobs: timeout-minutes: 45 strategy: matrix: - python-version: ["3.8", "3.12"] + python-version: ["3.9", "3.12"] batches: [4] batchIdx: [0, 1, 2, 3] steps: @@ -198,7 +198,7 @@ jobs: echo ${{ github.event.pull_request.number }} | tee pr_number.txt - name: Upload PR number if: - startsWith(steps.python.outputs.python-version, '3.8') && matrix.batchIdx == 0 + startsWith(steps.python.outputs.python-version, '3.9') && matrix.batchIdx == 0 uses: actions/upload-artifact@v4.3.4 with: name: pr_number diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index d8dceb2201..ad6731eb5f 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,7 +31,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.8, 3.9, "3.10", "3.11", "3.12"] + python-version: [3.9, "3.10", "3.11", "3.12"] outputs: python-key: ${{ steps.generate-python-key.outputs.key }} steps: @@ -175,7 +175,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.8, 3.9, "3.10", "3.11", "3.12"] + python-version: [3.9, "3.10", "3.11", "3.12"] steps: - name: Set temp directory run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV @@ -225,7 +225,7 @@ jobs: fail-fast: false matrix: # We only run on the oldest supported version on Mac - python-version: [3.8] + python-version: [3.9] steps: - name: Check out code from GitHub uses: actions/checkout@v4.1.7 @@ -269,7 +269,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["pypy-3.8", "pypy-3.9", "pypy-3.10"] + python-version: ["pypy-3.9", "pypy-3.10"] steps: - name: Check out code from GitHub uses: actions/checkout@v4.1.7 diff --git a/README.rst b/README.rst index 2910eba680..d9c867443a 100644 --- a/README.rst +++ b/README.rst @@ -45,7 +45,7 @@ What is Pylint? --------------- Pylint is a `static code analyser`_ for Python 2 or 3. The latest version supports Python -3.8.0 and above. +3.9.0 and above. .. _`static code analyser`: https://en.wikipedia.org/wiki/Static_code_analysis diff --git a/doc/development_guide/contributor_guide/tests/launching_test.rst b/doc/development_guide/contributor_guide/tests/launching_test.rst index 78f42e144a..48c3a0649b 100644 --- a/doc/development_guide/contributor_guide/tests/launching_test.rst +++ b/doc/development_guide/contributor_guide/tests/launching_test.rst @@ -30,7 +30,7 @@ tox You can also *optionally* install tox_ and run our tests using the tox_ package, as in:: python -m tox - python -m tox -epy38 # for Python 3.8 suite only + python -m tox -epy312 # for Python 3.12 suite only python -m tox -epylint # for running Pylint over Pylint's codebase python -m tox -eformatting # for running formatting checks over Pylint's codebase diff --git a/doc/development_guide/contributor_guide/tests/writing_test.rst b/doc/development_guide/contributor_guide/tests/writing_test.rst index 9ce9ca1f0d..9a65994ab7 100644 --- a/doc/development_guide/contributor_guide/tests/writing_test.rst +++ b/doc/development_guide/contributor_guide/tests/writing_test.rst @@ -61,7 +61,6 @@ test runner. The following options are currently supported: - "min_pyver": Minimal python version required to run the test - "max_pyver": Python version from which the test won't be run. If the last supported version is 3.9 this setting should be set to 3.10. -- "min_pyver_end_position": Minimal python version required to check the end_line and end_column attributes of the message - "requires": Packages required to be installed locally to run the test - "except_implementations": List of python implementations on which the test should not run - "exclude_platforms": List of operating systems on which the test should not run diff --git a/doc/exts/pylint_messages.py b/doc/exts/pylint_messages.py index 7fc694bcc2..1dda5eda12 100644 --- a/doc/exts/pylint_messages.py +++ b/doc/exts/pylint_messages.py @@ -12,7 +12,7 @@ from inspect import getmodule from itertools import chain, groupby from pathlib import Path -from typing import DefaultDict, Dict, List, NamedTuple, Tuple +from typing import NamedTuple from sphinx.application import Sphinx @@ -52,8 +52,8 @@ class ExampleType(str, Enum): BAD = "bad" -MessagesDict = Dict[str, List[MessageData]] -OldMessagesDict = Dict[str, DefaultDict[Tuple[str, str], List[Tuple[str, str]]]] +MessagesDict = dict[str, list[MessageData]] +OldMessagesDict = dict[str, defaultdict[tuple[str, str], list[tuple[str, str]]]] """DefaultDict is indexed by tuples of (old name symbol, old name id) and values are tuples of (new name symbol, new name category). """ diff --git a/doc/exts/pylint_options.py b/doc/exts/pylint_options.py index d06a9b87d0..7ec9baa26e 100644 --- a/doc/exts/pylint_options.py +++ b/doc/exts/pylint_options.py @@ -10,7 +10,7 @@ from collections import defaultdict from inspect import getmodule from pathlib import Path -from typing import Dict, List, NamedTuple +from typing import NamedTuple import tomlkit from sphinx.application import Sphinx @@ -30,7 +30,7 @@ class OptionsData(NamedTuple): extension: bool -OptionsDataDict = Dict[str, List[OptionsData]] +OptionsDataDict = dict[str, list[OptionsData]] PYLINT_BASE_PATH = Path(__file__).resolve().parent.parent.parent """Base path to the project folder.""" diff --git a/doc/test_messages_documentation.py b/doc/test_messages_documentation.py index 96d98ed6c5..6898384f79 100644 --- a/doc/test_messages_documentation.py +++ b/doc/test_messages_documentation.py @@ -6,21 +6,9 @@ from __future__ import annotations -import sys - -if sys.version_info[:2] > (3, 9): - from collections import Counter -else: - from collections import Counter as _Counter - - class Counter(_Counter): - def total(self): - return len(tuple(self.elements())) - - +from collections import Counter from pathlib import Path -from typing import Counter as CounterType -from typing import TextIO, Tuple +from typing import TextIO import pytest @@ -31,7 +19,7 @@ def total(self): from pylint.testutils.constants import _EXPECTED_RE from pylint.testutils.reporter_for_tests import FunctionalTestReporter -MessageCounter = CounterType[Tuple[int, str]] +MessageCounter = Counter[tuple[int, str]] def get_functional_test_files_from_directory(input_dir: Path) -> list[tuple[str, Path]]: diff --git a/doc/user_guide/checkers/features.rst b/doc/user_guide/checkers/features.rst index 5e3a43d9c6..4dd5494b36 100644 --- a/doc/user_guide/checkers/features.rst +++ b/doc/user_guide/checkers/features.rst @@ -687,8 +687,7 @@ Method Args checker Messages ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :positional-only-arguments-expected (E3102): *`%s()` got some positional-only arguments passed as keyword arguments: %s* Emitted when positional-only arguments have been passed as keyword arguments. - Remove the keywords for the affected arguments in the function call. This - message can't be emitted when using Python < 3.8. + Remove the keywords for the affected arguments in the function call. :missing-timeout (W3101): *Missing timeout argument for method '%s' can cause your program to hang indefinitely* Used when a method needs a 'timeout' parameter in order to avoid waiting for a long time. If no timeout is specified explicitly the default value is used. diff --git a/doc/whatsnew/fragments/9774.other b/doc/whatsnew/fragments/9774.other new file mode 100644 index 0000000000..52d2f502c3 --- /dev/null +++ b/doc/whatsnew/fragments/9774.other @@ -0,0 +1,6 @@ +Remove support for launching pylint with Python 3.8. +Code that supports Python 3.8 can still be linted with the ``--py-version=3.8`` setting. + +``--min_pyver_end_position`` in the functional test runner is no longer relevant and is removed. + +Refs #9774 diff --git a/pylint/checkers/base/name_checker/checker.py b/pylint/checkers/base/name_checker/checker.py index 3514829fb1..1d8589a576 100644 --- a/pylint/checkers/base/name_checker/checker.py +++ b/pylint/checkers/base/name_checker/checker.py @@ -14,7 +14,7 @@ from collections.abc import Iterable from enum import Enum, auto from re import Pattern -from typing import TYPE_CHECKING, Tuple +from typing import TYPE_CHECKING import astroid from astroid import nodes @@ -34,7 +34,7 @@ if TYPE_CHECKING: from pylint.lint.pylinter import PyLinter -_BadNamesTuple = Tuple[nodes.NodeNG, str, str, interfaces.Confidence] +_BadNamesTuple = tuple[nodes.NodeNG, str, str, interfaces.Confidence] # Default patterns for name types that do not have styles DEFAULT_PATTERNS = { diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index afef0277ee..9d103640c0 100644 --- a/pylint/checkers/imports.py +++ b/pylint/checkers/imports.py @@ -13,7 +13,7 @@ from collections import defaultdict from collections.abc import ItemsView, Sequence from functools import cached_property -from typing import TYPE_CHECKING, Any, Dict, List, Union +from typing import TYPE_CHECKING, Any, Union import astroid from astroid import nodes @@ -43,7 +43,7 @@ # The dictionary with Any should actually be a _ImportTree again # but mypy doesn't support recursive types yet -_ImportTree = Dict[str, Union[List[Dict[str, Any]], List[str]]] +_ImportTree = dict[str, Union[list[dict[str, Any]], list[str]]] DEPRECATED_MODULES = { (0, 0, 0): {"tkinter.tix", "fpectl"}, diff --git a/pylint/checkers/method_args.py b/pylint/checkers/method_args.py index 59083fa25a..565309d282 100644 --- a/pylint/checkers/method_args.py +++ b/pylint/checkers/method_args.py @@ -41,7 +41,6 @@ class MethodArgsChecker(BaseChecker): "positional-only-arguments-expected", "Emitted when positional-only arguments have been passed as keyword arguments. " "Remove the keywords for the affected arguments in the function call.", - {"minversion": (3, 8)}, ), } options = ( diff --git a/pylint/checkers/nested_min_max.py b/pylint/checkers/nested_min_max.py index c8231fe7d2..2a3e05459e 100644 --- a/pylint/checkers/nested_min_max.py +++ b/pylint/checkers/nested_min_max.py @@ -14,7 +14,6 @@ from pylint.checkers import BaseChecker from pylint.checkers.utils import only_required_for_messages, safe_infer -from pylint.constants import PY39_PLUS from pylint.interfaces import INFERENCE if TYPE_CHECKING: @@ -139,8 +138,8 @@ def _is_splattable_expression(self, arg: nodes.NodeNG) -> bool: return self._is_splattable_expression( arg.left ) and self._is_splattable_expression(arg.right) - # Support dict merge (operator __or__ in Python 3.9) - if isinstance(arg, nodes.BinOp) and arg.op == "|" and PY39_PLUS: + # Support dict merge (operator __or__) + if isinstance(arg, nodes.BinOp) and arg.op == "|": return self._is_splattable_expression( arg.left ) and self._is_splattable_expression(arg.right) diff --git a/pylint/checkers/stdlib.py b/pylint/checkers/stdlib.py index 10c1d54bfc..9fab490b9c 100644 --- a/pylint/checkers/stdlib.py +++ b/pylint/checkers/stdlib.py @@ -8,7 +8,7 @@ import sys from collections.abc import Iterable -from typing import TYPE_CHECKING, Any, Dict, Set, Tuple +from typing import TYPE_CHECKING, Any import astroid from astroid import nodes, util @@ -22,7 +22,7 @@ if TYPE_CHECKING: from pylint.lint import PyLinter -DeprecationDict = Dict[Tuple[int, int, int], Set[str]] +DeprecationDict = dict[tuple[int, int, int], set[str]] OPEN_FILES_MODE = ("open", "file") OPEN_FILES_FUNCS = (*OPEN_FILES_MODE, "read_text", "write_text") diff --git a/pylint/checkers/symilar.py b/pylint/checkers/symilar.py index be9f90c48e..7a34bafdce 100644 --- a/pylint/checkers/symilar.py +++ b/pylint/checkers/symilar.py @@ -42,17 +42,7 @@ from getopt import GetoptError, getopt from io import BufferedIOBase, BufferedReader, BytesIO from itertools import chain -from typing import ( - TYPE_CHECKING, - Dict, - List, - NamedTuple, - NewType, - NoReturn, - TextIO, - Tuple, - Union, -) +from typing import TYPE_CHECKING, NamedTuple, NewType, NoReturn, TextIO, Union import astroid from astroid import nodes @@ -84,10 +74,10 @@ class LineSpecifs(NamedTuple): # Links LinesChunk object to the starting indices (in lineset's stripped lines) # of the different chunk of lines that are used to compute the hash -HashToIndex_T = Dict["LinesChunk", List[Index]] +HashToIndex_T = dict["LinesChunk", list[Index]] # Links index in the lineset's stripped lines to the real lines in the file -IndexToLines_T = Dict[Index, "SuccessiveLinesLimits"] +IndexToLines_T = dict[Index, "SuccessiveLinesLimits"] # The types the streams read by pylint can take. Originating from astroid.nodes.Module.stream() and open() STREAM_TYPES = Union[TextIO, BufferedReader, BytesIO] @@ -113,7 +103,7 @@ def __init__( # Links the indices to the starting line in both lineset's stripped lines to # the start and end lines in both files -CplIndexToCplLines_T = Dict["LineSetStartCouple", CplSuccessiveLinesLimits] +CplIndexToCplLines_T = dict["LineSetStartCouple", CplSuccessiveLinesLimits] class LinesChunk: @@ -212,7 +202,7 @@ def increment(self, value: Index) -> LineSetStartCouple: ) -LinesChunkLimits_T = Tuple["LineSet", LineNumber, LineNumber] +LinesChunkLimits_T = tuple["LineSet", LineNumber, LineNumber] def hash_lineset( diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index d2e9cd6b96..a029758cb3 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -13,10 +13,10 @@ import numbers import re import string -from collections.abc import Iterable, Iterator +from collections.abc import Callable, Iterable, Iterator from functools import lru_cache, partial from re import Match -from typing import TYPE_CHECKING, Any, Callable, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar import astroid.objects from astroid import TooManyLevelsError, nodes, util @@ -1817,10 +1817,7 @@ def is_sys_guard(node: nodes.If) -> bool: """Return True if IF stmt is a sys.version_info guard. >>> import sys - >>> if sys.version_info > (3, 8): - >>> from typing import Literal - >>> else: - >>> from typing_extensions import Literal + >>> from typing import Literal """ if isinstance(node.test, nodes.Compare): value = node.test.left diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index bfc80697c4..5d7a6137aa 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -32,7 +32,7 @@ is_sys_guard, overridden_method, ) -from pylint.constants import PY39_PLUS, PY311_PLUS, TYPING_NEVER, TYPING_NORETURN +from pylint.constants import PY311_PLUS, TYPING_NEVER, TYPING_NORETURN from pylint.interfaces import CONTROL_FLOW, HIGH, INFERENCE, INFERENCE_FAILURE from pylint.typing import MessageDefinitionTuple @@ -2350,23 +2350,6 @@ def _is_variable_violation( and defnode.col_offset < node.col_offset ) or (defnode.lineno < node.lineno) - or ( - # Issue in the `ast` module until py39 - # Nodes in a multiline string have the same lineno - # Could be false-positive without check - not PY39_PLUS - and defnode.lineno == node.lineno - and isinstance( - defstmt, - ( - nodes.Assign, - nodes.AnnAssign, - nodes.AugAssign, - nodes.Return, - ), - ) - and isinstance(defstmt.value, nodes.JoinedStr) - ) ) ): # Relation of a name to the same name in a named expression diff --git a/pylint/config/argument.py b/pylint/config/argument.py index 95cdde4ecb..a515a942b4 100644 --- a/pylint/config/argument.py +++ b/pylint/config/argument.py @@ -13,9 +13,10 @@ import os import pathlib import re -from collections.abc import Callable +from collections.abc import Callable, Sequence from glob import glob -from typing import Any, Literal, Pattern, Sequence, Tuple, Union +from re import Pattern +from typing import Any, Literal, Union from pylint import interfaces from pylint import utils as pylint_utils @@ -30,7 +31,7 @@ Pattern[str], Sequence[str], Sequence[Pattern[str]], - Tuple[int, ...], + tuple[int, ...], ] """List of possible argument types.""" diff --git a/pylint/config/config_file_parser.py b/pylint/config/config_file_parser.py index efc085e590..4ceed28d6e 100644 --- a/pylint/config/config_file_parser.py +++ b/pylint/config/config_file_parser.py @@ -10,7 +10,7 @@ import os import sys from pathlib import Path -from typing import TYPE_CHECKING, Dict, List, Tuple +from typing import TYPE_CHECKING from pylint.config.utils import _parse_rich_type_value @@ -22,7 +22,7 @@ if TYPE_CHECKING: from pylint.lint import PyLinter -PylintConfigFileData = Tuple[Dict[str, str], List[str]] +PylintConfigFileData = tuple[dict[str, str], list[str]] class _RawConfParser: diff --git a/pylint/constants.py b/pylint/constants.py index f147e5189a..0ba20162a1 100644 --- a/pylint/constants.py +++ b/pylint/constants.py @@ -14,8 +14,6 @@ from pylint.__pkginfo__ import __version__ from pylint.typing import MessageTypesFullName -PY38_PLUS = sys.version_info[:2] >= (3, 8) -PY39_PLUS = sys.version_info[:2] >= (3, 9) PY310_PLUS = sys.version_info[:2] >= (3, 10) PY311_PLUS = sys.version_info[:2] >= (3, 11) PY312_PLUS = sys.version_info[:2] >= (3, 12) diff --git a/pylint/extensions/code_style.py b/pylint/extensions/code_style.py index 622601c75f..00d539500c 100644 --- a/pylint/extensions/code_style.py +++ b/pylint/extensions/code_style.py @@ -5,7 +5,7 @@ from __future__ import annotations import sys -from typing import TYPE_CHECKING, Tuple, Type, cast +from typing import TYPE_CHECKING, cast from astroid import nodes @@ -152,7 +152,7 @@ def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None: if len(node.items) > 1 and all( isinstance(dict_value, nodes.Dict) for _, dict_value in node.items ): - KeyTupleT = Tuple[Type[nodes.NodeNG], str] + KeyTupleT = tuple[type[nodes.NodeNG], str] # Makes sure all keys are 'Const' string nodes keys_checked: set[KeyTupleT] = set() diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py index eff15cc444..6bba99031a 100644 --- a/pylint/lint/pylinter.py +++ b/pylint/lint/pylinter.py @@ -48,7 +48,6 @@ report_total_messages_stats, ) from pylint.lint.utils import ( - _is_relative_to, augmented_sys_path, get_fatal_error_message, prepare_crash_report, @@ -918,7 +917,7 @@ def _get_namespace_for_file( self, filepath: Path, namespaces: DirectoryNamespaceDict ) -> argparse.Namespace | None: for directory in namespaces: - if _is_relative_to(filepath, directory): + if Path.is_relative_to(filepath, directory): namespace = self._get_namespace_for_file( filepath, namespaces[directory][1] ) diff --git a/pylint/lint/utils.py b/pylint/lint/utils.py index a7fbfd0bc3..c5487a8c6d 100644 --- a/pylint/lint/utils.py +++ b/pylint/lint/utils.py @@ -133,16 +133,3 @@ def augmented_sys_path(additional_paths: Sequence[str]) -> Iterator[None]: yield finally: sys.path[:] = original - - -def _is_relative_to(self: Path, *other: Path) -> bool: - """Checks if self is relative to other. - - Backport of pathlib.Path.is_relative_to for Python <3.9 - TODO: py39: Remove this backport and use stdlib function. - """ - try: - self.relative_to(*other) - return True - except ValueError: - return False diff --git a/pylint/message/_deleted_message_ids.py b/pylint/message/_deleted_message_ids.py index 60289e8053..149a800b7c 100644 --- a/pylint/message/_deleted_message_ids.py +++ b/pylint/message/_deleted_message_ids.py @@ -4,7 +4,7 @@ from __future__ import annotations -from functools import lru_cache +from functools import cache from typing import NamedTuple @@ -131,7 +131,7 @@ class DeletedMessage(NamedTuple): } -@lru_cache(maxsize=None) +@cache def is_deleted_symbol(symbol: str) -> str | None: """Return the explanation for removal if the message was removed.""" for explanation, deleted_messages in DELETED_MESSAGES_IDS.items(): @@ -143,7 +143,7 @@ def is_deleted_symbol(symbol: str) -> str | None: return None -@lru_cache(maxsize=None) +@cache def is_deleted_msgid(msgid: str) -> str | None: """Return the explanation for removal if the message was removed.""" for explanation, deleted_messages in DELETED_MESSAGES_IDS.items(): @@ -155,7 +155,7 @@ def is_deleted_msgid(msgid: str) -> str | None: return None -@lru_cache(maxsize=None) +@cache def is_moved_symbol(symbol: str) -> str | None: """Return the explanation for moving if the message was moved to extensions.""" for explanation, moved_messages in MOVED_TO_EXTENSIONS.items(): @@ -167,7 +167,7 @@ def is_moved_symbol(symbol: str) -> str | None: return None -@lru_cache(maxsize=None) +@cache def is_moved_msgid(msgid: str) -> str | None: """Return the explanation for moving if the message was moved to extensions.""" for explanation, moved_messages in MOVED_TO_EXTENSIONS.items(): diff --git a/pylint/message/message_definition_store.py b/pylint/message/message_definition_store.py index cf271d7ffc..d56308541a 100644 --- a/pylint/message/message_definition_store.py +++ b/pylint/message/message_definition_store.py @@ -5,9 +5,9 @@ from __future__ import annotations import collections -import functools import sys from collections.abc import Sequence, ValuesView +from functools import cache from typing import TYPE_CHECKING from pylint.exceptions import UnknownMessageError @@ -58,9 +58,7 @@ def register_message(self, message: MessageDefinition) -> None: # and the arguments are relatively small we do not run the # risk of creating a large memory leak. # See discussion in: https://github.com/pylint-dev/pylint/pull/5673 - @functools.lru_cache( # pylint: disable=method-cache-max-size-none # noqa: B019 - maxsize=None - ) + @cache # pylint: disable=method-cache-max-size-none # noqa: B019 def get_message_definitions(self, msgid_or_symbol: str) -> list[MessageDefinition]: """Returns the Message definition for either a numeric or symbolic id. diff --git a/pylint/pyreverse/inspector.py b/pylint/pyreverse/inspector.py index 23ccfa6f30..8825363fa7 100644 --- a/pylint/pyreverse/inspector.py +++ b/pylint/pyreverse/inspector.py @@ -13,7 +13,8 @@ import os import traceback from abc import ABC, abstractmethod -from typing import Callable, Optional +from collections.abc import Callable +from typing import Optional import astroid from astroid import nodes diff --git a/pylint/pyreverse/utils.py b/pylint/pyreverse/utils.py index bdd28dc7c3..5ad92d3231 100644 --- a/pylint/pyreverse/utils.py +++ b/pylint/pyreverse/utils.py @@ -11,7 +11,8 @@ import shutil import subprocess import sys -from typing import TYPE_CHECKING, Any, Callable, Optional, Tuple, Union +from collections.abc import Callable +from typing import TYPE_CHECKING, Any, Optional, Union import astroid from astroid import nodes @@ -22,9 +23,9 @@ _CallbackT = Callable[ [nodes.NodeNG], - Union[Tuple[ClassDiagram], Tuple[PackageDiagram, ClassDiagram], None], + Union[tuple[ClassDiagram], tuple[PackageDiagram, ClassDiagram], None], ] - _CallbackTupleT = Tuple[Optional[_CallbackT], Optional[_CallbackT]] + _CallbackTupleT = tuple[Optional[_CallbackT], Optional[_CallbackT]] RCFILE = ".pyreverserc" diff --git a/pylint/reporters/reports_handler_mix_in.py b/pylint/reporters/reports_handler_mix_in.py index 95d45ba919..071879ca1e 100644 --- a/pylint/reporters/reports_handler_mix_in.py +++ b/pylint/reporters/reports_handler_mix_in.py @@ -6,7 +6,7 @@ import collections from collections.abc import MutableSequence -from typing import TYPE_CHECKING, DefaultDict, List, Tuple +from typing import TYPE_CHECKING from pylint.exceptions import EmptyReportError from pylint.reporters.ureports.nodes import Section @@ -17,7 +17,9 @@ from pylint.checkers import BaseChecker from pylint.lint.pylinter import PyLinter -ReportsDict = DefaultDict["BaseChecker", List[Tuple[str, str, ReportsCallable]]] +ReportsDict = collections.defaultdict[ + "BaseChecker", list[tuple[str, str, ReportsCallable]] +] class ReportsHandlerMixIn: diff --git a/pylint/reporters/text.py b/pylint/reporters/text.py index 0e3577199a..894207ad7d 100644 --- a/pylint/reporters/text.py +++ b/pylint/reporters/text.py @@ -15,7 +15,7 @@ import sys import warnings from dataclasses import asdict, fields -from typing import TYPE_CHECKING, Dict, NamedTuple, TextIO +from typing import TYPE_CHECKING, NamedTuple, TextIO from pylint.message import Message from pylint.reporters import BaseReporter @@ -65,7 +65,7 @@ def _colorize_ansi(self, msg: str) -> str: return msg -ColorMappingDict = Dict[str, MessageStyle] +ColorMappingDict = dict[str, MessageStyle] TITLE_UNDERLINES = ["", "=", "-", "."] diff --git a/pylint/reporters/ureports/nodes.py b/pylint/reporters/ureports/nodes.py index 59443996db..c414865121 100644 --- a/pylint/reporters/ureports/nodes.py +++ b/pylint/reporters/ureports/nodes.py @@ -9,8 +9,8 @@ from __future__ import annotations -from collections.abc import Iterable, Iterator -from typing import Any, Callable, TypeVar +from collections.abc import Callable, Iterable, Iterator +from typing import Any, TypeVar from pylint.reporters.ureports.base_writer import BaseWriter diff --git a/pylint/testutils/_primer/primer_command.py b/pylint/testutils/_primer/primer_command.py index 817c1a0d31..01c2bed368 100644 --- a/pylint/testutils/_primer/primer_command.py +++ b/pylint/testutils/_primer/primer_command.py @@ -7,7 +7,7 @@ import abc import argparse from pathlib import Path -from typing import Dict, TypedDict +from typing import TypedDict from pylint.reporters.json_reporter import OldJsonExport from pylint.testutils._primer import PackageToLint @@ -18,7 +18,7 @@ class PackageData(TypedDict): messages: list[OldJsonExport] -PackageMessages = Dict[str, PackageData] +PackageMessages = dict[str, PackageData] class PrimerCommand: diff --git a/pylint/testutils/checker_test_case.py b/pylint/testutils/checker_test_case.py index 3ffbbc44ad..6b26674b53 100644 --- a/pylint/testutils/checker_test_case.py +++ b/pylint/testutils/checker_test_case.py @@ -10,7 +10,6 @@ from astroid import nodes -from pylint.constants import IS_PYPY, PY39_PLUS from pylint.testutils.global_test_linter import linter from pylint.testutils.output_line import MessageTest from pylint.testutils.unittest_linter import UnittestLinter @@ -76,9 +75,8 @@ def assertAddsMessages( assert expected_msg.line == gotten_msg.line, msg assert expected_msg.col_offset == gotten_msg.col_offset, msg - if not IS_PYPY or PY39_PLUS: - assert expected_msg.end_line == gotten_msg.end_line, msg - assert expected_msg.end_col_offset == gotten_msg.end_col_offset, msg + assert expected_msg.end_line == gotten_msg.end_line, msg + assert expected_msg.end_col_offset == gotten_msg.end_col_offset, msg def walk(self, node: nodes.NodeNG) -> None: """Recursive walk on the given node.""" diff --git a/pylint/testutils/configuration_test.py b/pylint/testutils/configuration_test.py index 9933c9de81..ce2239e5c2 100644 --- a/pylint/testutils/configuration_test.py +++ b/pylint/testutils/configuration_test.py @@ -11,14 +11,14 @@ import logging import unittest from pathlib import Path -from typing import Any, Dict +from typing import Any from pylint.lint import Run # We use Any in this typing because the configuration contains real objects and constants # that could be a lot of things. ConfigurationValue = Any -PylintConfiguration = Dict[str, ConfigurationValue] +PylintConfiguration = dict[str, ConfigurationValue] def get_expected_or_default( diff --git a/pylint/testutils/functional/test_file.py b/pylint/testutils/functional/test_file.py index 37ba3a5fc6..8b83e38485 100644 --- a/pylint/testutils/functional/test_file.py +++ b/pylint/testutils/functional/test_file.py @@ -22,7 +22,6 @@ class NoFileError(Exception): class TestFileOptions(TypedDict): min_pyver: tuple[int, ...] max_pyver: tuple[int, ...] - min_pyver_end_position: tuple[int, ...] requires: list[str] except_implementations: list[str] exclude_platforms: list[str] @@ -33,7 +32,6 @@ class TestFileOptions(TypedDict): POSSIBLE_TEST_OPTIONS = { "min_pyver", "max_pyver", - "min_pyver_end_position", "requires", "except_implementations", "exclude_platforms", @@ -47,7 +45,6 @@ class FunctionalTestFile: _CONVERTERS: dict[str, Callable[[str], tuple[int, ...] | list[str]]] = { "min_pyver": parse_python_version, "max_pyver": parse_python_version, - "min_pyver_end_position": parse_python_version, "requires": lambda s: [i.strip() for i in s.split(",")], "except_implementations": lambda s: [i.strip() for i in s.split(",")], "exclude_platforms": lambda s: [i.strip() for i in s.split(",")], @@ -61,7 +58,6 @@ def __init__(self, directory: str, filename: str) -> None: self.options: TestFileOptions = { "min_pyver": (2, 5), "max_pyver": (4, 0), - "min_pyver_end_position": (3, 8), "requires": [], "except_implementations": [], "exclude_platforms": [], diff --git a/pylint/testutils/lint_module_test.py b/pylint/testutils/lint_module_test.py index 48ee5a0b2f..04615f6d5a 100644 --- a/pylint/testutils/lint_module_test.py +++ b/pylint/testutils/lint_module_test.py @@ -11,15 +11,13 @@ from collections import Counter from io import StringIO from pathlib import Path -from typing import Counter as CounterType -from typing import TextIO, Tuple +from typing import TextIO import pytest from _pytest.config import Config from pylint import checkers from pylint.config.config_initialization import _config_initialization -from pylint.constants import IS_PYPY from pylint.lint import PyLinter from pylint.message.message import Message from pylint.testutils.constants import _EXPECTED_RE, _OPERATORS, UPDATE_OPTION @@ -33,7 +31,7 @@ from pylint.testutils.output_line import OutputLine from pylint.testutils.reporter_for_tests import FunctionalTestReporter -MessageCounter = CounterType[Tuple[int, str]] +MessageCounter = Counter[tuple[int, str]] PYLINTRC = Path(__file__).parent / "testing_pylintrc" @@ -81,9 +79,6 @@ def __init__( self._linter._arg_parser.add_argument( "--max_pyver", type=parse_python_version, default=(4, 0) ) - self._linter._arg_parser.add_argument( - "--min_pyver_end_position", type=parse_python_version, default=(3, 8) - ) self._linter._arg_parser.add_argument( "--requires", type=lambda s: [i.strip() for i in s.split(",")], default=[] ) @@ -105,13 +100,6 @@ def __init__( self._linter, args_list=args, config_file=rc_file, reporter=_test_reporter ) - self._check_end_position = ( - sys.version_info >= self._linter.config.min_pyver_end_position - ) - # TODO: PY3.9: PyPy supports end_lineno from 3.9 and above - if self._check_end_position and IS_PYPY: - self._check_end_position = sys.version_info >= (3, 9) # pragma: no cover - self._config = config def setUp(self) -> None: @@ -227,8 +215,7 @@ def _get_expected(self) -> tuple[MessageCounter, list[OutputLine]]: expected_msgs = Counter() with self._open_expected_file() as f: expected_output_lines = [ - OutputLine.from_csv(row, self._check_end_position) - for row in csv.reader(f, "test") + OutputLine.from_csv(row) for row in csv.reader(f, "test") ] return expected_msgs, expected_output_lines @@ -242,9 +229,7 @@ def _get_actual(self) -> tuple[MessageCounter, list[OutputLine]]: msg.symbol != "fatal" ), f"Pylint analysis failed because of '{msg.msg}'" received_msgs[msg.line, msg.symbol] += 1 - received_output_lines.append( - OutputLine.from_msg(msg, self._check_end_position) - ) + received_output_lines.append(OutputLine.from_msg(msg)) return received_msgs, received_output_lines def _runTest(self) -> None: diff --git a/pylint/testutils/output_line.py b/pylint/testutils/output_line.py index c979a049c3..3146c12c78 100644 --- a/pylint/testutils/output_line.py +++ b/pylint/testutils/output_line.py @@ -5,15 +5,13 @@ from __future__ import annotations from collections.abc import Sequence -from typing import Any, NamedTuple, TypeVar +from typing import Any, NamedTuple from astroid import nodes from pylint.interfaces import UNDEFINED, Confidence from pylint.message.message import Message -_T = TypeVar("_T") - class MessageTest(NamedTuple): msg_id: str @@ -41,17 +39,15 @@ class OutputLine(NamedTuple): confidence: str @classmethod - def from_msg(cls, msg: Message, check_endline: bool = True) -> OutputLine: + def from_msg(cls, msg: Message) -> OutputLine: """Create an OutputLine from a Pylint Message.""" column = cls._get_column(msg.column) - end_line = cls._get_py38_none_value(msg.end_line, check_endline) - end_column = cls._get_py38_none_value(msg.end_column, check_endline) return cls( msg.symbol, msg.line, column, - end_line, - end_column, + msg.end_line, + msg.end_column, msg.obj or "", msg.msg.replace("\r\n", "\n"), msg.confidence.name, @@ -62,19 +58,8 @@ def _get_column(column: str | int) -> int: """Handle column numbers.""" return int(column) - @staticmethod - def _get_py38_none_value(value: _T, check_endline: bool) -> _T | None: - """Used to make end_line and end_column None as indicated by our version - compared to `min_pyver_end_position`. - """ - if not check_endline: - return None # pragma: no cover - return value - @classmethod - def from_csv( - cls, row: Sequence[str] | str, check_endline: bool = True - ) -> OutputLine: + def from_csv(cls, row: Sequence[str] | str) -> OutputLine: """Create an OutputLine from a comma separated list (the functional tests expected output .txt files). """ @@ -83,12 +68,8 @@ def from_csv( try: line = int(row[1]) column = cls._get_column(row[2]) - end_line = cls._value_to_optional_int( - cls._get_py38_none_value(row[3], check_endline) - ) - end_column = cls._value_to_optional_int( - cls._get_py38_none_value(row[4], check_endline) - ) + end_line = cls._value_to_optional_int(row[3]) + end_column = cls._value_to_optional_int(row[4]) # symbol, line, column, end_line, end_column, node, msg, confidences assert len(row) == 8 return cls( diff --git a/pylint/typing.py b/pylint/typing.py index f9dde2e405..963222871f 100644 --- a/pylint/typing.py +++ b/pylint/typing.py @@ -7,20 +7,17 @@ from __future__ import annotations import argparse +from collections.abc import Iterable from pathlib import Path +from re import Pattern from typing import ( TYPE_CHECKING, Any, Callable, - Dict, - Iterable, Literal, NamedTuple, Optional, - Pattern, Protocol, - Tuple, - Type, TypedDict, Union, ) @@ -93,7 +90,7 @@ class ManagedMessage(NamedTuple): """All possible message categories.""" -OptionDict = Dict[ +OptionDict = dict[ str, Union[ None, @@ -102,12 +99,12 @@ class ManagedMessage(NamedTuple): int, Pattern[str], Iterable[Union[str, int, Pattern[str]]], - Type["_CallbackAction"], + type["_CallbackAction"], Callable[[Any], Any], Callable[[Any, Any, Any, Any], Any], ], ] -Options = Tuple[Tuple[str, OptionDict], ...] +Options = tuple[tuple[str, OptionDict], ...] ReportsCallable = Callable[["Section", "LinterStats", Optional["LinterStats"]], None] @@ -126,10 +123,10 @@ class ExtraMessageOptions(TypedDict, total=False): MessageDefinitionTuple = Union[ - Tuple[str, str, str], - Tuple[str, str, str, ExtraMessageOptions], + tuple[str, str, str], + tuple[str, str, str, ExtraMessageOptions], ] -DirectoryNamespaceDict = Dict[Path, Tuple[argparse.Namespace, "DirectoryNamespaceDict"]] +DirectoryNamespaceDict = dict[Path, tuple[argparse.Namespace, "DirectoryNamespaceDict"]] class GetProjectCallable(Protocol): diff --git a/pylint/utils/ast_walker.py b/pylint/utils/ast_walker.py index 367a39b817..2e7be0677b 100644 --- a/pylint/utils/ast_walker.py +++ b/pylint/utils/ast_walker.py @@ -7,8 +7,8 @@ import sys import traceback from collections import defaultdict -from collections.abc import Sequence -from typing import TYPE_CHECKING, Callable +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING from astroid import nodes diff --git a/pylint/utils/file_state.py b/pylint/utils/file_state.py index bc2763eaa4..45217bb7ea 100644 --- a/pylint/utils/file_state.py +++ b/pylint/utils/file_state.py @@ -7,7 +7,7 @@ import collections from collections import defaultdict from collections.abc import Iterator -from typing import TYPE_CHECKING, Dict, Literal +from typing import TYPE_CHECKING, Literal from astroid import nodes @@ -21,7 +21,7 @@ from pylint.message import MessageDefinition, MessageDefinitionStore -MessageStateDict = Dict[str, Dict[int, bool]] +MessageStateDict = dict[str, dict[int, bool]] class FileState: diff --git a/pylint/utils/utils.py b/pylint/utils/utils.py index 73e9e6a5f3..9316bcb7aa 100644 --- a/pylint/utils/utils.py +++ b/pylint/utils/utils.py @@ -25,17 +25,8 @@ from collections import deque from collections.abc import Iterable, Sequence from io import BufferedReader, BytesIO -from typing import ( - TYPE_CHECKING, - Any, - List, - Literal, - Pattern, - TextIO, - Tuple, - TypeVar, - Union, -) +from re import Pattern +from typing import TYPE_CHECKING, Any, Literal, TextIO, TypeVar, Union from astroid import Module, modutils, nodes @@ -76,10 +67,10 @@ "T_GlobalOptionReturnTypes", bool, int, - List[str], + list[str], Pattern[str], - List[Pattern[str]], - Tuple[int, ...], + list[Pattern[str]], + tuple[int, ...], ) diff --git a/pylintrc b/pylintrc index fc3bc4cc9c..8989a90a77 100644 --- a/pylintrc +++ b/pylintrc @@ -54,7 +54,7 @@ unsafe-load-any-extension=no extension-pkg-allow-list= # Minimum supported python version -py-version = 3.8.0 +py-version = 3.9.0 # Control the amount of potential inferred values when inferring a single # object. This can help the performance when dealing with large functions or diff --git a/pyproject.toml b/pyproject.toml index b5e430c7ac..084784241f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,6 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -32,7 +31,7 @@ classifiers = [ "Topic :: Software Development :: Testing", "Typing :: Typed" ] -requires-python = ">=3.8.0" +requires-python = ">=3.9.0" dependencies = [ "dill>=0.2;python_version<'3.11'", "dill>=0.3.6;python_version>='3.11'", diff --git a/tests/checkers/unittest_stdlib.py b/tests/checkers/unittest_stdlib.py index df0bcfd518..9b45fd33b3 100644 --- a/tests/checkers/unittest_stdlib.py +++ b/tests/checkers/unittest_stdlib.py @@ -6,7 +6,7 @@ import contextlib from collections.abc import Callable, Iterator -from typing import Any, Type +from typing import Any import astroid from astroid import nodes @@ -16,7 +16,7 @@ from pylint.checkers import stdlib from pylint.testutils import CheckerTestCase -_NodeNGT = Type[nodes.NodeNG] +_NodeNGT = type[nodes.NodeNG] @contextlib.contextmanager diff --git a/tests/checkers/unittest_symilar.py b/tests/checkers/unittest_symilar.py index 3619e24709..43ba7cd6c3 100644 --- a/tests/checkers/unittest_symilar.py +++ b/tests/checkers/unittest_symilar.py @@ -9,7 +9,6 @@ import pytest from pylint.checkers import symilar -from pylint.constants import IS_PYPY, PY39_PLUS from pylint.lint import PyLinter from pylint.testutils import GenericTestReporter as Reporter @@ -131,10 +130,6 @@ def test_multiline_imports() -> None: ) -@pytest.mark.skipif( - IS_PYPY and not PY39_PLUS, - reason="Requires accurate 'end_lineno' value", -) def test_ignore_multiline_imports() -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: diff --git a/tests/functional/d/deprecated/deprecated_methods_py38.py b/tests/functional/d/deprecated/deprecated_methods_py38.py deleted file mode 100644 index 3a7dfe862b..0000000000 --- a/tests/functional/d/deprecated/deprecated_methods_py38.py +++ /dev/null @@ -1,57 +0,0 @@ -""" Functional tests for method deprecation. """ -# pylint: disable=missing-docstring, super-init-not-called, not-callable, comparison-of-constants -import base64 -import inspect -import logging -import nntplib -import time -import unittest -import xml.etree.ElementTree - -class MyTest(unittest.TestCase): - def test(self): - self.assert_(True) # [deprecated-method] - -xml.etree.ElementTree.Element('tag').getchildren() # [deprecated-method] -xml.etree.ElementTree.Element('tag').getiterator() # [deprecated-method] -nntplib.NNTP(None).xpath(None) # [deprecated-method] - - -inspect.getargspec(None) # [deprecated-method] -logging.warn("a") # [deprecated-method] -base64.encodestring("42") # [deprecated-method] -base64.decodestring("42") # [deprecated-method] - - -class SuperCrash(unittest.TestCase): - - def __init__(self): - # should not crash. - super()() - -xml.etree.ElementTree.iterparse(None) - - -class Tests(unittest.TestCase): - - def test_foo(self): - self.assertEquals(2 + 2, 4) # [deprecated-method] - self.assertNotEquals(2 + 2, 4) # [deprecated-method] - self.assertAlmostEquals(2 + 2, 4) # [deprecated-method] - self.assertNotAlmostEquals(2 + 2, 4) # [deprecated-method] - self.assert_("abc" == "2") # [deprecated-method] - - self.assertRaisesRegex(ValueError, "exception") - self.assertRegex("something", r".+") - - -class Deprecated: # pylint: disable=too-few-public-methods - deprecated_method = logging.warn - - -d = Deprecated() -d.deprecated_method() # [deprecated-method] - -def test(clock = time.time): - """time.clock is deprecated but time.time via an alias is not!""" - clock() diff --git a/tests/functional/d/deprecated/deprecated_methods_py38.rc b/tests/functional/d/deprecated/deprecated_methods_py38.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/d/deprecated/deprecated_methods_py38.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/d/deprecated/deprecated_methods_py38.txt b/tests/functional/d/deprecated/deprecated_methods_py38.txt deleted file mode 100644 index afed0c6b47..0000000000 --- a/tests/functional/d/deprecated/deprecated_methods_py38.txt +++ /dev/null @@ -1,14 +0,0 @@ -deprecated-method:13:8:13:26:MyTest.test:Using deprecated method assert_():UNDEFINED -deprecated-method:15:0:15:50::Using deprecated method getchildren():UNDEFINED -deprecated-method:16:0:16:50::Using deprecated method getiterator():UNDEFINED -deprecated-method:17:0:17:30::Using deprecated method xpath():UNDEFINED -deprecated-method:20:0:20:24::Using deprecated method getargspec():UNDEFINED -deprecated-method:21:0:21:17::Using deprecated method warn():UNDEFINED -deprecated-method:22:0:22:25::Using deprecated method encodestring():UNDEFINED -deprecated-method:23:0:23:25::Using deprecated method decodestring():UNDEFINED -deprecated-method:38:8:38:35:Tests.test_foo:Using deprecated method assertEquals():UNDEFINED -deprecated-method:39:8:39:38:Tests.test_foo:Using deprecated method assertNotEquals():UNDEFINED -deprecated-method:40:8:40:41:Tests.test_foo:Using deprecated method assertAlmostEquals():UNDEFINED -deprecated-method:41:8:41:44:Tests.test_foo:Using deprecated method assertNotAlmostEquals():UNDEFINED -deprecated-method:42:8:42:34:Tests.test_foo:Using deprecated method assert_():UNDEFINED -deprecated-method:53:0:53:21::Using deprecated method deprecated_method():UNDEFINED diff --git a/tests/functional/d/deprecated/deprecated_methods_py39.rc b/tests/functional/d/deprecated/deprecated_methods_py39.rc index 062f6df19c..4e2b748313 100644 --- a/tests/functional/d/deprecated/deprecated_methods_py39.rc +++ b/tests/functional/d/deprecated/deprecated_methods_py39.rc @@ -1,3 +1,2 @@ [testoptions] -min_pyver=3.9 max_pyver=3.10 diff --git a/tests/functional/d/deprecated/deprecated_module_py39.rc b/tests/functional/d/deprecated/deprecated_module_py39.rc index 062f6df19c..4e2b748313 100644 --- a/tests/functional/d/deprecated/deprecated_module_py39.rc +++ b/tests/functional/d/deprecated/deprecated_module_py39.rc @@ -1,3 +1,2 @@ [testoptions] -min_pyver=3.9 max_pyver=3.10 diff --git a/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.rc b/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.rc index 09ceaa5e54..5dc39b1a65 100644 --- a/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.rc +++ b/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.rc @@ -2,5 +2,4 @@ py-version=3.8 [testoptions] -min_pyver=3.9 max_pyver=3.10 diff --git a/tests/functional/ext/typing/typing_deprecated_alias.rc b/tests/functional/ext/typing/typing_deprecated_alias.rc index a4a4c9022c..d075a593ef 100644 --- a/tests/functional/ext/typing/typing_deprecated_alias.rc +++ b/tests/functional/ext/typing/typing_deprecated_alias.rc @@ -1,8 +1,3 @@ [main] py-version=3.9 load-plugins=pylint.extensions.typing - -[testoptions] -min_pyver=3.9 - -[typing] diff --git a/tests/functional/g/generic_alias/generic_alias_collections.rc b/tests/functional/g/generic_alias/generic_alias_collections.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_collections.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/g/generic_alias/generic_alias_collections_py37.py b/tests/functional/g/generic_alias/generic_alias_collections_py37.py deleted file mode 100644 index eaa153cedb..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_collections_py37.py +++ /dev/null @@ -1,133 +0,0 @@ -"""Test generic alias support for stdlib types (added in PY39). - -Raise [unsubscriptable-object] error for PY37 and PY38. -""" -# flake8: noqa -# pylint: disable=missing-docstring,pointless-statement -# pylint: disable=too-few-public-methods,multiple-statements,line-too-long -import abc -import collections -import collections.abc -import contextlib -import re - -# special -tuple[int, int] # [unsubscriptable-object] -type[int] # [unsubscriptable-object] -collections.abc.Callable[[int], str] # [unsubscriptable-object] - -# builtins -dict[int, str] # [unsubscriptable-object] -list[int] # [unsubscriptable-object] -set[int] # [unsubscriptable-object] -frozenset[int] # [unsubscriptable-object] - -# collections -collections.defaultdict[int, str] # [unsubscriptable-object] -collections.OrderedDict[int, str] # [unsubscriptable-object] -collections.ChainMap[int, str] # [unsubscriptable-object] -collections.Counter[int] # [unsubscriptable-object] -collections.deque[int] # [unsubscriptable-object] - -# collections.abc -collections.abc.Set[int] # [unsubscriptable-object] -collections.abc.Collection[int] # [unsubscriptable-object] -collections.abc.Container[int] # [unsubscriptable-object] -collections.abc.ItemsView[int, str] # [unsubscriptable-object] -collections.abc.KeysView[int] # [unsubscriptable-object] -collections.abc.Mapping[int, str] # [unsubscriptable-object] -collections.abc.MappingView[int] # [unsubscriptable-object] -collections.abc.MutableMapping[int, str] # [unsubscriptable-object] -collections.abc.MutableSequence[int] # [unsubscriptable-object] -collections.abc.MutableSet[int] # [unsubscriptable-object] -collections.abc.Sequence[int] # [unsubscriptable-object] -collections.abc.ValuesView[int] # [unsubscriptable-object] - -collections.abc.Iterable[int] # [unsubscriptable-object] -collections.abc.Iterator[int] # [unsubscriptable-object] -collections.abc.Generator[int, None, None] # [unsubscriptable-object] -collections.abc.Reversible[int] # [unsubscriptable-object] - -collections.abc.Coroutine[list[str], str, int] # [unsubscriptable-object,unsubscriptable-object] -collections.abc.AsyncGenerator[int, None] # [unsubscriptable-object] -collections.abc.AsyncIterable[int] # [unsubscriptable-object] -collections.abc.AsyncIterator[int] # [unsubscriptable-object] -collections.abc.Awaitable[int] # [unsubscriptable-object] - -# contextlib -contextlib.AbstractContextManager[int] # [unsubscriptable-object] -contextlib.AbstractAsyncContextManager[int] # [unsubscriptable-object] - -# re -re.Pattern[str] # [unsubscriptable-object] -re.Match[str] # [unsubscriptable-object] - - -# unsubscriptable types -collections.abc.Hashable -collections.abc.Sized -collections.abc.Hashable[int] # [unsubscriptable-object] -collections.abc.Sized[int] # [unsubscriptable-object] - -# subscriptable with Python 3.9 -collections.abc.ByteString[int] # [unsubscriptable-object] - - -# Missing implementation for 'collections.abc' derived classes -class DerivedHashable(collections.abc.Hashable): # [abstract-method] # __hash__ - pass - -class DerivedIterable(collections.abc.Iterable[int]): # [unsubscriptable-object] - pass - -class DerivedCollection(collections.abc.Collection[int]): # [unsubscriptable-object] - pass - - -# No implementation required for 'builtins' and 'collections' types -class DerivedList(list[int]): # [unsubscriptable-object] - pass - -class DerivedSet(set[int]): # [unsubscriptable-object] - pass - -class DerivedOrderedDict(collections.OrderedDict[int, str]): # [unsubscriptable-object] - pass - -class DerivedListIterable(list[collections.abc.Iterable[int]]): # [unsubscriptable-object,unsubscriptable-object] - pass - - -# Multiple generic base classes -class DerivedMultiple(collections.abc.Sized, collections.abc.Hashable): # [abstract-method,abstract-method] - pass - -class CustomAbstractCls1(abc.ABC): - pass -class CustomAbstractCls2(collections.abc.Sized, collections.abc.Iterable[CustomAbstractCls1]): # [abstract-method,unsubscriptable-object] # __len__ - pass -class CustomImplementation(CustomAbstractCls2): # [abstract-method] # __len__ - pass - - -# Type annotations -var_tuple: tuple[int, int] # [unsubscriptable-object] -var_dict: dict[int, str] # [unsubscriptable-object] -var_orderedDict: collections.OrderedDict[int, str] # [unsubscriptable-object] -var_container: collections.abc.Container[int] # [unsubscriptable-object] -var_sequence: collections.abc.Sequence[int] # [unsubscriptable-object] -var_iterable: collections.abc.Iterable[int] # [unsubscriptable-object] -var_awaitable: collections.abc.Awaitable[int] # [unsubscriptable-object] -var_contextmanager: contextlib.AbstractContextManager[int] # [unsubscriptable-object] -var_pattern: re.Pattern[int] # [unsubscriptable-object] -var_bytestring: collections.abc.ByteString -var_hashable: collections.abc.Hashable -var_sized: collections.abc.Sized - -# Type annotation with unsubscriptable type -var_int: int[int] # [unsubscriptable-object] -var_hashable2: collections.abc.Hashable[int] # [unsubscriptable-object] -var_sized2: collections.abc.Sized[int] # [unsubscriptable-object] - -# subscriptable with Python 3.9 -var_bytestring2: collections.abc.ByteString[int] # [unsubscriptable-object] diff --git a/tests/functional/g/generic_alias/generic_alias_collections_py37.rc b/tests/functional/g/generic_alias/generic_alias_collections_py37.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_collections_py37.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/g/generic_alias/generic_alias_collections_py37.txt b/tests/functional/g/generic_alias/generic_alias_collections_py37.txt deleted file mode 100644 index 72104b4bed..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_collections_py37.txt +++ /dev/null @@ -1,67 +0,0 @@ -unsubscriptable-object:15:0:15:5::Value 'tuple' is unsubscriptable:UNDEFINED -unsubscriptable-object:16:0:16:4::Value 'type' is unsubscriptable:UNDEFINED -unsubscriptable-object:17:0:17:24::Value 'collections.abc.Callable' is unsubscriptable:UNDEFINED -unsubscriptable-object:20:0:20:4::Value 'dict' is unsubscriptable:UNDEFINED -unsubscriptable-object:21:0:21:4::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:22:0:22:3::Value 'set' is unsubscriptable:UNDEFINED -unsubscriptable-object:23:0:23:9::Value 'frozenset' is unsubscriptable:UNDEFINED -unsubscriptable-object:26:0:26:23::Value 'collections.defaultdict' is unsubscriptable:UNDEFINED -unsubscriptable-object:27:0:27:23::Value 'collections.OrderedDict' is unsubscriptable:UNDEFINED -unsubscriptable-object:28:0:28:20::Value 'collections.ChainMap' is unsubscriptable:UNDEFINED -unsubscriptable-object:29:0:29:19::Value 'collections.Counter' is unsubscriptable:UNDEFINED -unsubscriptable-object:30:0:30:17::Value 'collections.deque' is unsubscriptable:UNDEFINED -unsubscriptable-object:33:0:33:19::Value 'collections.abc.Set' is unsubscriptable:UNDEFINED -unsubscriptable-object:34:0:34:26::Value 'collections.abc.Collection' is unsubscriptable:UNDEFINED -unsubscriptable-object:35:0:35:25::Value 'collections.abc.Container' is unsubscriptable:UNDEFINED -unsubscriptable-object:36:0:36:25::Value 'collections.abc.ItemsView' is unsubscriptable:UNDEFINED -unsubscriptable-object:37:0:37:24::Value 'collections.abc.KeysView' is unsubscriptable:UNDEFINED -unsubscriptable-object:38:0:38:23::Value 'collections.abc.Mapping' is unsubscriptable:UNDEFINED -unsubscriptable-object:39:0:39:27::Value 'collections.abc.MappingView' is unsubscriptable:UNDEFINED -unsubscriptable-object:40:0:40:30::Value 'collections.abc.MutableMapping' is unsubscriptable:UNDEFINED -unsubscriptable-object:41:0:41:31::Value 'collections.abc.MutableSequence' is unsubscriptable:UNDEFINED -unsubscriptable-object:42:0:42:26::Value 'collections.abc.MutableSet' is unsubscriptable:UNDEFINED -unsubscriptable-object:43:0:43:24::Value 'collections.abc.Sequence' is unsubscriptable:UNDEFINED -unsubscriptable-object:44:0:44:26::Value 'collections.abc.ValuesView' is unsubscriptable:UNDEFINED -unsubscriptable-object:46:0:46:24::Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:47:0:47:24::Value 'collections.abc.Iterator' is unsubscriptable:UNDEFINED -unsubscriptable-object:48:0:48:25::Value 'collections.abc.Generator' is unsubscriptable:UNDEFINED -unsubscriptable-object:49:0:49:26::Value 'collections.abc.Reversible' is unsubscriptable:UNDEFINED -unsubscriptable-object:51:0:51:25::Value 'collections.abc.Coroutine' is unsubscriptable:UNDEFINED -unsubscriptable-object:51:26:51:30::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:52:0:52:30::Value 'collections.abc.AsyncGenerator' is unsubscriptable:UNDEFINED -unsubscriptable-object:53:0:53:29::Value 'collections.abc.AsyncIterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:54:0:54:29::Value 'collections.abc.AsyncIterator' is unsubscriptable:UNDEFINED -unsubscriptable-object:55:0:55:25::Value 'collections.abc.Awaitable' is unsubscriptable:UNDEFINED -unsubscriptable-object:58:0:58:33::Value 'contextlib.AbstractContextManager' is unsubscriptable:UNDEFINED -unsubscriptable-object:59:0:59:38::Value 'contextlib.AbstractAsyncContextManager' is unsubscriptable:UNDEFINED -unsubscriptable-object:62:0:62:10::Value 're.Pattern' is unsubscriptable:UNDEFINED -unsubscriptable-object:63:0:63:8::Value 're.Match' is unsubscriptable:UNDEFINED -unsubscriptable-object:69:0:69:24::Value 'collections.abc.Hashable' is unsubscriptable:UNDEFINED -unsubscriptable-object:70:0:70:21::Value 'collections.abc.Sized' is unsubscriptable:UNDEFINED -unsubscriptable-object:73:0:73:26::Value 'collections.abc.ByteString' is unsubscriptable:UNDEFINED -abstract-method:77:0:77:21:DerivedHashable:Method '__hash__' is abstract in class 'Hashable' but is not overridden in child class 'DerivedHashable':INFERENCE -unsubscriptable-object:80:22:80:46:DerivedIterable:Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:83:24:83:50:DerivedCollection:Value 'collections.abc.Collection' is unsubscriptable:UNDEFINED -unsubscriptable-object:88:18:88:22:DerivedList:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:91:17:91:20:DerivedSet:Value 'set' is unsubscriptable:UNDEFINED -unsubscriptable-object:94:25:94:48:DerivedOrderedDict:Value 'collections.OrderedDict' is unsubscriptable:UNDEFINED -unsubscriptable-object:97:31:97:55:DerivedListIterable:Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:97:26:97:30:DerivedListIterable:Value 'list' is unsubscriptable:UNDEFINED -abstract-method:102:0:102:21:DerivedMultiple:Method '__hash__' is abstract in class 'Hashable' but is not overridden in child class 'DerivedMultiple':INFERENCE -abstract-method:102:0:102:21:DerivedMultiple:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'DerivedMultiple':INFERENCE -abstract-method:107:0:107:24:CustomAbstractCls2:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'CustomAbstractCls2':INFERENCE -unsubscriptable-object:107:48:107:72:CustomAbstractCls2:Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -abstract-method:109:0:109:26:CustomImplementation:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'CustomImplementation':INFERENCE -unsubscriptable-object:114:11:114:16::Value 'tuple' is unsubscriptable:UNDEFINED -unsubscriptable-object:115:10:115:14::Value 'dict' is unsubscriptable:UNDEFINED -unsubscriptable-object:116:17:116:40::Value 'collections.OrderedDict' is unsubscriptable:UNDEFINED -unsubscriptable-object:117:15:117:40::Value 'collections.abc.Container' is unsubscriptable:UNDEFINED -unsubscriptable-object:118:14:118:38::Value 'collections.abc.Sequence' is unsubscriptable:UNDEFINED -unsubscriptable-object:119:14:119:38::Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:120:15:120:40::Value 'collections.abc.Awaitable' is unsubscriptable:UNDEFINED -unsubscriptable-object:121:20:121:53::Value 'contextlib.AbstractContextManager' is unsubscriptable:UNDEFINED -unsubscriptable-object:122:13:122:23::Value 're.Pattern' is unsubscriptable:UNDEFINED -unsubscriptable-object:128:9:128:12::Value 'int' is unsubscriptable:UNDEFINED -unsubscriptable-object:129:15:129:39::Value 'collections.abc.Hashable' is unsubscriptable:UNDEFINED -unsubscriptable-object:130:12:130:33::Value 'collections.abc.Sized' is unsubscriptable:UNDEFINED -unsubscriptable-object:133:17:133:43::Value 'collections.abc.ByteString' is unsubscriptable:UNDEFINED diff --git a/tests/functional/g/generic_alias/generic_alias_collections_py37_with_typing.py b/tests/functional/g/generic_alias/generic_alias_collections_py37_with_typing.py deleted file mode 100644 index 5319f13b62..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_collections_py37_with_typing.py +++ /dev/null @@ -1,135 +0,0 @@ -"""Test generic alias support for stdlib types (added in PY39). - -Raise [unsubscriptable-object] error for PY37 and PY38. -Make sure `import typing` doesn't change anything. -""" -# flake8: noqa -# pylint: disable=missing-docstring,pointless-statement,unused-import -# pylint: disable=too-few-public-methods,multiple-statements,line-too-long -import abc -import collections -import collections.abc -import contextlib -import re -import typing - -# special -tuple[int, int] # [unsubscriptable-object] -type[int] # [unsubscriptable-object] -collections.abc.Callable[[int], str] # [unsubscriptable-object] - -# builtins -dict[int, str] # [unsubscriptable-object] -list[int] # [unsubscriptable-object] -set[int] # [unsubscriptable-object] -frozenset[int] # [unsubscriptable-object] - -# collections -collections.defaultdict[int, str] # [unsubscriptable-object] -collections.OrderedDict[int, str] # [unsubscriptable-object] -collections.ChainMap[int, str] # [unsubscriptable-object] -collections.Counter[int] # [unsubscriptable-object] -collections.deque[int] # [unsubscriptable-object] - -# collections.abc -collections.abc.Set[int] # [unsubscriptable-object] -collections.abc.Collection[int] # [unsubscriptable-object] -collections.abc.Container[int] # [unsubscriptable-object] -collections.abc.ItemsView[int, str] # [unsubscriptable-object] -collections.abc.KeysView[int] # [unsubscriptable-object] -collections.abc.Mapping[int, str] # [unsubscriptable-object] -collections.abc.MappingView[int] # [unsubscriptable-object] -collections.abc.MutableMapping[int, str] # [unsubscriptable-object] -collections.abc.MutableSequence[int] # [unsubscriptable-object] -collections.abc.MutableSet[int] # [unsubscriptable-object] -collections.abc.Sequence[int] # [unsubscriptable-object] -collections.abc.ValuesView[int] # [unsubscriptable-object] - -collections.abc.Iterable[int] # [unsubscriptable-object] -collections.abc.Iterator[int] # [unsubscriptable-object] -collections.abc.Generator[int, None, None] # [unsubscriptable-object] -collections.abc.Reversible[int] # [unsubscriptable-object] - -collections.abc.Coroutine[list[str], str, int] # [unsubscriptable-object,unsubscriptable-object] -collections.abc.AsyncGenerator[int, None] # [unsubscriptable-object] -collections.abc.AsyncIterable[int] # [unsubscriptable-object] -collections.abc.AsyncIterator[int] # [unsubscriptable-object] -collections.abc.Awaitable[int] # [unsubscriptable-object] - -# contextlib -contextlib.AbstractContextManager[int] # [unsubscriptable-object] -contextlib.AbstractAsyncContextManager[int] # [unsubscriptable-object] - -# re -re.Pattern[str] # [unsubscriptable-object] -re.Match[str] # [unsubscriptable-object] - - -# unsubscriptable types -collections.abc.Hashable -collections.abc.Sized -collections.abc.Hashable[int] # [unsubscriptable-object] -collections.abc.Sized[int] # [unsubscriptable-object] - -# subscriptable with Python 3.9 -collections.abc.ByteString[int] # [unsubscriptable-object] - - -# Missing implementation for 'collections.abc' derived classes -class DerivedHashable(collections.abc.Hashable): # [abstract-method] # __hash__ - pass - -class DerivedIterable(collections.abc.Iterable[int]): # [unsubscriptable-object] - pass - -class DerivedCollection(collections.abc.Collection[int]): # [unsubscriptable-object] - pass - - -# No implementation required for 'builtins' and 'collections' types -class DerivedList(list[int]): # [unsubscriptable-object] - pass - -class DerivedSet(set[int]): # [unsubscriptable-object] - pass - -class DerivedOrderedDict(collections.OrderedDict[int, str]): # [unsubscriptable-object] - pass - -class DerivedListIterable(list[collections.abc.Iterable[int]]): # [unsubscriptable-object,unsubscriptable-object] - pass - - -# Multiple generic base classes -class DerivedMultiple(collections.abc.Sized, collections.abc.Hashable): # [abstract-method,abstract-method] - pass - -class CustomAbstractCls1(abc.ABC): - pass -class CustomAbstractCls2(collections.abc.Sized, collections.abc.Iterable[CustomAbstractCls1]): # [abstract-method,unsubscriptable-object] # __len__ - pass -class CustomImplementation(CustomAbstractCls2): # [abstract-method] # __len__ - pass - - -# Type annotations -var_tuple: tuple[int, int] # [unsubscriptable-object] -var_dict: dict[int, str] # [unsubscriptable-object] -var_orderedDict: collections.OrderedDict[int, str] # [unsubscriptable-object] -var_container: collections.abc.Container[int] # [unsubscriptable-object] -var_sequence: collections.abc.Sequence[int] # [unsubscriptable-object] -var_iterable: collections.abc.Iterable[int] # [unsubscriptable-object] -var_awaitable: collections.abc.Awaitable[int] # [unsubscriptable-object] -var_contextmanager: contextlib.AbstractContextManager[int] # [unsubscriptable-object] -var_pattern: re.Pattern[int] # [unsubscriptable-object] -var_bytestring: collections.abc.ByteString -var_hashable: collections.abc.Hashable -var_sized: collections.abc.Sized - -# Type annotation with unsubscriptable type -var_int: int[int] # [unsubscriptable-object] -var_hashable2: collections.abc.Hashable[int] # [unsubscriptable-object] -var_sized2: collections.abc.Sized[int] # [unsubscriptable-object] - -# subscriptable with Python 3.9 -var_bytestring2: collections.abc.ByteString[int] # [unsubscriptable-object] diff --git a/tests/functional/g/generic_alias/generic_alias_collections_py37_with_typing.rc b/tests/functional/g/generic_alias/generic_alias_collections_py37_with_typing.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_collections_py37_with_typing.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/g/generic_alias/generic_alias_collections_py37_with_typing.txt b/tests/functional/g/generic_alias/generic_alias_collections_py37_with_typing.txt deleted file mode 100644 index 0dd989f2e8..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_collections_py37_with_typing.txt +++ /dev/null @@ -1,67 +0,0 @@ -unsubscriptable-object:17:0:17:5::Value 'tuple' is unsubscriptable:UNDEFINED -unsubscriptable-object:18:0:18:4::Value 'type' is unsubscriptable:UNDEFINED -unsubscriptable-object:19:0:19:24::Value 'collections.abc.Callable' is unsubscriptable:UNDEFINED -unsubscriptable-object:22:0:22:4::Value 'dict' is unsubscriptable:UNDEFINED -unsubscriptable-object:23:0:23:4::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:24:0:24:3::Value 'set' is unsubscriptable:UNDEFINED -unsubscriptable-object:25:0:25:9::Value 'frozenset' is unsubscriptable:UNDEFINED -unsubscriptable-object:28:0:28:23::Value 'collections.defaultdict' is unsubscriptable:UNDEFINED -unsubscriptable-object:29:0:29:23::Value 'collections.OrderedDict' is unsubscriptable:UNDEFINED -unsubscriptable-object:30:0:30:20::Value 'collections.ChainMap' is unsubscriptable:UNDEFINED -unsubscriptable-object:31:0:31:19::Value 'collections.Counter' is unsubscriptable:UNDEFINED -unsubscriptable-object:32:0:32:17::Value 'collections.deque' is unsubscriptable:UNDEFINED -unsubscriptable-object:35:0:35:19::Value 'collections.abc.Set' is unsubscriptable:UNDEFINED -unsubscriptable-object:36:0:36:26::Value 'collections.abc.Collection' is unsubscriptable:UNDEFINED -unsubscriptable-object:37:0:37:25::Value 'collections.abc.Container' is unsubscriptable:UNDEFINED -unsubscriptable-object:38:0:38:25::Value 'collections.abc.ItemsView' is unsubscriptable:UNDEFINED -unsubscriptable-object:39:0:39:24::Value 'collections.abc.KeysView' is unsubscriptable:UNDEFINED -unsubscriptable-object:40:0:40:23::Value 'collections.abc.Mapping' is unsubscriptable:UNDEFINED -unsubscriptable-object:41:0:41:27::Value 'collections.abc.MappingView' is unsubscriptable:UNDEFINED -unsubscriptable-object:42:0:42:30::Value 'collections.abc.MutableMapping' is unsubscriptable:UNDEFINED -unsubscriptable-object:43:0:43:31::Value 'collections.abc.MutableSequence' is unsubscriptable:UNDEFINED -unsubscriptable-object:44:0:44:26::Value 'collections.abc.MutableSet' is unsubscriptable:UNDEFINED -unsubscriptable-object:45:0:45:24::Value 'collections.abc.Sequence' is unsubscriptable:UNDEFINED -unsubscriptable-object:46:0:46:26::Value 'collections.abc.ValuesView' is unsubscriptable:UNDEFINED -unsubscriptable-object:48:0:48:24::Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:49:0:49:24::Value 'collections.abc.Iterator' is unsubscriptable:UNDEFINED -unsubscriptable-object:50:0:50:25::Value 'collections.abc.Generator' is unsubscriptable:UNDEFINED -unsubscriptable-object:51:0:51:26::Value 'collections.abc.Reversible' is unsubscriptable:UNDEFINED -unsubscriptable-object:53:0:53:25::Value 'collections.abc.Coroutine' is unsubscriptable:UNDEFINED -unsubscriptable-object:53:26:53:30::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:54:0:54:30::Value 'collections.abc.AsyncGenerator' is unsubscriptable:UNDEFINED -unsubscriptable-object:55:0:55:29::Value 'collections.abc.AsyncIterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:56:0:56:29::Value 'collections.abc.AsyncIterator' is unsubscriptable:UNDEFINED -unsubscriptable-object:57:0:57:25::Value 'collections.abc.Awaitable' is unsubscriptable:UNDEFINED -unsubscriptable-object:60:0:60:33::Value 'contextlib.AbstractContextManager' is unsubscriptable:UNDEFINED -unsubscriptable-object:61:0:61:38::Value 'contextlib.AbstractAsyncContextManager' is unsubscriptable:UNDEFINED -unsubscriptable-object:64:0:64:10::Value 're.Pattern' is unsubscriptable:UNDEFINED -unsubscriptable-object:65:0:65:8::Value 're.Match' is unsubscriptable:UNDEFINED -unsubscriptable-object:71:0:71:24::Value 'collections.abc.Hashable' is unsubscriptable:UNDEFINED -unsubscriptable-object:72:0:72:21::Value 'collections.abc.Sized' is unsubscriptable:UNDEFINED -unsubscriptable-object:75:0:75:26::Value 'collections.abc.ByteString' is unsubscriptable:UNDEFINED -abstract-method:79:0:79:21:DerivedHashable:Method '__hash__' is abstract in class 'Hashable' but is not overridden in child class 'DerivedHashable':INFERENCE -unsubscriptable-object:82:22:82:46:DerivedIterable:Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:85:24:85:50:DerivedCollection:Value 'collections.abc.Collection' is unsubscriptable:UNDEFINED -unsubscriptable-object:90:18:90:22:DerivedList:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:93:17:93:20:DerivedSet:Value 'set' is unsubscriptable:UNDEFINED -unsubscriptable-object:96:25:96:48:DerivedOrderedDict:Value 'collections.OrderedDict' is unsubscriptable:UNDEFINED -unsubscriptable-object:99:31:99:55:DerivedListIterable:Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:99:26:99:30:DerivedListIterable:Value 'list' is unsubscriptable:UNDEFINED -abstract-method:104:0:104:21:DerivedMultiple:Method '__hash__' is abstract in class 'Hashable' but is not overridden in child class 'DerivedMultiple':INFERENCE -abstract-method:104:0:104:21:DerivedMultiple:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'DerivedMultiple':INFERENCE -abstract-method:109:0:109:24:CustomAbstractCls2:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'CustomAbstractCls2':INFERENCE -unsubscriptable-object:109:48:109:72:CustomAbstractCls2:Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -abstract-method:111:0:111:26:CustomImplementation:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'CustomImplementation':INFERENCE -unsubscriptable-object:116:11:116:16::Value 'tuple' is unsubscriptable:UNDEFINED -unsubscriptable-object:117:10:117:14::Value 'dict' is unsubscriptable:UNDEFINED -unsubscriptable-object:118:17:118:40::Value 'collections.OrderedDict' is unsubscriptable:UNDEFINED -unsubscriptable-object:119:15:119:40::Value 'collections.abc.Container' is unsubscriptable:UNDEFINED -unsubscriptable-object:120:14:120:38::Value 'collections.abc.Sequence' is unsubscriptable:UNDEFINED -unsubscriptable-object:121:14:121:38::Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:122:15:122:40::Value 'collections.abc.Awaitable' is unsubscriptable:UNDEFINED -unsubscriptable-object:123:20:123:53::Value 'contextlib.AbstractContextManager' is unsubscriptable:UNDEFINED -unsubscriptable-object:124:13:124:23::Value 're.Pattern' is unsubscriptable:UNDEFINED -unsubscriptable-object:130:9:130:12::Value 'int' is unsubscriptable:UNDEFINED -unsubscriptable-object:131:15:131:39::Value 'collections.abc.Hashable' is unsubscriptable:UNDEFINED -unsubscriptable-object:132:12:132:33::Value 'collections.abc.Sized' is unsubscriptable:UNDEFINED -unsubscriptable-object:135:17:135:43::Value 'collections.abc.ByteString' is unsubscriptable:UNDEFINED diff --git a/tests/functional/g/generic_alias/generic_alias_mixed_py37.py b/tests/functional/g/generic_alias/generic_alias_mixed_py37.py deleted file mode 100644 index cb7a4d0f43..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_mixed_py37.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Test generic alias support with mix of typing.py and stdlib types. - -Possible with postponed evaluation enabled, starting with PY37. -""" -# flake8: noqa -# pylint: disable=missing-docstring,pointless-statement -# pylint: disable=too-few-public-methods,multiple-statements,line-too-long -from __future__ import annotations - -import collections -import collections.abc -import contextlib -import re -import typing - -# Type annotations -var_orderedDict: collections.OrderedDict[int, str] -var_container: collections.abc.Container[int] -var_sequence: collections.abc.Sequence[int] -var_iterable: collections.abc.Iterable[int] -var_awaitable: collections.abc.Awaitable[int] -var_pattern: re.Pattern[int] -var_bytestring: collections.abc.ByteString -var_hashable: collections.abc.Hashable -var_ContextManager: contextlib.AbstractContextManager[int] - - -# No implementation required for 'builtins' -class DerivedListIterable(typing.List[typing.Iterable[int]]): - pass - - -# Missing implementation for 'collections.abc' derived classes -class DerivedHashable(typing.Hashable): # [abstract-method] # __hash__ - pass - -class DerivedIterable(typing.Iterable[int]): # [abstract-method] # __iter__ - pass - -class DerivedCollection(typing.Collection[int]): # [abstract-method,abstract-method,abstract-method] # __contains__, __iter__, __len__ - pass diff --git a/tests/functional/g/generic_alias/generic_alias_mixed_py37.rc b/tests/functional/g/generic_alias/generic_alias_mixed_py37.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_mixed_py37.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/g/generic_alias/generic_alias_mixed_py37.txt b/tests/functional/g/generic_alias/generic_alias_mixed_py37.txt deleted file mode 100644 index 188039c60d..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_mixed_py37.txt +++ /dev/null @@ -1,5 +0,0 @@ -abstract-method:34:0:34:21:DerivedHashable:Method '__hash__' is abstract in class 'Hashable' but is not overridden in child class 'DerivedHashable':INFERENCE -abstract-method:37:0:37:21:DerivedIterable:Method '__iter__' is abstract in class 'Iterable' but is not overridden in child class 'DerivedIterable':INFERENCE -abstract-method:40:0:40:23:DerivedCollection:Method '__contains__' is abstract in class 'Container' but is not overridden in child class 'DerivedCollection':INFERENCE -abstract-method:40:0:40:23:DerivedCollection:Method '__iter__' is abstract in class 'Iterable' but is not overridden in child class 'DerivedCollection':INFERENCE -abstract-method:40:0:40:23:DerivedCollection:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'DerivedCollection':INFERENCE diff --git a/tests/functional/g/generic_alias/generic_alias_mixed_py39.rc b/tests/functional/g/generic_alias/generic_alias_mixed_py39.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_mixed_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/g/generic_alias/generic_alias_postponed_evaluation_py37.py b/tests/functional/g/generic_alias/generic_alias_postponed_evaluation_py37.py deleted file mode 100644 index 02cbcf081c..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_postponed_evaluation_py37.py +++ /dev/null @@ -1,189 +0,0 @@ -"""Test generic alias support for stdlib types (added in PY39). - -In type annotation context, they can be used with postponed evaluation enabled, -starting with PY37. -""" -# flake8: noqa -# pylint: disable=missing-docstring,pointless-statement,invalid-name -# pylint: disable=too-few-public-methods,multiple-statements,line-too-long -from __future__ import annotations - -import abc -import collections -import collections.abc -import contextlib -import re - - -# ----- unsubscriptable (even with postponed evaluation) ----- -# special -tuple[int, int] # [unsubscriptable-object] -type[int] # [unsubscriptable-object] -collections.abc.Callable[[int], str] # [unsubscriptable-object] - -# builtins -dict[int, str] # [unsubscriptable-object] -list[int] # [unsubscriptable-object] -set[int] # [unsubscriptable-object] -frozenset[int] # [unsubscriptable-object] - -# collections -collections.defaultdict[int, str] # [unsubscriptable-object] -collections.OrderedDict[int, str] # [unsubscriptable-object] -collections.ChainMap[int, str] # [unsubscriptable-object] -collections.Counter[int] # [unsubscriptable-object] -collections.deque[int] # [unsubscriptable-object] - -# collections.abc -collections.abc.Set[int] # [unsubscriptable-object] -collections.abc.Collection[int] # [unsubscriptable-object] -collections.abc.Container[int] # [unsubscriptable-object] -collections.abc.ItemsView[int, str] # [unsubscriptable-object] -collections.abc.KeysView[int] # [unsubscriptable-object] -collections.abc.Mapping[int, str] # [unsubscriptable-object] -collections.abc.MappingView[int] # [unsubscriptable-object] -collections.abc.MutableMapping[int, str] # [unsubscriptable-object] -collections.abc.MutableSequence[int] # [unsubscriptable-object] -collections.abc.MutableSet[int] # [unsubscriptable-object] -collections.abc.Sequence[int] # [unsubscriptable-object] -collections.abc.ValuesView[int] # [unsubscriptable-object] - -collections.abc.Iterable[int] # [unsubscriptable-object] -collections.abc.Iterator[int] # [unsubscriptable-object] -collections.abc.Generator[int, None, None] # [unsubscriptable-object] -collections.abc.Reversible[int] # [unsubscriptable-object] - -collections.abc.Coroutine[list[str], str, int] # [unsubscriptable-object,unsubscriptable-object] -collections.abc.AsyncGenerator[int, None] # [unsubscriptable-object] -collections.abc.AsyncIterable[int] # [unsubscriptable-object] -collections.abc.AsyncIterator[int] # [unsubscriptable-object] -collections.abc.Awaitable[int] # [unsubscriptable-object] - -# contextlib -contextlib.AbstractContextManager[int] # [unsubscriptable-object] -contextlib.AbstractAsyncContextManager[int] # [unsubscriptable-object] - -# re -re.Pattern[str] # [unsubscriptable-object] -re.Match[str] # [unsubscriptable-object] - - -# unsubscriptable types -collections.abc.Hashable -collections.abc.Sized -collections.abc.Hashable[int] # [unsubscriptable-object] -collections.abc.Sized[int] # [unsubscriptable-object] - -# subscriptable with Python 3.9 -collections.abc.ByteString[int] # [unsubscriptable-object] - - -# Missing implementation for 'collections.abc' derived classes -class DerivedHashable(collections.abc.Hashable): # [abstract-method] # __hash__ - pass - -class DerivedIterable(collections.abc.Iterable[int]): # [unsubscriptable-object] - pass - -class DerivedCollection(collections.abc.Collection[int]): # [unsubscriptable-object] - pass - - -# No implementation required for 'builtins' and 'collections' types -class DerivedList(list[int]): # [unsubscriptable-object] - pass - -class DerivedSet(set[int]): # [unsubscriptable-object] - pass - -class DerivedOrderedDict(collections.OrderedDict[int, str]): # [unsubscriptable-object] - pass - -class DerivedListIterable(list[collections.abc.Iterable[int]]): # [unsubscriptable-object,unsubscriptable-object] - pass - - -# Multiple generic base classes -class DerivedMultiple(collections.abc.Sized, collections.abc.Hashable): # [abstract-method,abstract-method] - pass - -class CustomAbstractCls1(abc.ABC): - pass -class CustomAbstractCls2(collections.abc.Sized, collections.abc.Iterable[CustomAbstractCls1]): # [abstract-method,unsubscriptable-object] # __len__ - pass -class CustomImplementation(CustomAbstractCls2): # [abstract-method] # __len__ - pass - - - -# ----- subscriptable (with postponed evaluation) ----- -# special -var_tuple: tuple[int, int] -var_type: type[int] -var_callable: collections.abc.Callable[[int], str] - -# builtins -var_dict: dict[int, str] -var_list: list[int] -var_set: set[int] -var_frozenset: frozenset[int] - -# collections -var_defaultdict: collections.defaultdict[int, str] -var_OrderedDict: collections.OrderedDict[int, str] -var_ChainMap: collections.ChainMap[int, str] -var_Counter: collections.Counter[int] -var_deque: collections.deque[int] - -# collections.abc -var_abc_set: collections.abc.Set[int] -var_abc_collection: collections.abc.Collection[int] -var_abc_container: collections.abc.Container[int] -var_abc_ItemsView: collections.abc.ItemsView[int, str] -var_abc_KeysView: collections.abc.KeysView[int] -var_abc_Mapping: collections.abc.Mapping[int, str] -var_abc_MappingView: collections.abc.MappingView[int] -var_abc_MutableMapping: collections.abc.MutableMapping[int, str] -var_abc_MutableSequence: collections.abc.MutableSequence[int] -var_abc_MutableSet: collections.abc.MutableSet[int] -var_abc_Sequence: collections.abc.Sequence[int] -var_abc_ValuesView: collections.abc.ValuesView[int] - -var_abc_Iterable: collections.abc.Iterable[int] -var_abc_Iterator: collections.abc.Iterator[int] -var_abc_Generator: collections.abc.Generator[int, None, None] -var_abc_Reversible: collections.abc.Reversible[int] - -var_abc_Coroutine: collections.abc.Coroutine[list[str], str, int] -var_abc_AsyncGenerator: collections.abc.AsyncGenerator[int, None] -var_abc_AsyncIterable: collections.abc.AsyncIterable[int] -var_abc_AsyncIterator: collections.abc.AsyncIterator[int] -var_abc_Awaitable: collections.abc.Awaitable[int] - -# contextlib -var_ContextManager: contextlib.AbstractContextManager[int] -var_AsyncContextManager: contextlib.AbstractAsyncContextManager[int] - -# re -var_re_Pattern: re.Pattern[str] -var_re_Match: re.Match[str] - - -# unsubscriptable types -var_abc_Hashable: collections.abc.Hashable -var_abc_Sized: collections.abc.Sized -var_abc_Hashable2: collections.abc.Hashable[int] # string annotations aren't checked -var_abc_Sized2: collections.abc.Sized[int] # string annotations aren't checked - -# subscriptable with Python 3.9 -var_abc_ByteString: collections.abc.ByteString[int] - - -# Generic in type stubs only -> string annotations aren't checked -class A: - ... - -var_a1: A[str] # string annotations aren't checked -var_a2: "A[str]" # string annotations aren't checked -class B(A[str]): # [unsubscriptable-object] - ... diff --git a/tests/functional/g/generic_alias/generic_alias_postponed_evaluation_py37.rc b/tests/functional/g/generic_alias/generic_alias_postponed_evaluation_py37.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_postponed_evaluation_py37.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/g/generic_alias/generic_alias_postponed_evaluation_py37.txt b/tests/functional/g/generic_alias/generic_alias_postponed_evaluation_py37.txt deleted file mode 100644 index cbf46bfef4..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_postponed_evaluation_py37.txt +++ /dev/null @@ -1,55 +0,0 @@ -unsubscriptable-object:20:0:20:5::Value 'tuple' is unsubscriptable:UNDEFINED -unsubscriptable-object:21:0:21:4::Value 'type' is unsubscriptable:UNDEFINED -unsubscriptable-object:22:0:22:24::Value 'collections.abc.Callable' is unsubscriptable:UNDEFINED -unsubscriptable-object:25:0:25:4::Value 'dict' is unsubscriptable:UNDEFINED -unsubscriptable-object:26:0:26:4::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:27:0:27:3::Value 'set' is unsubscriptable:UNDEFINED -unsubscriptable-object:28:0:28:9::Value 'frozenset' is unsubscriptable:UNDEFINED -unsubscriptable-object:31:0:31:23::Value 'collections.defaultdict' is unsubscriptable:UNDEFINED -unsubscriptable-object:32:0:32:23::Value 'collections.OrderedDict' is unsubscriptable:UNDEFINED -unsubscriptable-object:33:0:33:20::Value 'collections.ChainMap' is unsubscriptable:UNDEFINED -unsubscriptable-object:34:0:34:19::Value 'collections.Counter' is unsubscriptable:UNDEFINED -unsubscriptable-object:35:0:35:17::Value 'collections.deque' is unsubscriptable:UNDEFINED -unsubscriptable-object:38:0:38:19::Value 'collections.abc.Set' is unsubscriptable:UNDEFINED -unsubscriptable-object:39:0:39:26::Value 'collections.abc.Collection' is unsubscriptable:UNDEFINED -unsubscriptable-object:40:0:40:25::Value 'collections.abc.Container' is unsubscriptable:UNDEFINED -unsubscriptable-object:41:0:41:25::Value 'collections.abc.ItemsView' is unsubscriptable:UNDEFINED -unsubscriptable-object:42:0:42:24::Value 'collections.abc.KeysView' is unsubscriptable:UNDEFINED -unsubscriptable-object:43:0:43:23::Value 'collections.abc.Mapping' is unsubscriptable:UNDEFINED -unsubscriptable-object:44:0:44:27::Value 'collections.abc.MappingView' is unsubscriptable:UNDEFINED -unsubscriptable-object:45:0:45:30::Value 'collections.abc.MutableMapping' is unsubscriptable:UNDEFINED -unsubscriptable-object:46:0:46:31::Value 'collections.abc.MutableSequence' is unsubscriptable:UNDEFINED -unsubscriptable-object:47:0:47:26::Value 'collections.abc.MutableSet' is unsubscriptable:UNDEFINED -unsubscriptable-object:48:0:48:24::Value 'collections.abc.Sequence' is unsubscriptable:UNDEFINED -unsubscriptable-object:49:0:49:26::Value 'collections.abc.ValuesView' is unsubscriptable:UNDEFINED -unsubscriptable-object:51:0:51:24::Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:52:0:52:24::Value 'collections.abc.Iterator' is unsubscriptable:UNDEFINED -unsubscriptable-object:53:0:53:25::Value 'collections.abc.Generator' is unsubscriptable:UNDEFINED -unsubscriptable-object:54:0:54:26::Value 'collections.abc.Reversible' is unsubscriptable:UNDEFINED -unsubscriptable-object:56:0:56:25::Value 'collections.abc.Coroutine' is unsubscriptable:UNDEFINED -unsubscriptable-object:56:26:56:30::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:57:0:57:30::Value 'collections.abc.AsyncGenerator' is unsubscriptable:UNDEFINED -unsubscriptable-object:58:0:58:29::Value 'collections.abc.AsyncIterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:59:0:59:29::Value 'collections.abc.AsyncIterator' is unsubscriptable:UNDEFINED -unsubscriptable-object:60:0:60:25::Value 'collections.abc.Awaitable' is unsubscriptable:UNDEFINED -unsubscriptable-object:63:0:63:33::Value 'contextlib.AbstractContextManager' is unsubscriptable:UNDEFINED -unsubscriptable-object:64:0:64:38::Value 'contextlib.AbstractAsyncContextManager' is unsubscriptable:UNDEFINED -unsubscriptable-object:67:0:67:10::Value 're.Pattern' is unsubscriptable:UNDEFINED -unsubscriptable-object:68:0:68:8::Value 're.Match' is unsubscriptable:UNDEFINED -unsubscriptable-object:74:0:74:24::Value 'collections.abc.Hashable' is unsubscriptable:UNDEFINED -unsubscriptable-object:75:0:75:21::Value 'collections.abc.Sized' is unsubscriptable:UNDEFINED -unsubscriptable-object:78:0:78:26::Value 'collections.abc.ByteString' is unsubscriptable:UNDEFINED -abstract-method:82:0:82:21:DerivedHashable:Method '__hash__' is abstract in class 'Hashable' but is not overridden in child class 'DerivedHashable':INFERENCE -unsubscriptable-object:85:22:85:46:DerivedIterable:Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:88:24:88:50:DerivedCollection:Value 'collections.abc.Collection' is unsubscriptable:UNDEFINED -unsubscriptable-object:93:18:93:22:DerivedList:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:96:17:96:20:DerivedSet:Value 'set' is unsubscriptable:UNDEFINED -unsubscriptable-object:99:25:99:48:DerivedOrderedDict:Value 'collections.OrderedDict' is unsubscriptable:UNDEFINED -unsubscriptable-object:102:31:102:55:DerivedListIterable:Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -unsubscriptable-object:102:26:102:30:DerivedListIterable:Value 'list' is unsubscriptable:UNDEFINED -abstract-method:107:0:107:21:DerivedMultiple:Method '__hash__' is abstract in class 'Hashable' but is not overridden in child class 'DerivedMultiple':INFERENCE -abstract-method:107:0:107:21:DerivedMultiple:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'DerivedMultiple':INFERENCE -abstract-method:112:0:112:24:CustomAbstractCls2:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'CustomAbstractCls2':INFERENCE -unsubscriptable-object:112:48:112:72:CustomAbstractCls2:Value 'collections.abc.Iterable' is unsubscriptable:UNDEFINED -abstract-method:114:0:114:26:CustomImplementation:Method '__len__' is abstract in class 'Sized' but is not overridden in child class 'CustomImplementation':INFERENCE -unsubscriptable-object:188:8:188:9:B:Value 'A' is unsubscriptable:UNDEFINED diff --git a/tests/functional/g/generic_alias/generic_alias_related_py39.rc b/tests/functional/g/generic_alias/generic_alias_related_py39.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/g/generic_alias/generic_alias_related_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/i/import_error.rc b/tests/functional/i/import_error.rc index 7278ff8f17..efd9369c9e 100644 --- a/tests/functional/i/import_error.rc +++ b/tests/functional/i/import_error.rc @@ -4,7 +4,3 @@ enable=multiple-imports [TYPECHECK] ignored-modules=external_module,fake_module.submodule,foo,bar,*_ignored - -[testoptions] -# TODO: PY3.9: This does pass on PyPy 3.9 -except_implementations=PyPy diff --git a/tests/functional/i/invalid/invalid_field_call.py b/tests/functional/i/invalid/invalid_field_call.py index 43ff41c429..62d62733ae 100644 --- a/tests/functional/i/invalid/invalid_field_call.py +++ b/tests/functional/i/invalid/invalid_field_call.py @@ -34,7 +34,6 @@ class DC: mc.field() a: float = field(init=False) b: float = dc.field(init=False) - # TODO(remove py3.9 min) pylint: disable-next=unsubscriptable-object c: list[float] = [field(), field()] # [invalid-field-call, invalid-field-call] @dc.dataclass @@ -42,7 +41,6 @@ class IsAlsoDC: field() # [invalid-field-call] a: float = field(init=False) b: float = dc.field(init=False) - # TODO(remove py3.9 min) pylint: disable-next=unsubscriptable-object c: list[float] = [field(), field()] # [invalid-field-call, invalid-field-call] @dc.dataclass(frozen=True) diff --git a/tests/functional/i/invalid/invalid_field_call.txt b/tests/functional/i/invalid/invalid_field_call.txt index c672a2bfea..5e4f0fe244 100644 --- a/tests/functional/i/invalid/invalid_field_call.txt +++ b/tests/functional/i/invalid/invalid_field_call.txt @@ -6,9 +6,9 @@ invalid-field-call:27:4:27:14:NotADataClass:Invalid usage of field(), it should invalid-field-call:28:15:28:35:NotADataClass:Invalid usage of field(), it should be used within a dataclass or the make_dataclass() function.:INFERENCE invalid-field-call:32:4:32:11:DC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE invalid-field-call:33:4:33:14:DC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE -invalid-field-call:38:22:38:29:DC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE -invalid-field-call:38:31:38:38:DC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE -invalid-field-call:42:4:42:11:IsAlsoDC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE -invalid-field-call:46:22:46:29:IsAlsoDC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE -invalid-field-call:46:31:46:38:IsAlsoDC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE -invalid-field-call:61:15:61:32:AlsoNotADataClass:Invalid usage of field(), it should be used within a dataclass or the make_dataclass() function.:INFERENCE +invalid-field-call:37:22:37:29:DC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE +invalid-field-call:37:31:37:38:DC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE +invalid-field-call:41:4:41:11:IsAlsoDC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE +invalid-field-call:44:22:44:29:IsAlsoDC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE +invalid-field-call:44:31:44:38:IsAlsoDC:Invalid usage of field(), it should be the value of an assignment within a dataclass.:INFERENCE +invalid-field-call:59:15:59:32:AlsoNotADataClass:Invalid usage of field(), it should be used within a dataclass or the make_dataclass() function.:INFERENCE diff --git a/tests/functional/m/method_cache_max_size_none_py39.py b/tests/functional/m/method_cache_max_size_none_py39.py deleted file mode 100644 index d0bd65755e..0000000000 --- a/tests/functional/m/method_cache_max_size_none_py39.py +++ /dev/null @@ -1,47 +0,0 @@ -"""Tests for method-cache-max-size-none""" -# pylint: disable=missing-function-docstring, reimported, too-few-public-methods -# pylint: disable=missing-class-docstring, function-redefined - -import functools -import functools as aliased_functools -from functools import cache -from functools import cache as aliased_cache - - -@cache -def my_func(param): - return param + 1 - - -class MyClassWithMethods: - @cache - @staticmethod - def my_func(param): - return param + 1 - - @cache - @classmethod - def my_func(cls, param): - return param + 1 - - @cache # [method-cache-max-size-none] - def my_func(self, param): - return param + 1 - - @functools.cache # [method-cache-max-size-none] - def my_func(self, param): - return param + 1 - - @aliased_functools.cache # [method-cache-max-size-none] - def my_func(self, param): - return param + 1 - - @aliased_cache # [method-cache-max-size-none] - def my_func(self, param): - return param + 1 - - # Check double decorating to check robustness of checker itself - @functools.lru_cache(maxsize=1) - @aliased_cache # [method-cache-max-size-none] - def my_func(self, param): - return param + 1 diff --git a/tests/functional/m/method_cache_max_size_none_py39.rc b/tests/functional/m/method_cache_max_size_none_py39.rc deleted file mode 100644 index 15ad50f5ab..0000000000 --- a/tests/functional/m/method_cache_max_size_none_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver = 3.9 diff --git a/tests/functional/m/method_cache_max_size_none_py39.txt b/tests/functional/m/method_cache_max_size_none_py39.txt deleted file mode 100644 index e364e50ef5..0000000000 --- a/tests/functional/m/method_cache_max_size_none_py39.txt +++ /dev/null @@ -1,5 +0,0 @@ -method-cache-max-size-none:27:5:27:10:MyClassWithMethods.my_func:'lru_cache(maxsize=None)' or 'cache' will keep all method args alive indefinitely, including 'self':INFERENCE -method-cache-max-size-none:31:5:31:20:MyClassWithMethods.my_func:'lru_cache(maxsize=None)' or 'cache' will keep all method args alive indefinitely, including 'self':INFERENCE -method-cache-max-size-none:35:5:35:28:MyClassWithMethods.my_func:'lru_cache(maxsize=None)' or 'cache' will keep all method args alive indefinitely, including 'self':INFERENCE -method-cache-max-size-none:39:5:39:18:MyClassWithMethods.my_func:'lru_cache(maxsize=None)' or 'cache' will keep all method args alive indefinitely, including 'self':INFERENCE -method-cache-max-size-none:45:5:45:18:MyClassWithMethods.my_func:'lru_cache(maxsize=None)' or 'cache' will keep all method args alive indefinitely, including 'self':INFERENCE diff --git a/tests/functional/m/method_hidden.py b/tests/functional/m/method_hidden.py index 19fd60c722..31bba74bf5 100644 --- a/tests/functional/m/method_hidden.py +++ b/tests/functional/m/method_hidden.py @@ -134,3 +134,9 @@ def __init__(self): class ChildTwo(ParentTwo): def __private(self): pass + + +class ChildHidingAncestorAttribute(Parent): + @functools().cached_property + def _protected(self): + pass diff --git a/tests/functional/m/method_hidden_py39.py b/tests/functional/m/method_hidden_py39.py deleted file mode 100644 index ac087d0d6c..0000000000 --- a/tests/functional/m/method_hidden_py39.py +++ /dev/null @@ -1,16 +0,0 @@ -# pylint: disable=too-few-public-methods,missing-docstring -"""check method hiding ancestor attribute -""" -import something_else as functools # pylint: disable=import-error - - -class Parent: - def __init__(self): - self._protected = None - - -class Child(Parent): - @functools().cached_property - def _protected(self): - # This test case is only valid for python3.9 and above - pass diff --git a/tests/functional/m/method_hidden_py39.rc b/tests/functional/m/method_hidden_py39.rc deleted file mode 100644 index 15ad50f5ab..0000000000 --- a/tests/functional/m/method_hidden_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver = 3.9 diff --git a/tests/functional/n/nested_min_max_py39.rc b/tests/functional/n/nested_min_max_py39.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/n/nested_min_max_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_decorator.rc b/tests/functional/n/non_ascii_name/non_ascii_name_decorator.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_decorator.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py38.py b/tests/functional/n/non_ascii_name/non_ascii_name_function_argument.py similarity index 89% rename from tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py38.py rename to tests/functional/n/non_ascii_name/non_ascii_name_function_argument.py index a75e1c6b78..377bf865e6 100644 --- a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py38.py +++ b/tests/functional/n/non_ascii_name/non_ascii_name_function_argument.py @@ -1,7 +1,5 @@ """ non ascii variable defined in a function - -This test is only for 3.8 as the starting column is incorrect """ diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument.txt b/tests/functional/n/non_ascii_name/non_ascii_name_function_argument.txt new file mode 100644 index 0000000000..8a26db2e12 --- /dev/null +++ b/tests/functional/n/non_ascii_name/non_ascii_name_function_argument.txt @@ -0,0 +1,2 @@ +non-ascii-name:9:4:9:13:okay:"Argument name ""łol"" contains a non-ASCII character, consider renaming it.":HIGH +non-ascii-name:21:4:21:12::"Argument name ""łol"" contains a non-ASCII character, consider renaming it.":HIGH diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py38.rc b/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py38.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py38.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py38.txt b/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py38.txt deleted file mode 100644 index 7813364747..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py38.txt +++ /dev/null @@ -1,2 +0,0 @@ -non-ascii-name:11:4:11:13:okay:"Argument name ""łol"" contains a non-ASCII character, consider renaming it.":HIGH -non-ascii-name:23:0:None:None::"Argument name ""łol"" contains a non-ASCII character, consider renaming it.":HIGH diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py39plus.py b/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py39plus.py deleted file mode 100644 index a2d87ac4d7..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py39plus.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -non ascii variable defined in a function - -This test is 3.9+ and not using 'min_pyver_end_position' -as the starting column is also incorrect on < 3.9 -""" - - -def okay( - just_some_thing_long_again: str, - lol_very_long_argument: str, - łol: str, # [non-ascii-name] -) -> bool: - """Be okay, yeah?""" - # Usage should not raise a second error - print(just_some_thing_long_again, lol_very_long_argument, łol) - return True - - -# Usage should raise a second error -okay( - "A VVVVVVVEEEERRRRRRRRRRYYYYYYYYYY LONG TIME ", - lol_very_long_argument="a", - łol="b", # [non-ascii-name] -) diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py39plus.rc b/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py39plus.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py39plus.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py39plus.txt b/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py39plus.txt deleted file mode 100644 index 0222308af6..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_function_argument_py39plus.txt +++ /dev/null @@ -1,2 +0,0 @@ -non-ascii-name:12:4:12:13:okay:"Argument name ""łol"" contains a non-ASCII character, consider renaming it.":HIGH -non-ascii-name:24:4:24:12::"Argument name ""łol"" contains a non-ASCII character, consider renaming it.":HIGH diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py38.py b/tests/functional/n/non_ascii_name/non_ascii_name_kwargs.py similarity index 79% rename from tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py38.py rename to tests/functional/n/non_ascii_name/non_ascii_name_kwargs.py index 3c7b8c6835..fbd382f41d 100644 --- a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py38.py +++ b/tests/functional/n/non_ascii_name/non_ascii_name_kwargs.py @@ -1,7 +1,5 @@ """ Defining non ASCII variables in a function call - -This test is only for 3.8 as the starting column is incorrect """ diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs.txt b/tests/functional/n/non_ascii_name/non_ascii_name_kwargs.txt new file mode 100644 index 0000000000..b5ab4d5bc8 --- /dev/null +++ b/tests/functional/n/non_ascii_name/non_ascii_name_kwargs.txt @@ -0,0 +1 @@ +non-ascii-name:14:4:14:10::"Argument name ""łol"" contains a non-ASCII character, consider renaming it.":HIGH diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py38.rc b/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py38.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py38.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py38.txt b/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py38.txt deleted file mode 100644 index b43189658f..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py38.txt +++ /dev/null @@ -1 +0,0 @@ -non-ascii-name:16:0:None:None::"Argument name ""łol"" contains a non-ASCII character, consider renaming it.":HIGH diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py39plus.py b/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py39plus.py deleted file mode 100644 index 0dfceb38f4..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py39plus.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -Defining non ASCII variables in a function call - -This test is 3.9+ and not using 'min_pyver_end_position' -as the starting column is also incorrect on < 3.9 -""" - - -def okay(**kwargs): - """Print kwargs""" - print(kwargs) - - -okay( - a_long_attribute_that_is_very_okay=1, - b_belongs_to_yet_another_okay_attributed=2, - łol=3, # [non-ascii-name] -) diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py39plus.rc b/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py39plus.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py39plus.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py39plus.txt b/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py39plus.txt deleted file mode 100644 index 7595a9d082..0000000000 --- a/tests/functional/n/non_ascii_name/non_ascii_name_kwargs_py39plus.txt +++ /dev/null @@ -1 +0,0 @@ -non-ascii-name:17:4:17:10::"Argument name ""łol"" contains a non-ASCII character, consider renaming it.":HIGH diff --git a/tests/functional/p/postponed/postponed_evaluation_pep585.py b/tests/functional/p/postponed/postponed_evaluation_pep585.py index 2317228e55..5354e081fd 100644 --- a/tests/functional/p/postponed/postponed_evaluation_pep585.py +++ b/tests/functional/p/postponed/postponed_evaluation_pep585.py @@ -1,18 +1,5 @@ -"""Test PEP 585 in combination with postponed evaluation PEP 563. - -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 -# pylint: disable=inherit-non-class,unsupported-binary-operation,wrong-import-position,ungrouped-imports -# pylint: disable=unused-variable,unnecessary-direct-lambda-call - -# Disabled because of a bug with pypy 3.8 see -# https://github.com/pylint-dev/pylint/pull/7918#issuecomment-1352737369 -# pylint: disable=multiple-statements - -from __future__ import annotations +"""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,wrong-import-position,ungrouped-imports,unused-variable,unnecessary-direct-lambda-call import collections import dataclasses import typing @@ -20,25 +7,25 @@ from typing import Any, Dict, NamedTuple, TypedDict, Union, Tuple -AliasInvalid = list[int] # [unsubscriptable-object] +AliasValid = list[int] class CustomIntList(typing.List[int]): pass -class CustomIntListError(list[int]): # [unsubscriptable-object] +class CustomIntListError(list[int]): pass cast_variable = [1, 2, 3] -cast_variable = typing.cast(list[int], cast_variable) # [unsubscriptable-object] +cast_variable = typing.cast(list[int], cast_variable) -T = typing.TypeVar("T", list[int], str) # [unsubscriptable-object] +T = typing.TypeVar("T", list[int], str) -(lambda x: 2)(list[int]) # [unsubscriptable-object] +(lambda x: 2)(list[int]) # Check typing.NamedTuple CustomNamedTuple = typing.NamedTuple( - "CustomNamedTuple", [("my_var", list[int])]) # [unsubscriptable-object] + "CustomNamedTuple", [("my_var", list[int])]) class CustomNamedTuple2(NamedTuple): my_var: list[int] @@ -48,9 +35,9 @@ class CustomNamedTuple3(typing.NamedTuple): # Check typing.TypedDict -CustomTypedDict = TypedDict("CustomTypedDict", my_var=list[int]) # [unsubscriptable-object] +CustomTypedDict = TypedDict("CustomTypedDict", my_var=list[int]) -CustomTypedDict2 = TypedDict("CustomTypedDict2", {"my_var": list[int]}) # [unsubscriptable-object] +CustomTypedDict2 = TypedDict("CustomTypedDict2", {"my_var": list[int]}) class CustomTypedDict3(TypedDict): my_var: list[int] @@ -101,12 +88,12 @@ def func(arg: list[int]): def func2() -> list[int]: pass -Alias2 = Union[list[str], None] # [unsubscriptable-object] -Alias3 = Union[Union[list[int], int]] # [unsubscriptable-object] -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] +Alias2 = Union[list[str], None] +Alias3 = Union[Union[list[int], int]] +Alias4 = Tuple[list[int]] +Alias5 = Dict[str, list[int]] +Alias6 = int | list[int] +Alias7 = list[list[int]] import collections.abc @@ -116,7 +103,7 @@ def func2() -> list[int]: class OrderedDict: pass -var12: OrderedDict[str, int] # string annotations aren't checked +var12: OrderedDict[str, int] # [unsubscriptable-object] var13: list[int] var14: collections.OrderedDict[str, int] var15: collections.Counter[int] @@ -126,15 +113,15 @@ class OrderedDict: def func3(): - AliasInvalid2 = list[int] # [unsubscriptable-object] + AliasInvalid2 = list[int] cast_variable2 = [1, 2, 3] - cast_variable2 = typing.cast(list[int], cast_variable2) # [unsubscriptable-object] + cast_variable2 = typing.cast(list[int], cast_variable2) var19: list[int] -def func4(arg=list[int]): # [unsubscriptable-object] +def func4(var=list[int]): pass -def func5(arg1: list[int], arg2=set[int]): # [unsubscriptable-object] +def func5(arg1: list[int], arg2=set[int]): pass def func6(arg1: list[int], /, *args: tuple[str], arg2: set[int], **kwargs: dict[str, Any]): diff --git a/tests/functional/p/postponed/postponed_evaluation_pep585.rc b/tests/functional/p/postponed/postponed_evaluation_pep585.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/p/postponed/postponed_evaluation_pep585.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/p/postponed/postponed_evaluation_pep585.txt b/tests/functional/p/postponed/postponed_evaluation_pep585.txt index 899dc59774..127e252a53 100644 --- a/tests/functional/p/postponed/postponed_evaluation_pep585.txt +++ b/tests/functional/p/postponed/postponed_evaluation_pep585.txt @@ -1,19 +1 @@ -unsubscriptable-object:23:15:23:19::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:28:25:28:29:CustomIntListError:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:32:28:32:32::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:34:24:34:28::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:36:14:36:18::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:41:36:41:40::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:51:54:51:58::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:53:60:53:64::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:104:15:104:19::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:105:21:105:25::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:106:15:106:19::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:107:19:107:23::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:108:15:108:19::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:109:9:109:13::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:109:14:109:18::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:129:20:129:24:func3:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:131:33:131:37:func3:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:134:14:134:18:func4:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:137:32:137:35:func5:Value 'set' is unsubscriptable:UNDEFINED +unsubscriptable-object:106:7:106:18::Value 'OrderedDict' is unsubscriptable:UNDEFINED diff --git a/tests/functional/p/postponed/postponed_evaluation_pep585_error.py b/tests/functional/p/postponed/postponed_evaluation_pep585_error.py deleted file mode 100644 index 9810c0c14b..0000000000 --- a/tests/functional/p/postponed/postponed_evaluation_pep585_error.py +++ /dev/null @@ -1,124 +0,0 @@ -"""Test PEP 585 without postponed evaluation. Everything should fail. - -This check requires Python 3.7 or Python 3.8! -Testing with 3.8 only, to support TypedDict. -""" - -# pylint: disable=missing-docstring,unused-argument,unused-import,too-few-public-methods -# pylint: disable=invalid-name,inherit-non-class,unsupported-binary-operation -# pylint: disable=unused-variable,line-too-long,unnecessary-direct-lambda-call - -# Disabled because of a bug with pypy 3.8 see -# https://github.com/pylint-dev/pylint/pull/7918#issuecomment-1352737369 -# pylint: disable=multiple-statements - -import collections -import dataclasses -import typing -from dataclasses import dataclass -from typing import Any, Dict, NamedTuple, TypedDict, Union - - -AliasInvalid = list[int] # [unsubscriptable-object] - -class CustomIntList(typing.List[int]): - pass - -class CustomIntListError(list[int]): # [unsubscriptable-object] - pass - -cast_variable = [1, 2, 3] -cast_variable = typing.cast(list[int], cast_variable) # [unsubscriptable-object] - -T = typing.TypeVar("T", list[int], str) # [unsubscriptable-object] - -(lambda x: 2)(list[int]) # [unsubscriptable-object] - - -# Check typing.NamedTuple -CustomNamedTuple = typing.NamedTuple( - "CustomNamedTuple", [("my_var", list[int])]) # [unsubscriptable-object] - -class CustomNamedTuple2(NamedTuple): - my_var: list[int] # [unsubscriptable-object] - -class CustomNamedTuple3(typing.NamedTuple): - my_var: list[int] # [unsubscriptable-object] - - -# Check typing.TypedDict -CustomTypedDict = TypedDict("CustomTypedDict", my_var=list[int]) # [unsubscriptable-object] - -CustomTypedDict2 = TypedDict("CustomTypedDict2", {"my_var": list[int]}) # [unsubscriptable-object] - -class CustomTypedDict3(TypedDict): - my_var: list[int] # [unsubscriptable-object] - -class CustomTypedDict4(typing.TypedDict): - my_var: list[int] # [unsubscriptable-object] - - -# Check dataclasses -def my_decorator(*args, **kwargs): - def wraps(*args, **kwargs): - pass - return wraps - -@dataclass -class CustomDataClass: - my_var: list[int] # [unsubscriptable-object] - -@dataclasses.dataclass -class CustomDataClass2: - my_var: list[int] # [unsubscriptable-object] - -@dataclass() -class CustomDataClass3: - my_var: list[int] # [unsubscriptable-object] - -@my_decorator -@dataclasses.dataclass -class CustomDataClass4: - my_var: list[int] # [unsubscriptable-object] - - -var1: set[int] # [unsubscriptable-object] -var2: collections.OrderedDict[str, int] # [unsubscriptable-object] -var3: dict[str, list[int]] # [unsubscriptable-object,unsubscriptable-object] -var4: Dict[str, list[int]] # [unsubscriptable-object] -var5: dict[tuple[int, int], str] # [unsubscriptable-object,unsubscriptable-object] -var6: Dict[tuple[int, int], str] # [unsubscriptable-object] -var7: list[list[int]] # [unsubscriptable-object,unsubscriptable-object] -var8: tuple[list[int]] # [unsubscriptable-object,unsubscriptable-object] -var9: int | list[str | int] # [unsubscriptable-object] -var10: Union[list[str], None] # [unsubscriptable-object] -var11: Union[Union[list[int], int]] # [unsubscriptable-object] - -def func(arg: list[int]): # [unsubscriptable-object] - pass - -def func2() -> list[int]: # [unsubscriptable-object] - pass - -Alias2 = Union[list[str], None] # [unsubscriptable-object] -Alias3 = Union[Union[list[int], int]] # [unsubscriptable-object] -Alias5 = Dict[str, list[int]] # [unsubscriptable-object] -Alias6 = int | list[int] # [unsubscriptable-object] -Alias7 = list[list[int]] # [unsubscriptable-object,unsubscriptable-object] - - -def func3(): - AliasInvalid2 = list[int] # [unsubscriptable-object] - cast_variable2 = [1, 2, 3] - cast_variable2 = typing.cast(list[int], cast_variable2) # [unsubscriptable-object] - var12: list[int] # [unsubscriptable-object] - -def func4(var=list[int]): # [unsubscriptable-object] - pass - -def func5(arg1: list[int], arg2=set[int]): # [unsubscriptable-object,unsubscriptable-object] - pass - -def func6(arg1: list[int], /, *args: tuple[str], arg2: set[int], **kwargs: dict[str, Any]): - # -1:[unsubscriptable-object,unsubscriptable-object,unsubscriptable-object,unsubscriptable-object] - pass diff --git a/tests/functional/p/postponed/postponed_evaluation_pep585_error.rc b/tests/functional/p/postponed/postponed_evaluation_pep585_error.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/p/postponed/postponed_evaluation_pep585_error.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/p/postponed/postponed_evaluation_pep585_error.txt b/tests/functional/p/postponed/postponed_evaluation_pep585_error.txt deleted file mode 100644 index 406081dfae..0000000000 --- a/tests/functional/p/postponed/postponed_evaluation_pep585_error.txt +++ /dev/null @@ -1,49 +0,0 @@ -unsubscriptable-object:22:15:22:19::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:27:25:27:29:CustomIntListError:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:31:28:31:32::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:33:24:33:28::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:35:14:35:18::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:40:36:40:40::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:43:12:43:16:CustomNamedTuple2:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:46:12:46:16:CustomNamedTuple3:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:50:54:50:58::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:52:60:52:64::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:55:12:55:16:CustomTypedDict3:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:58:12:58:16:CustomTypedDict4:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:69:12:69:16:CustomDataClass:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:73:12:73:16:CustomDataClass2:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:77:12:77:16:CustomDataClass3:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:82:12:82:16:CustomDataClass4:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:85:6:85:9::Value 'set' is unsubscriptable:UNDEFINED -unsubscriptable-object:86:6:86:29::Value 'collections.OrderedDict' is unsubscriptable:UNDEFINED -unsubscriptable-object:87:6:87:10::Value 'dict' is unsubscriptable:UNDEFINED -unsubscriptable-object:87:16:87:20::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:88:16:88:20::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:89:6:89:10::Value 'dict' is unsubscriptable:UNDEFINED -unsubscriptable-object:89:11:89:16::Value 'tuple' is unsubscriptable:UNDEFINED -unsubscriptable-object:90:11:90:16::Value 'tuple' is unsubscriptable:UNDEFINED -unsubscriptable-object:91:6:91:10::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:91:11:91:15::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:92:12:92:16::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:92:6:92:11::Value 'tuple' is unsubscriptable:UNDEFINED -unsubscriptable-object:93:12:93:16::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:94:13:94:17::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:95:19:95:23::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:97:14:97:18:func:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:100:15:100:19:func2:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:103:15:103:19::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:104:21:104:25::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:105:19:105:23::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:106:15:106:19::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:107:9:107:13::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:107:14:107:18::Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:111:20:111:24:func3:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:113:33:113:37:func3:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:114:11:114:15:func3:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:116:14:116:18:func4:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:119:16:119:20:func5:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:119:32:119:35:func5:Value 'set' is unsubscriptable:UNDEFINED -unsubscriptable-object:122:75:122:79:func6:Value 'dict' is unsubscriptable:UNDEFINED -unsubscriptable-object:122:16:122:20:func6:Value 'list' is unsubscriptable:UNDEFINED -unsubscriptable-object:122:55:122:58:func6:Value 'set' is unsubscriptable:UNDEFINED -unsubscriptable-object:122:37:122:42:func6:Value 'tuple' is unsubscriptable:UNDEFINED diff --git a/tests/functional/p/postponed/postponed_evaluation_pep585_py39.py b/tests/functional/p/postponed/postponed_evaluation_pep585_py39.py deleted file mode 100644 index 5354e081fd..0000000000 --- a/tests/functional/p/postponed/postponed_evaluation_pep585_py39.py +++ /dev/null @@ -1,128 +0,0 @@ -"""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,wrong-import-position,ungrouped-imports,unused-variable,unnecessary-direct-lambda-call -import collections -import dataclasses -import typing -from dataclasses import dataclass -from typing import Any, Dict, NamedTuple, TypedDict, Union, Tuple - - -AliasValid = list[int] - -class CustomIntList(typing.List[int]): - pass - -class CustomIntListError(list[int]): - pass - -cast_variable = [1, 2, 3] -cast_variable = typing.cast(list[int], cast_variable) - -T = typing.TypeVar("T", list[int], str) - -(lambda x: 2)(list[int]) - - -# Check typing.NamedTuple -CustomNamedTuple = typing.NamedTuple( - "CustomNamedTuple", [("my_var", list[int])]) - -class CustomNamedTuple2(NamedTuple): - my_var: list[int] - -class CustomNamedTuple3(typing.NamedTuple): - my_var: list[int] - - -# Check typing.TypedDict -CustomTypedDict = TypedDict("CustomTypedDict", my_var=list[int]) - -CustomTypedDict2 = TypedDict("CustomTypedDict2", {"my_var": list[int]}) - -class CustomTypedDict3(TypedDict): - my_var: list[int] - -class CustomTypedDict4(typing.TypedDict): - my_var: list[int] - - -# Check dataclasses -def my_decorator(*args, **kwargs): - def wraps(*args, **kwargs): - pass - return wraps - -@dataclass -class CustomDataClass: - my_var: list[int] - -@dataclasses.dataclass -class CustomDataClass2: - my_var: list[int] - -@dataclass() -class CustomDataClass3: - my_var: list[int] - -@my_decorator -@dataclasses.dataclass -class CustomDataClass4: - my_var: list[int] - - -var1: set[int] -var2: collections.OrderedDict[str, int] -var3: dict[str, list[int]] -var4: Dict[str, list[int]] -var5: dict[tuple[int, int], str] -var6: Dict[tuple[int, int], str] -var7: list[list[int]] -var8: tuple[list[int]] -var9: int | list[str | int] -var10: Union[list[str], None] -var11: Union[Union[list[int], int]] - -def func(arg: list[int]): - pass - -def func2() -> list[int]: - pass - -Alias2 = Union[list[str], None] -Alias3 = Union[Union[list[int], int]] -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] - - -def func3(): - AliasInvalid2 = list[int] - cast_variable2 = [1, 2, 3] - cast_variable2 = typing.cast(list[int], cast_variable2) - var19: list[int] - -def func4(var=list[int]): - pass - -def func5(arg1: list[int], arg2=set[int]): - pass - -def func6(arg1: list[int], /, *args: tuple[str], arg2: set[int], **kwargs: dict[str, Any]): - pass diff --git a/tests/functional/p/postponed/postponed_evaluation_pep585_py39.rc b/tests/functional/p/postponed/postponed_evaluation_pep585_py39.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/p/postponed/postponed_evaluation_pep585_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/p/postponed/postponed_evaluation_pep585_py39.txt b/tests/functional/p/postponed/postponed_evaluation_pep585_py39.txt deleted file mode 100644 index 127e252a53..0000000000 --- a/tests/functional/p/postponed/postponed_evaluation_pep585_py39.txt +++ /dev/null @@ -1 +0,0 @@ -unsubscriptable-object:106:7:106:18::Value 'OrderedDict' is unsubscriptable:UNDEFINED diff --git a/tests/functional/r/regression_02/regression_5408.rc b/tests/functional/r/regression_02/regression_5408.rc index 7b414202d3..b47a745259 100644 --- a/tests/functional/r/regression_02/regression_5408.rc +++ b/tests/functional/r/regression_02/regression_5408.rc @@ -1,3 +1,2 @@ [testoptions] -min_pyver=3.9 except_implementations=PyPy diff --git a/tests/functional/s/star/star_needs_assignment_target_py38.py b/tests/functional/s/star/star_needs_assignment_target_py38.py deleted file mode 100644 index fb5eea86a7..0000000000 --- a/tests/functional/s/star/star_needs_assignment_target_py38.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -Test PEP 0448 -- Additional Unpacking Generalizations -https://www.python.org/dev/peps/pep-0448/ -""" - -# pylint: disable=superfluous-parens, unnecessary-comprehension - -UNPACK_TUPLE = (*range(4), 4) -UNPACK_LIST = [*range(4), 4] -UNPACK_SET = {*range(4), 4} -UNPACK_DICT = {'a': 1, **{'b': '2'}} -UNPACK_DICT2 = {**UNPACK_DICT, "x": 1, "y": 2} -UNPACK_DICT3 = {**{'a': 1}, 'a': 2, **{'a': 3}} - -UNPACK_IN_COMP = {elem for elem in (*range(10))} # [star-needs-assignment-target] diff --git a/tests/functional/s/star/star_needs_assignment_target_py38.rc b/tests/functional/s/star/star_needs_assignment_target_py38.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/s/star/star_needs_assignment_target_py38.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/s/star/star_needs_assignment_target_py38.txt b/tests/functional/s/star/star_needs_assignment_target_py38.txt deleted file mode 100644 index fb5a5faa6b..0000000000 --- a/tests/functional/s/star/star_needs_assignment_target_py38.txt +++ /dev/null @@ -1 +0,0 @@ -star-needs-assignment-target:15:36:15:46::Can use starred expression only in assignment target:UNDEFINED diff --git a/tests/functional/s/super/super_init_not_called_extensions.py b/tests/functional/s/super/super_init_not_called_extensions.py deleted file mode 100644 index 241e0008a1..0000000000 --- a/tests/functional/s/super/super_init_not_called_extensions.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Tests for super-init-not-called.""" -# pylint: disable=too-few-public-methods - -from typing_extensions import Protocol as ExtensionProtocol - - -class TestProto(ExtensionProtocol): - """A protocol without __init__ using Protocol from typing_extensions.""" - - -class TestParent(TestProto): - """An implementation.""" - - def __init__(self): - ... - - -class TestChild(TestParent): - """An implementation which should call the init of TestParent.""" - - def __init__(self): # [super-init-not-called] - ... diff --git a/tests/functional/s/super/super_init_not_called_extensions.rc b/tests/functional/s/super/super_init_not_called_extensions.rc deleted file mode 100644 index d584aa9595..0000000000 --- a/tests/functional/s/super/super_init_not_called_extensions.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.9 diff --git a/tests/functional/s/super/super_init_not_called_extensions.txt b/tests/functional/s/super/super_init_not_called_extensions.txt deleted file mode 100644 index b80cb80be4..0000000000 --- a/tests/functional/s/super/super_init_not_called_extensions.txt +++ /dev/null @@ -1 +0,0 @@ -super-init-not-called:21:4:21:16:TestChild.__init__:__init__ method from base class 'TestParent' is not called:INFERENCE diff --git a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38.py b/tests/functional/u/unnecessary/unnecessary_dunder_call.py similarity index 100% rename from tests/functional/u/unnecessary/unnecessary_dunder_call_py38.py rename to tests/functional/u/unnecessary/unnecessary_dunder_call.py diff --git a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38.txt b/tests/functional/u/unnecessary/unnecessary_dunder_call.txt similarity index 100% rename from tests/functional/u/unnecessary/unnecessary_dunder_call_py38.txt rename to tests/functional/u/unnecessary/unnecessary_dunder_call.txt diff --git a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38.rc b/tests/functional/u/unnecessary/unnecessary_dunder_call_py38.rc deleted file mode 100644 index 28df6cccd9..0000000000 --- a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38.rc +++ /dev/null @@ -1,3 +0,0 @@ -[testoptions] -max_pyver=3.9 -except_implementations=PyPy diff --git a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38_pypy.py b/tests/functional/u/unnecessary/unnecessary_dunder_call_py38_pypy.py deleted file mode 100644 index f86e14651d..0000000000 --- a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38_pypy.py +++ /dev/null @@ -1,144 +0,0 @@ -"""Checks for unnecessary-dunder-call.""" -# pylint: disable=too-few-public-methods, undefined-variable -# pylint: disable=missing-class-docstring, missing-function-docstring -# pylint: disable=protected-access, unnecessary-lambda-assignment, unnecessary-lambda -from collections import OrderedDict -from typing import Any - -# Test includelisted dunder methods raise lint when manually called. -num_str = some_num.__str__() # [unnecessary-dunder-call] -num_repr = some_num.__add__(2) # [unnecessary-dunder-call] -my_repr = my_module.my_object.__repr__() # [unnecessary-dunder-call] - -MY_CONTAINS_BAD = {1, 2, 3}.__contains__(1) # [unnecessary-dunder-call] -MY_CONTAINS_GOOD = 1 in {1, 2, 3} - -# Just instantiate like a normal person please -my_list_bad = [] -my_list_bad.__init__({1, 2, 3}) # [unnecessary-dunder-call] -my_list_good = list({1, 2, 3}) - -# Test unknown/user-defined dunder methods don't raise lint. -my_woohoo = my_object.__woohoo__() - -# Test lint raised within function. -def is_bigger_than_two(val): - return val.__gt__(2) # [unnecessary-dunder-call] - -# Test dunder methods don't raise lint -# if within a dunder method definition. -class Foo1: - def __init__(self): - object.__init__(self) - -class Foo2: - def __init__(self): - super().__init__(self) - -class Bar1: - def __new__(cls): - object.__new__(cls) - -class Bar2: - def __new__(cls): - super().__new__(cls) - -class CustomRegistry(dict): - def __init__(self) -> None: - super().__init__() - self._entry_ids = {} - - def __setitem__(self, key, entry) -> None: - super().__setitem__(key, entry) - self._entry_ids.__setitem__(entry.id, entry) - self._entry_ids.__delitem__(entry.id) - - def __delitem__(self, key: str) -> None: - entry = self[key] - self._entry_ids.__delitem__(entry.id) - super().__delitem__(key) - -class CustomState: - def __init__(self, state): - self._state = state - - def __eq__(self, other: Any) -> bool: - return self._state.__eq__(other) - -class CustomDict(OrderedDict): - def __init__(self, *args, **kwds): - OrderedDict.__init__(self, *args, **kwds) - - def __setitem__(self, key, value): - OrderedDict.__setitem__(self, key, value) - - -class MyClass(list): - def __contains__(self, item): - print("do some special checks") - return super().__contains__(item) - -class PluginBase: - subclasses = [] - - def __init_subclass__(cls, **kwargs): - super().__init_subclass__(**kwargs) - cls.subclasses.append(cls) - -# Validate that dunder call is allowed -# at any depth within dunder definition -class SomeClass: - def __init__(self): - self.my_attr = object() - - def __setattr__(self, name, value): - def nested_function(): - self.my_attr.__setattr__(name, value) - - nested_function() - -# Allow use of dunder methods that don't -# have an alternate method of being called -class Base: - @classmethod - def get_first_subclass(cls): - for subklass in cls.__subclasses__(): - return subklass - return object - -# Test no lint raised for attributes. -my_instance_name = x.__class__.__name__ -my_pkg_version = pkg.__version__ - -# Allow use of dunder methods on non instantiated classes -MANUAL_SELF = int.__add__(1, 1) -MY_DICT = {"a": 1, "b": 2} -dict.__setitem__(MY_DICT, "key", "value") - -# Still flag instantiated classes -INSTANTIATED_SELF = int("1").__add__(1) # [unnecessary-dunder-call] -{"a": 1, "b": 2}.__setitem__("key", "value") # [unnecessary-dunder-call] - -# We also exclude dunder methods called on super -# since we can't apply alternate operators/functions here. -a = [1, 2, 3] -assert super(type(a), a).__str__() == "[1, 2, 3]" - -class MyString(str): - """Custom str implementation""" - def rjust(self, width, fillchar= ' '): - """Acceptable call to __index__""" - width = width.__index__() - -# Test no lint raised for these dunders within lambdas -lambda1 = lambda x: x.__setitem__(1,2) -lambda2 = lambda x: x.__del__(1) -lambda3 = lambda x,y: x.__ipow__(y) -lambda4 = lambda u,v: u.__setitem__(v()) - -# Test lint raised for these dunders within lambdas -lambda5 = lambda x: x.__gt__(3) # [unnecessary-dunder-call] -lambda6 = lambda x,y: x.__or__(y) # [unnecessary-dunder-call] -lambda7 = lambda x: x.__iter__() # [unnecessary-dunder-call] -lambda8 = lambda z: z.__hash__() # [unnecessary-dunder-call] -lambda9 = lambda n: (4).__rmul__(n) # [unnecessary-dunder-call] diff --git a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38_pypy.rc b/tests/functional/u/unnecessary/unnecessary_dunder_call_py38_pypy.rc deleted file mode 100644 index 8d23335b67..0000000000 --- a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38_pypy.rc +++ /dev/null @@ -1,3 +0,0 @@ -[testoptions] -max_pyver=3.9 -except_implementations=CPython diff --git a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38_pypy.txt b/tests/functional/u/unnecessary/unnecessary_dunder_call_py38_pypy.txt deleted file mode 100644 index 2152103f8c..0000000000 --- a/tests/functional/u/unnecessary/unnecessary_dunder_call_py38_pypy.txt +++ /dev/null @@ -1,13 +0,0 @@ -unnecessary-dunder-call:9:10:None:None::Unnecessarily calls dunder method __str__. Use str built-in function.:HIGH -unnecessary-dunder-call:10:11:None:None::Unnecessarily calls dunder method __add__. Use + operator.:HIGH -unnecessary-dunder-call:11:10:None:None::Unnecessarily calls dunder method __repr__. Use repr built-in function.:HIGH -unnecessary-dunder-call:13:18:None:None::Unnecessarily calls dunder method __contains__. Use in keyword.:HIGH -unnecessary-dunder-call:18:0:None:None::Unnecessarily calls dunder method __init__. Instantiate class directly.:HIGH -unnecessary-dunder-call:26:11:None:None:is_bigger_than_two:Unnecessarily calls dunder method __gt__. Use > operator.:HIGH -unnecessary-dunder-call:119:20:None:None::Unnecessarily calls dunder method __add__. Use + operator.:HIGH -unnecessary-dunder-call:120:0:None:None::Unnecessarily calls dunder method __setitem__. Set item via subscript.:HIGH -unnecessary-dunder-call:140:20:None:None::Unnecessarily calls dunder method __gt__. Use > operator.:HIGH -unnecessary-dunder-call:141:22:None:None::Unnecessarily calls dunder method __or__. Use | operator.:HIGH -unnecessary-dunder-call:142:20:None:None::Unnecessarily calls dunder method __iter__. Use iter built-in function.:HIGH -unnecessary-dunder-call:143:20:None:None::Unnecessarily calls dunder method __hash__. Use hash built-in function.:HIGH -unnecessary-dunder-call:144:21:None:None::Unnecessarily calls dunder method __rmul__. Use * operator.:HIGH diff --git a/tests/functional/u/unnecessary/unnecessary_dunder_call_py39.py b/tests/functional/u/unnecessary/unnecessary_dunder_call_py39.py deleted file mode 100644 index f86e14651d..0000000000 --- a/tests/functional/u/unnecessary/unnecessary_dunder_call_py39.py +++ /dev/null @@ -1,144 +0,0 @@ -"""Checks for unnecessary-dunder-call.""" -# pylint: disable=too-few-public-methods, undefined-variable -# pylint: disable=missing-class-docstring, missing-function-docstring -# pylint: disable=protected-access, unnecessary-lambda-assignment, unnecessary-lambda -from collections import OrderedDict -from typing import Any - -# Test includelisted dunder methods raise lint when manually called. -num_str = some_num.__str__() # [unnecessary-dunder-call] -num_repr = some_num.__add__(2) # [unnecessary-dunder-call] -my_repr = my_module.my_object.__repr__() # [unnecessary-dunder-call] - -MY_CONTAINS_BAD = {1, 2, 3}.__contains__(1) # [unnecessary-dunder-call] -MY_CONTAINS_GOOD = 1 in {1, 2, 3} - -# Just instantiate like a normal person please -my_list_bad = [] -my_list_bad.__init__({1, 2, 3}) # [unnecessary-dunder-call] -my_list_good = list({1, 2, 3}) - -# Test unknown/user-defined dunder methods don't raise lint. -my_woohoo = my_object.__woohoo__() - -# Test lint raised within function. -def is_bigger_than_two(val): - return val.__gt__(2) # [unnecessary-dunder-call] - -# Test dunder methods don't raise lint -# if within a dunder method definition. -class Foo1: - def __init__(self): - object.__init__(self) - -class Foo2: - def __init__(self): - super().__init__(self) - -class Bar1: - def __new__(cls): - object.__new__(cls) - -class Bar2: - def __new__(cls): - super().__new__(cls) - -class CustomRegistry(dict): - def __init__(self) -> None: - super().__init__() - self._entry_ids = {} - - def __setitem__(self, key, entry) -> None: - super().__setitem__(key, entry) - self._entry_ids.__setitem__(entry.id, entry) - self._entry_ids.__delitem__(entry.id) - - def __delitem__(self, key: str) -> None: - entry = self[key] - self._entry_ids.__delitem__(entry.id) - super().__delitem__(key) - -class CustomState: - def __init__(self, state): - self._state = state - - def __eq__(self, other: Any) -> bool: - return self._state.__eq__(other) - -class CustomDict(OrderedDict): - def __init__(self, *args, **kwds): - OrderedDict.__init__(self, *args, **kwds) - - def __setitem__(self, key, value): - OrderedDict.__setitem__(self, key, value) - - -class MyClass(list): - def __contains__(self, item): - print("do some special checks") - return super().__contains__(item) - -class PluginBase: - subclasses = [] - - def __init_subclass__(cls, **kwargs): - super().__init_subclass__(**kwargs) - cls.subclasses.append(cls) - -# Validate that dunder call is allowed -# at any depth within dunder definition -class SomeClass: - def __init__(self): - self.my_attr = object() - - def __setattr__(self, name, value): - def nested_function(): - self.my_attr.__setattr__(name, value) - - nested_function() - -# Allow use of dunder methods that don't -# have an alternate method of being called -class Base: - @classmethod - def get_first_subclass(cls): - for subklass in cls.__subclasses__(): - return subklass - return object - -# Test no lint raised for attributes. -my_instance_name = x.__class__.__name__ -my_pkg_version = pkg.__version__ - -# Allow use of dunder methods on non instantiated classes -MANUAL_SELF = int.__add__(1, 1) -MY_DICT = {"a": 1, "b": 2} -dict.__setitem__(MY_DICT, "key", "value") - -# Still flag instantiated classes -INSTANTIATED_SELF = int("1").__add__(1) # [unnecessary-dunder-call] -{"a": 1, "b": 2}.__setitem__("key", "value") # [unnecessary-dunder-call] - -# We also exclude dunder methods called on super -# since we can't apply alternate operators/functions here. -a = [1, 2, 3] -assert super(type(a), a).__str__() == "[1, 2, 3]" - -class MyString(str): - """Custom str implementation""" - def rjust(self, width, fillchar= ' '): - """Acceptable call to __index__""" - width = width.__index__() - -# Test no lint raised for these dunders within lambdas -lambda1 = lambda x: x.__setitem__(1,2) -lambda2 = lambda x: x.__del__(1) -lambda3 = lambda x,y: x.__ipow__(y) -lambda4 = lambda u,v: u.__setitem__(v()) - -# Test lint raised for these dunders within lambdas -lambda5 = lambda x: x.__gt__(3) # [unnecessary-dunder-call] -lambda6 = lambda x,y: x.__or__(y) # [unnecessary-dunder-call] -lambda7 = lambda x: x.__iter__() # [unnecessary-dunder-call] -lambda8 = lambda z: z.__hash__() # [unnecessary-dunder-call] -lambda9 = lambda n: (4).__rmul__(n) # [unnecessary-dunder-call] diff --git a/tests/functional/u/unnecessary/unnecessary_dunder_call_py39.rc b/tests/functional/u/unnecessary/unnecessary_dunder_call_py39.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/u/unnecessary/unnecessary_dunder_call_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/u/unnecessary/unnecessary_dunder_call_py39.txt b/tests/functional/u/unnecessary/unnecessary_dunder_call_py39.txt deleted file mode 100644 index 65ab199829..0000000000 --- a/tests/functional/u/unnecessary/unnecessary_dunder_call_py39.txt +++ /dev/null @@ -1,13 +0,0 @@ -unnecessary-dunder-call:9:10:9:28::Unnecessarily calls dunder method __str__. Use str built-in function.:HIGH -unnecessary-dunder-call:10:11:10:30::Unnecessarily calls dunder method __add__. Use + operator.:HIGH -unnecessary-dunder-call:11:10:11:40::Unnecessarily calls dunder method __repr__. Use repr built-in function.:HIGH -unnecessary-dunder-call:13:18:13:43::Unnecessarily calls dunder method __contains__. Use in keyword.:HIGH -unnecessary-dunder-call:18:0:18:31::Unnecessarily calls dunder method __init__. Instantiate class directly.:HIGH -unnecessary-dunder-call:26:11:26:24:is_bigger_than_two:Unnecessarily calls dunder method __gt__. Use > operator.:HIGH -unnecessary-dunder-call:119:20:119:39::Unnecessarily calls dunder method __add__. Use + operator.:HIGH -unnecessary-dunder-call:120:0:120:44::Unnecessarily calls dunder method __setitem__. Set item via subscript.:HIGH -unnecessary-dunder-call:140:20:140:31::Unnecessarily calls dunder method __gt__. Use > operator.:HIGH -unnecessary-dunder-call:141:22:141:33::Unnecessarily calls dunder method __or__. Use | operator.:HIGH -unnecessary-dunder-call:142:20:142:32::Unnecessarily calls dunder method __iter__. Use iter built-in function.:HIGH -unnecessary-dunder-call:143:20:143:32::Unnecessarily calls dunder method __hash__. Use hash built-in function.:HIGH -unnecessary-dunder-call:144:20:144:35::Unnecessarily calls dunder method __rmul__. Use * operator.:HIGH diff --git a/tests/functional/u/unused/unused_import.py b/tests/functional/u/unused/unused_import.py index c8e7c5640b..a2e3ceca3f 100644 --- a/tests/functional/u/unused/unused_import.py +++ b/tests/functional/u/unused/unused_import.py @@ -39,6 +39,8 @@ class SomeClass: import xml +example: t.Annotated[str, "Path"] = "/foo/bar" + def get_ordered_dict() -> "collections.OrderedDict": return [] diff --git a/tests/functional/u/unused/unused_import.txt b/tests/functional/u/unused/unused_import.txt index f356843fa9..b8f1b2f8fe 100644 --- a/tests/functional/u/unused/unused_import.txt +++ b/tests/functional/u/unused/unused_import.txt @@ -7,8 +7,8 @@ unused-import:11:0:11:51::Unused OrderedDict imported from collections:UNDEFINED unused-import:11:0:11:51::Unused deque imported from collections:UNDEFINED unused-import:12:0:12:22::Unused import re:UNDEFINED unused-import:17:0:17:40::Unused SomeOtherName imported from fake:UNDEFINED -unused-import:54:0:54:9::Unused import os:UNDEFINED -unused-import:89:4:89:19::Unused import unittest:UNDEFINED -unused-import:91:4:91:15::Unused import uuid:UNDEFINED -unused-import:93:4:93:19::Unused import warnings:UNDEFINED -unused-import:95:4:95:21::Unused import compileall:UNDEFINED +unused-import:56:0:56:9::Unused import os:UNDEFINED +unused-import:91:4:91:19::Unused import unittest:UNDEFINED +unused-import:93:4:93:15::Unused import uuid:UNDEFINED +unused-import:95:4:95:19::Unused import warnings:UNDEFINED +unused-import:97:4:97:21::Unused import compileall:UNDEFINED diff --git a/tests/functional/u/unused/unused_import_py39.py b/tests/functional/u/unused/unused_import_py39.py deleted file mode 100644 index 2a897b1741..0000000000 --- a/tests/functional/u/unused/unused_import_py39.py +++ /dev/null @@ -1,10 +0,0 @@ -""" -Test that a constant parameter of `typing.Annotated` does not emit `unused-import`. -`typing.Annotated` was introduced in Python version 3.9 -""" - -from pathlib import Path # [unused-import] -import typing as t - - -example: t.Annotated[str, "Path"] = "/foo/bar" diff --git a/tests/functional/u/unused/unused_import_py39.rc b/tests/functional/u/unused/unused_import_py39.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/u/unused/unused_import_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/u/unused/unused_import_py39.txt b/tests/functional/u/unused/unused_import_py39.txt deleted file mode 100644 index 50e5ad5a96..0000000000 --- a/tests/functional/u/unused/unused_import_py39.txt +++ /dev/null @@ -1 +0,0 @@ -unused-import:6:0:6:24::Unused Path imported from pathlib:UNDEFINED diff --git a/tests/functional/u/unused/unused_name_in_string_literal_type_annotation_py39.rc b/tests/functional/u/unused/unused_name_in_string_literal_type_annotation_py39.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/u/unused/unused_name_in_string_literal_type_annotation_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/functional/u/used/used_before_assignment.py b/tests/functional/u/used/used_before_assignment.py index 5e589e81bb..b398afa370 100644 --- a/tests/functional/u/used/used_before_assignment.py +++ b/tests/functional/u/used/used_before_assignment.py @@ -2,7 +2,7 @@ # pylint: disable=consider-using-f-string, missing-function-docstring import datetime import sys -# from typing import NoReturn # uncomment when we reunite with used_before_assignment_py38.py +from typing import NoReturn MSG = "hello %s" % MSG # [used-before-assignment] @@ -206,3 +206,19 @@ def inner_if_continues_outer_if_has_no_other_statements(): else: order = None print(order) + + +class PlatformChecks: # pylint: disable=missing-docstring + """https://github.com/pylint-dev/pylint/issues/9674""" + def skip(self, msg) -> NoReturn: + raise Exception(msg) # pylint: disable=broad-exception-raised + + def print_platform_specific_command(self): + if sys.platform == "linux": + cmd = "ls" + elif sys.platform == "win32": + cmd = "dir" + else: + self.skip("only runs on Linux/Windows") + + print(cmd) diff --git a/tests/functional/u/used/used_before_assignment_py38.py b/tests/functional/u/used/used_before_assignment_py38.py deleted file mode 100644 index 81d69268e2..0000000000 --- a/tests/functional/u/used/used_before_assignment_py38.py +++ /dev/null @@ -1,26 +0,0 @@ -""" -Temporary file until we drop python 3.8 -See https://github.com/pylint-dev/pylint/issues/9751 -Please reunite with used_before_assignment.py at this point -""" - -# pylint: disable=missing-docstring - -import sys -from typing import NoReturn - - -class PlatformChecks: - """https://github.com/pylint-dev/pylint/issues/9674""" - def skip(self, msg) -> NoReturn: - raise Exception(msg) # pylint: disable=broad-exception-raised - - def print_platform_specific_command(self): - if sys.platform == "linux": - cmd = "ls" - elif sys.platform == "win32": - cmd = "dir" - else: - self.skip("only runs on Linux/Windows") - - print(cmd) diff --git a/tests/functional/u/used/used_before_assignment_py38.rc b/tests/functional/u/used/used_before_assignment_py38.rc deleted file mode 100644 index 16b75eea75..0000000000 --- a/tests/functional/u/used/used_before_assignment_py38.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.9 diff --git a/tests/testutils/test_lint_module_output_update.py b/tests/testutils/test_lint_module_output_update.py index 038dc77ed3..6d732a57ab 100644 --- a/tests/testutils/test_lint_module_output_update.py +++ b/tests/testutils/test_lint_module_output_update.py @@ -12,7 +12,6 @@ import pytest -from pylint.constants import IS_PYPY, PY39_PLUS from pylint.testutils import FunctionalTestFile, LintModuleTest from pylint.testutils.functional import LintModuleOutputUpdate @@ -72,10 +71,6 @@ def test_lint_module_output_update_remove_useless_txt( assert not expected_output_file.exists() -@pytest.mark.skipif( - IS_PYPY and not PY39_PLUS, - reason="Requires accurate 'end_col' value to update output", -) @pytest.mark.parametrize( "directory_path", DIRECTORIES, ids=[str(p) for p in DIRECTORIES] ) diff --git a/tests/testutils/test_output_line.py b/tests/testutils/test_output_line.py index faffc8110f..07be2f2411 100644 --- a/tests/testutils/test_output_line.py +++ b/tests/testutils/test_output_line.py @@ -70,33 +70,13 @@ def test_output_line_from_message(message: _MessageCallable) -> None: assert output_line.msg == "msg" assert output_line.confidence == "HIGH" - output_line_with_end = OutputLine.from_msg(message(), True) - assert output_line_with_end.symbol == "missing-docstring" - assert output_line_with_end.lineno == 1 - assert output_line_with_end.column == 2 - assert output_line_with_end.end_lineno == 1 - assert output_line_with_end.end_column == 3 - assert output_line_with_end.object == "obj" - assert output_line_with_end.msg == "msg" - assert output_line_with_end.confidence == "HIGH" - - output_line_without_end = OutputLine.from_msg(message(), False) - assert output_line_without_end.symbol == "missing-docstring" - assert output_line_without_end.lineno == 1 - assert output_line_without_end.column == 2 - assert output_line_without_end.end_lineno is None - assert output_line_without_end.end_column is None - assert output_line_without_end.object == "obj" - assert output_line_without_end.msg == "msg" - assert output_line_without_end.confidence == "HIGH" - @pytest.mark.parametrize("confidence", [HIGH, INFERENCE]) def test_output_line_to_csv(confidence: Confidence, message: _MessageCallable) -> None: """Test that the OutputLine NamedTuple is instantiated correctly with from_msg and then converted to csv. """ - output_line = OutputLine.from_msg(message(confidence), True) + output_line = OutputLine.from_msg(message(confidence)) csv = output_line.to_csv() assert csv == ( "missing-docstring", @@ -109,19 +89,6 @@ def test_output_line_to_csv(confidence: Confidence, message: _MessageCallable) - confidence.name, ) - output_line_without_end = OutputLine.from_msg(message(confidence), False) - csv = output_line_without_end.to_csv() - assert csv == ( - "missing-docstring", - "1", - "2", - "None", - "None", - "obj", - "msg", - confidence.name, - ) - def test_output_line_from_csv() -> None: """Test that the OutputLine NamedTuple is instantiated correctly with from_csv. @@ -140,25 +107,3 @@ def test_output_line_from_csv() -> None: msg="msg", confidence="HIGH", ) - output_line_with_end = OutputLine.from_csv(proper_csv, True) - assert output_line_with_end == OutputLine( - symbol="missing-docstring", - lineno=1, - column=2, - end_lineno=1, - end_column=None, - object="obj", - msg="msg", - confidence="HIGH", - ) - output_line_without_end = OutputLine.from_csv(proper_csv, False) - assert output_line_without_end == OutputLine( - symbol="missing-docstring", - lineno=1, - column=2, - end_lineno=None, - end_column=None, - object="obj", - msg="msg", - confidence="HIGH", - ) diff --git a/tox.ini b/tox.ini index b3e429cc8c..82ee65da37 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 3.0 -envlist = formatting, py38, py39, py310, py311, py312, pypy, benchmark +envlist = formatting, py39, py310, py311, py312, pypy, benchmark skip_missing_interpreters = true requires = pip >=21.3.1 isolated_build = true