diff --git a/.github/workflows/primer-test.yaml b/.github/workflows/primer-test.yaml index dc3c0942ac..8f7de5a0cf 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.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13"] outputs: python-key: ${{ steps.generate-python-key.outputs.key }} steps: @@ -72,7 +72,7 @@ jobs: needs: prepare-tests-linux strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - name: Check out code from GitHub uses: actions/checkout@v4.2.2 diff --git a/.github/workflows/primer_run_main.yaml b/.github/workflows/primer_run_main.yaml index 2d37943e8d..ccaf207d96 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.9", "3.13"] + python-version: ["3.10", "3.13"] 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 f2bd5b563f..0e0eafd26f 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.9", "3.13"] + python-version: ["3.10", "3.13"] batches: [4] batchIdx: [0, 1, 2, 3] steps: @@ -217,7 +217,8 @@ jobs: echo ${{ github.event.pull_request.number }} | tee pr_number.txt - name: Upload PR number if: - startsWith(steps.python.outputs.python-version, '3.9') && matrix.batchIdx == 0 + startsWith(steps.python.outputs.python-version, '3.10') && matrix.batchIdx == + 0 uses: actions/upload-artifact@v4.6.2 with: name: pr_number diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 43ea67586a..c99707fa26 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,12 +31,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13"] include: - os: macos-latest - python-version: "3.9" - - os: ubuntu-latest - python-version: "pypy-3.9" + python-version: "3.10" - os: ubuntu-latest python-version: "pypy-3.10" - os: ubuntu-latest @@ -190,7 +188,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - name: Set temp directory run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV diff --git a/README.rst b/README.rst index 76134f428c..a4f22ef58d 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.9.0 and above. +3.10.0 and above. .. _`static code analyser`: https://en.wikipedia.org/wiki/Static_code_analysis diff --git a/doc/whatsnew/fragments/10405.other b/doc/whatsnew/fragments/10405.other new file mode 100644 index 0000000000..0bdaa73042 --- /dev/null +++ b/doc/whatsnew/fragments/10405.other @@ -0,0 +1,4 @@ +Remove support for launching pylint with Python 3.9. +Code that supports Python 3.9 can still be linted with the ``--py-version=3.9`` setting. + +Refs #10405 diff --git a/pylint/checkers/base/basic_checker.py b/pylint/checkers/base/basic_checker.py index 56400cbead..68cf2c4327 100644 --- a/pylint/checkers/base/basic_checker.py +++ b/pylint/checkers/base/basic_checker.py @@ -884,7 +884,7 @@ def visit_with(self, node: nodes.With) -> None: # to one AST "With" node with multiple items pairs = node.items if pairs: - for prev_pair, pair in zip(pairs, pairs[1:]): + for prev_pair, pair in itertools.pairwise(pairs): if isinstance(prev_pair[1], nodes.AssignName) and ( pair[1] is None and not isinstance(pair[0], nodes.Call) ): diff --git a/pylint/checkers/classes/class_checker.py b/pylint/checkers/classes/class_checker.py index b493a1ba73..133ab16584 100644 --- a/pylint/checkers/classes/class_checker.py +++ b/pylint/checkers/classes/class_checker.py @@ -11,7 +11,7 @@ from functools import cached_property from itertools import chain, zip_longest from re import Pattern -from typing import TYPE_CHECKING, Any, NamedTuple, Union +from typing import TYPE_CHECKING, Any, NamedTuple, TypeAlias import astroid from astroid import bases, nodes, util @@ -46,7 +46,7 @@ from pylint.lint.pylinter import PyLinter -_AccessNodes = Union[nodes.Attribute, nodes.AssignAttr] +_AccessNodes: TypeAlias = nodes.Attribute | nodes.AssignAttr INVALID_BASE_CLASSES = {"bool", "range", "slice", "memoryview"} ALLOWED_PROPERTIES = {"bultins.property", "functools.cached_property"} diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index fa63ea9dfb..83435efabd 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, Union +from typing import TYPE_CHECKING, Any 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, list[dict[str, Any]] | list[str]] DEPRECATED_MODULES = { (0, 0, 0): {"tkinter.tix", "fpectl"}, diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py index 08e5c3491f..e277da9dc1 100644 --- a/pylint/checkers/refactoring/refactoring_checker.py +++ b/pylint/checkers/refactoring/refactoring_checker.py @@ -11,7 +11,7 @@ from collections.abc import Iterator from functools import cached_property, reduce from re import Pattern -from typing import TYPE_CHECKING, Any, NamedTuple, Union, cast +from typing import TYPE_CHECKING, Any, NamedTuple, TypeAlias, cast import astroid from astroid import bases, nodes @@ -27,7 +27,7 @@ from pylint.lint import PyLinter -NodesWithNestedBlocks = Union[nodes.Try, nodes.While, nodes.For, nodes.If] +NodesWithNestedBlocks: TypeAlias = nodes.Try | nodes.While | nodes.For | nodes.If KNOWN_INFINITE_ITERATORS = {"itertools.count", "itertools.cycle"} BUILTIN_EXIT_FUNCS = frozenset(("quit", "exit")) diff --git a/pylint/checkers/symilar.py b/pylint/checkers/symilar.py index 21d22529d6..5b3ff046c3 100644 --- a/pylint/checkers/symilar.py +++ b/pylint/checkers/symilar.py @@ -41,7 +41,7 @@ from collections.abc import Callable, Generator, Iterable, Sequence from io import BufferedIOBase, BufferedReader, BytesIO from itertools import chain -from typing import TYPE_CHECKING, NamedTuple, NewType, NoReturn, TextIO, Union +from typing import TYPE_CHECKING, NamedTuple, NewType, NoReturn, TextIO, TypeAlias import astroid from astroid import nodes @@ -79,7 +79,7 @@ class LineSpecifs(NamedTuple): 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] +STREAM_TYPES: TypeAlias = TextIO | BufferedReader | BytesIO class CplSuccessiveLinesLimits: diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index 7953e640b4..e9c5e0140a 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -15,7 +15,7 @@ from collections.abc import Callable, Iterable from functools import cached_property, lru_cache, singledispatch from re import Pattern -from typing import TYPE_CHECKING, Any, Literal, Union +from typing import TYPE_CHECKING, Any, Literal, TypeAlias import astroid import astroid.exceptions @@ -49,20 +49,19 @@ supports_membership_test, supports_setitem, ) -from pylint.constants import PY310_PLUS from pylint.interfaces import HIGH, INFERENCE from pylint.typing import MessageDefinitionTuple if TYPE_CHECKING: from pylint.lint import PyLinter -CallableObjects = Union[ - bases.BoundMethod, - bases.UnboundMethod, - nodes.FunctionDef, - nodes.Lambda, - nodes.ClassDef, -] +CallableObjects: TypeAlias = ( + bases.BoundMethod + | bases.UnboundMethod + | nodes.FunctionDef + | nodes.Lambda + | nodes.ClassDef +) STR_FORMAT = {"builtins.str.format"} ASYNCIO_COROUTINE = "asyncio.coroutines.coroutine" @@ -796,7 +795,7 @@ def _is_c_extension(module_node: InferenceResult) -> bool: def _is_invalid_isinstance_type(arg: nodes.NodeNG) -> bool: # Return True if we are sure that arg is not a type - if PY310_PLUS and isinstance(arg, nodes.BinOp) and arg.op == "|": + if isinstance(arg, nodes.BinOp) and arg.op == "|": return any( _is_invalid_isinstance_type(elt) and not is_none(elt) for elt in (arg.left, arg.right) @@ -811,7 +810,7 @@ def _is_invalid_isinstance_type(arg: nodes.NodeNG) -> bool: return False if isinstance(inferred, astroid.Instance) and inferred.qname() == BUILTIN_TUPLE: return False - if PY310_PLUS and isinstance(inferred, bases.UnionType): + if isinstance(inferred, bases.UnionType): return any( _is_invalid_isinstance_type(elt) and not is_none(elt) for elt in (inferred.left, inferred.right) diff --git a/pylint/config/_pylint_config/utils.py b/pylint/config/_pylint_config/utils.py index 7ed8b83843..54b199394a 100644 --- a/pylint/config/_pylint_config/utils.py +++ b/pylint/config/_pylint_config/utils.py @@ -9,12 +9,7 @@ import sys from collections.abc import Callable from pathlib import Path -from typing import Literal, TypeVar - -if sys.version_info >= (3, 10): - from typing import ParamSpec -else: - from typing_extensions import ParamSpec +from typing import Literal, ParamSpec, TypeVar _P = ParamSpec("_P") _ReturnValueT = TypeVar("_ReturnValueT", bool, str) diff --git a/pylint/config/argument.py b/pylint/config/argument.py index a515a942b4..a604d978aa 100644 --- a/pylint/config/argument.py +++ b/pylint/config/argument.py @@ -16,23 +16,23 @@ from collections.abc import Callable, Sequence from glob import glob from re import Pattern -from typing import Any, Literal, Union +from typing import Any, Literal from pylint import interfaces from pylint import utils as pylint_utils from pylint.config.callback_actions import _CallbackAction from pylint.config.deprecation_actions import _NewNamesAction, _OldNamesAction -_ArgumentTypes = Union[ - str, - int, - float, - bool, - Pattern[str], - Sequence[str], - Sequence[Pattern[str]], - tuple[int, ...], -] +_ArgumentTypes = ( + str + | int + | float + | bool + | Pattern[str] + | Sequence[str] + | Sequence[Pattern[str]] + | tuple[int, ...] +) """List of possible argument types.""" diff --git a/pylint/constants.py b/pylint/constants.py index 6911393d37..a5285d1bed 100644 --- a/pylint/constants.py +++ b/pylint/constants.py @@ -14,7 +14,6 @@ from pylint.__pkginfo__ import __version__ from pylint.typing import MessageTypesFullName -PY310_PLUS = sys.version_info[:2] >= (3, 10) PY311_PLUS = sys.version_info[:2] >= (3, 11) PY312_PLUS = sys.version_info[:2] >= (3, 12) PY314_PLUS = sys.version_info[:2] >= (3, 14) diff --git a/pylint/extensions/code_style.py b/pylint/extensions/code_style.py index a8c44ec5ed..d187cd7c5c 100644 --- a/pylint/extensions/code_style.py +++ b/pylint/extensions/code_style.py @@ -4,8 +4,7 @@ from __future__ import annotations -import sys -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING, TypeGuard, cast from astroid import nodes @@ -16,11 +15,6 @@ if TYPE_CHECKING: from pylint.lint import PyLinter -if sys.version_info >= (3, 10): - from typing import TypeGuard -else: - from typing_extensions import TypeGuard - class CodeStyleChecker(BaseChecker): """Checkers that can improve code consistency. diff --git a/pylint/extensions/mccabe.py b/pylint/extensions/mccabe.py index 9489f24d6c..45bd35cee6 100644 --- a/pylint/extensions/mccabe.py +++ b/pylint/extensions/mccabe.py @@ -7,7 +7,7 @@ from __future__ import annotations from collections.abc import Sequence -from typing import TYPE_CHECKING, Any, TypeVar, Union +from typing import TYPE_CHECKING, Any, TypeAlias, TypeVar from astroid import nodes from mccabe import PathGraph as Mccabe_PathGraph @@ -20,28 +20,28 @@ if TYPE_CHECKING: from pylint.lint import PyLinter -_StatementNodes = Union[ - nodes.Assert, - nodes.Assign, - nodes.AugAssign, - nodes.Delete, - nodes.Raise, - nodes.Yield, - nodes.Import, - nodes.Call, - nodes.Subscript, - nodes.Pass, - nodes.Continue, - nodes.Break, - nodes.Global, - nodes.Return, - nodes.Expr, - nodes.Await, -] - -_SubGraphNodes = Union[nodes.If, nodes.Try, nodes.For, nodes.While] +_StatementNodes: TypeAlias = ( + nodes.Assert + | nodes.Assign + | nodes.AugAssign + | nodes.Delete + | nodes.Raise + | nodes.Yield + | nodes.Import + | nodes.Call + | nodes.Subscript + | nodes.Pass + | nodes.Continue + | nodes.Break + | nodes.Global + | nodes.Return + | nodes.Expr + | nodes.Await +) + +_SubGraphNodes: TypeAlias = nodes.If | nodes.Try | nodes.For | nodes.While _AppendableNodeT = TypeVar( - "_AppendableNodeT", bound=Union[_StatementNodes, nodes.While, nodes.FunctionDef] + "_AppendableNodeT", bound=_StatementNodes | nodes.While | nodes.FunctionDef ) diff --git a/pylint/pyreverse/inspector.py b/pylint/pyreverse/inspector.py index 8e69e94470..aff15909ac 100644 --- a/pylint/pyreverse/inspector.py +++ b/pylint/pyreverse/inspector.py @@ -14,7 +14,6 @@ import traceback from abc import ABC, abstractmethod from collections.abc import Callable, Sequence -from typing import Optional import astroid from astroid import nodes @@ -24,7 +23,7 @@ from pylint.pyreverse import utils _WrapperFuncT = Callable[ - [Callable[[str], nodes.Module], str, bool], Optional[nodes.Module] + [Callable[[str], nodes.Module], str, bool], nodes.Module | None ] diff --git a/pylint/pyreverse/utils.py b/pylint/pyreverse/utils.py index 5ad92d3231..4ec4052353 100644 --- a/pylint/pyreverse/utils.py +++ b/pylint/pyreverse/utils.py @@ -12,7 +12,7 @@ import subprocess import sys from collections.abc import Callable -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any import astroid from astroid import nodes @@ -23,9 +23,9 @@ _CallbackT = Callable[ [nodes.NodeNG], - Union[tuple[ClassDiagram], tuple[PackageDiagram, ClassDiagram], None], + tuple[ClassDiagram] | tuple[PackageDiagram, ClassDiagram] | None, ] - _CallbackTupleT = tuple[Optional[_CallbackT], Optional[_CallbackT]] + _CallbackTupleT = tuple[_CallbackT | None, _CallbackT | None] RCFILE = ".pyreverserc" diff --git a/pylint/reporters/json_reporter.py b/pylint/reporters/json_reporter.py index 7135dfc66c..d5f847cd9b 100644 --- a/pylint/reporters/json_reporter.py +++ b/pylint/reporters/json_reporter.py @@ -7,7 +7,7 @@ from __future__ import annotations import json -from typing import TYPE_CHECKING, Optional, TypedDict +from typing import TYPE_CHECKING, TypedDict from pylint.interfaces import CONFIDENCE_MAP, UNDEFINED from pylint.message import Message @@ -27,8 +27,8 @@ "obj": str, "line": int, "column": int, - "endLine": Optional[int], - "endColumn": Optional[int], + "endLine": int | None, + "endColumn": int | None, "path": str, "symbol": str, "message": str, diff --git a/pylint/testutils/configuration_test.py b/pylint/testutils/configuration_test.py index ce2239e5c2..93a812659a 100644 --- a/pylint/testutils/configuration_test.py +++ b/pylint/testutils/configuration_test.py @@ -9,7 +9,7 @@ import copy import json import logging -import unittest +import unittest.mock from pathlib import Path from typing import Any diff --git a/pylint/typing.py b/pylint/typing.py index a43674d249..5c59120324 100644 --- a/pylint/typing.py +++ b/pylint/typing.py @@ -7,19 +7,16 @@ from __future__ import annotations import argparse -from collections.abc import Iterable, Sequence +from collections.abc import Callable, Iterable, Sequence from pathlib import Path from re import Pattern from typing import ( TYPE_CHECKING, Any, - Callable, Literal, NamedTuple, - Optional, Protocol, TypedDict, - Union, ) if TYPE_CHECKING: @@ -95,22 +92,20 @@ class ManagedMessage(NamedTuple): OptionDict = dict[ str, - Union[ - None, - str, - bool, - int, - Pattern[str], - Iterable[Union[str, int, Pattern[str]]], - type["_CallbackAction"], - Callable[[Any], Any], - Callable[[Any, Any, Any, Any], Any], - ], + None + | str + | bool + | int + | Pattern[str] + | Iterable[str | int | Pattern[str]] + | type["_CallbackAction"] + | Callable[[Any], Any] + | Callable[[Any, Any, Any, Any], Any], ] Options = tuple[tuple[str, OptionDict], ...] -ReportsCallable = Callable[["Section", "LinterStats", Optional["LinterStats"]], None] +ReportsCallable = Callable[["Section", "LinterStats", "LinterStats | None"], None] """Callable to create a report.""" @@ -125,10 +120,9 @@ class ExtraMessageOptions(TypedDict, total=False): default_enabled: bool -MessageDefinitionTuple = Union[ - tuple[str, str, str], - tuple[str, str, str, ExtraMessageOptions], -] +MessageDefinitionTuple = ( + tuple[str, str, str] | tuple[str, str, str, ExtraMessageOptions] +) DirectoryNamespaceDict = dict[Path, tuple[argparse.Namespace, "DirectoryNamespaceDict"]] diff --git a/pylint/utils/utils.py b/pylint/utils/utils.py index 341a4aec6d..b32908307e 100644 --- a/pylint/utils/utils.py +++ b/pylint/utils/utils.py @@ -26,7 +26,7 @@ from collections.abc import Iterable, Sequence from io import BufferedReader, BytesIO from re import Pattern -from typing import TYPE_CHECKING, Any, Literal, TextIO, TypeVar, Union +from typing import TYPE_CHECKING, Any, Literal, TextIO, TypeVar from astroid import Module, modutils, nodes @@ -54,14 +54,14 @@ ] GLOBAL_OPTION_PATTERN_LIST = Literal["exclude-too-few-public-methods", "ignore-paths"] GLOBAL_OPTION_TUPLE_INT = Literal["py-version"] -GLOBAL_OPTION_NAMES = Union[ - GLOBAL_OPTION_BOOL, - GLOBAL_OPTION_INT, - GLOBAL_OPTION_LIST, - GLOBAL_OPTION_PATTERN, - GLOBAL_OPTION_PATTERN_LIST, - GLOBAL_OPTION_TUPLE_INT, -] +GLOBAL_OPTION_NAMES = ( + GLOBAL_OPTION_BOOL + | GLOBAL_OPTION_INT + | GLOBAL_OPTION_LIST + | GLOBAL_OPTION_PATTERN + | GLOBAL_OPTION_PATTERN_LIST + | GLOBAL_OPTION_TUPLE_INT +) T_GlobalOptionReturnTypes = TypeVar( "T_GlobalOptionReturnTypes", bool, diff --git a/pylintrc b/pylintrc index 6ccfa56650..fe653a092c 100644 --- a/pylintrc +++ b/pylintrc @@ -50,7 +50,7 @@ unsafe-load-any-extension=no extension-pkg-allow-list= # Minimum supported python version -py-version = 3.9.0 +py-version = 3.10.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 3b2a60f906..641981ecde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ license-files = [ "LICENSE", "CONTRIBUTORS.txt" ] authors = [ { name = "Python Code Quality Authority", email = "code-quality@python.org" }, ] -requires-python = ">=3.9.0" +requires-python = ">=3.10.0" classifiers = [ "Development Status :: 6 - Mature", "Environment :: Console", @@ -21,7 +21,6 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -137,6 +136,7 @@ lint.ignore = [ "PTH207", # Replace `glob` with `Path.glob` or `Path.rglob` "PTH208", # Use `pathlib.Path.iterdir()` instead" "RUF012", # mutable default values in class attributes + "UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)` ] lint.pydocstyle.convention = "pep257" diff --git a/tests/functional/a/alternative/alternative_union_syntax.rc b/tests/functional/a/alternative/alternative_union_syntax.rc index b8ab9047ad..d36622d880 100644 --- a/tests/functional/a/alternative/alternative_union_syntax.rc +++ b/tests/functional/a/alternative/alternative_union_syntax.rc @@ -1,5 +1,2 @@ [main] py-version=3.10 - -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/a/alternative/alternative_union_syntax_error.py b/tests/functional/a/alternative/alternative_union_syntax_error.py index 5730e2e503..b424e5bde9 100644 --- a/tests/functional/a/alternative/alternative_union_syntax_error.py +++ b/tests/functional/a/alternative/alternative_union_syntax_error.py @@ -23,7 +23,7 @@ lst = [typing.Dict[str, int] | None,] # [unsupported-binary-operation] var1: typing.Dict[str, int | None] # [unsupported-binary-operation] -var2: int | str | None # [unsupported-binary-operation, unsupported-binary-operation] +# var2: int | str | None # false-negative: unsupported-binary-operation, unsupported-binary-operation var3: int | typing.List[str | int] # [unsupported-binary-operation] var4: typing.Dict[typing.Tuple[int, int] | int, None] # [unsupported-binary-operation] diff --git a/tests/functional/a/alternative/alternative_union_syntax_error.rc b/tests/functional/a/alternative/alternative_union_syntax_error.rc index 5dc39b1a65..6f046622fa 100644 --- a/tests/functional/a/alternative/alternative_union_syntax_error.rc +++ b/tests/functional/a/alternative/alternative_union_syntax_error.rc @@ -1,5 +1,2 @@ [main] py-version=3.8 - -[testoptions] -max_pyver=3.10 diff --git a/tests/functional/a/alternative/alternative_union_syntax_error.txt b/tests/functional/a/alternative/alternative_union_syntax_error.txt index 6f4c19a4e4..8bc7dcd533 100644 --- a/tests/functional/a/alternative/alternative_union_syntax_error.txt +++ b/tests/functional/a/alternative/alternative_union_syntax_error.txt @@ -1,8 +1,6 @@ unsupported-binary-operation:22:8:22:30::unsupported operand type(s) for |:INFERENCE unsupported-binary-operation:23:7:23:35::unsupported operand type(s) for |:INFERENCE unsupported-binary-operation:25:23:25:33::unsupported operand type(s) for |:INFERENCE -unsupported-binary-operation:26:6:26:22::unsupported operand type(s) for |:INFERENCE -unsupported-binary-operation:26:6:26:15::unsupported operand type(s) for |:INFERENCE unsupported-binary-operation:27:6:27:34::unsupported operand type(s) for |:INFERENCE unsupported-binary-operation:28:18:28:46::unsupported operand type(s) for |:INFERENCE unsupported-binary-operation:31:23:31:32::unsupported operand type(s) for |:INFERENCE diff --git a/tests/functional/a/alternative/alternative_union_syntax_regession_8119.rc b/tests/functional/a/alternative/alternative_union_syntax_regession_8119.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/a/alternative/alternative_union_syntax_regession_8119.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/d/dataclass/dataclass_kw_only.rc b/tests/functional/d/dataclass/dataclass_kw_only.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/d/dataclass/dataclass_kw_only.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/d/dataclass/dataclass_parameter.rc b/tests/functional/d/dataclass/dataclass_parameter.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/d/dataclass/dataclass_parameter.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/d/deprecated/deprecated_class_py33.py b/tests/functional/d/deprecated/deprecated_class_py33.py index 470e467baa..13c89a7749 100644 --- a/tests/functional/d/deprecated/deprecated_class_py33.py +++ b/tests/functional/d/deprecated/deprecated_class_py33.py @@ -4,8 +4,3 @@ from collections import Iterable # [deprecated-class] import collections.Set # [deprecated-class] - -import collections - - -_ = collections.Awaitable() # [deprecated-class] diff --git a/tests/functional/d/deprecated/deprecated_class_py33.rc b/tests/functional/d/deprecated/deprecated_class_py33.rc index 4e2b748313..be3adcd6a9 100644 --- a/tests/functional/d/deprecated/deprecated_class_py33.rc +++ b/tests/functional/d/deprecated/deprecated_class_py33.rc @@ -1,2 +1,2 @@ -[testoptions] -max_pyver=3.10 +[main] +py-version=3.3 diff --git a/tests/functional/d/deprecated/deprecated_class_py33.txt b/tests/functional/d/deprecated/deprecated_class_py33.txt index ea1f8146ee..987c945dd1 100644 --- a/tests/functional/d/deprecated/deprecated_class_py33.txt +++ b/tests/functional/d/deprecated/deprecated_class_py33.txt @@ -1,3 +1,2 @@ deprecated-class:4:0:4:32::Using deprecated class Iterable of module collections:UNDEFINED deprecated-class:6:0:6:22::Using deprecated class Set of module collections:UNDEFINED -deprecated-class:11:4:11:27::Using deprecated class Awaitable of module collections:UNDEFINED diff --git a/tests/functional/d/deprecated/deprecated_methods_py39.py b/tests/functional/d/deprecated/deprecated_methods_py39.py deleted file mode 100644 index 9959b1c2a2..0000000000 --- a/tests/functional/d/deprecated/deprecated_methods_py39.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Test deprecated methods from Python 3.9.""" - -import binascii -binascii.b2a_hqx() # [deprecated-method] diff --git a/tests/functional/d/deprecated/deprecated_methods_py39.rc b/tests/functional/d/deprecated/deprecated_methods_py39.rc deleted file mode 100644 index 4e2b748313..0000000000 --- a/tests/functional/d/deprecated/deprecated_methods_py39.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -max_pyver=3.10 diff --git a/tests/functional/d/deprecated/deprecated_methods_py39.txt b/tests/functional/d/deprecated/deprecated_methods_py39.txt deleted file mode 100644 index 292ca5ef16..0000000000 --- a/tests/functional/d/deprecated/deprecated_methods_py39.txt +++ /dev/null @@ -1 +0,0 @@ -deprecated-method:4:0:4:18::Using deprecated method b2a_hqx():UNDEFINED diff --git a/tests/functional/d/deprecated/deprecated_module_py39.py b/tests/functional/d/deprecated/deprecated_module_py39.py index a897dd4e33..8f5827cefc 100644 --- a/tests/functional/d/deprecated/deprecated_module_py39.py +++ b/tests/functional/d/deprecated/deprecated_module_py39.py @@ -1,4 +1,4 @@ """Test deprecated modules from Python 3.9.""" -# pylint: disable=unused-import +# pylint: disable=unused-import, import-error import binhex # [deprecated-module] diff --git a/tests/functional/d/deprecated/deprecated_module_py39.rc b/tests/functional/d/deprecated/deprecated_module_py39.rc index 4e2b748313..77b418f759 100644 --- a/tests/functional/d/deprecated/deprecated_module_py39.rc +++ b/tests/functional/d/deprecated/deprecated_module_py39.rc @@ -1,2 +1,2 @@ -[testoptions] -max_pyver=3.10 +[main] +py-version=3.9 diff --git a/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.py b/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.py index c1c2f17883..dc3d83558d 100644 --- a/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.py +++ b/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.py @@ -1,6 +1,6 @@ """Test deprecated modules from Python 3.9, but use an earlier --py-version and ensure a warning is still emitted. """ -# pylint: disable=unused-import +# pylint: disable=unused-import, import-error import binhex # [deprecated-module] 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 5dc39b1a65..6f046622fa 100644 --- a/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.rc +++ b/tests/functional/d/deprecated/deprecated_module_py39_earlier_pyversion.rc @@ -1,5 +1,2 @@ [main] py-version=3.8 - -[testoptions] -max_pyver=3.10 diff --git a/tests/functional/ext/typing/redundant_typehint_argument_py310.rc b/tests/functional/ext/typing/redundant_typehint_argument_py310.rc index 3c06fa4330..63e11a4e6b 100644 --- a/tests/functional/ext/typing/redundant_typehint_argument_py310.rc +++ b/tests/functional/ext/typing/redundant_typehint_argument_py310.rc @@ -1,6 +1,3 @@ [main] py-version=3.10 load-plugins=pylint.extensions.typing - -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/ext/typing/typing_consider_using_union_py310.rc b/tests/functional/ext/typing/typing_consider_using_union_py310.rc index a35db15773..55c07d76e4 100644 --- a/tests/functional/ext/typing/typing_consider_using_union_py310.rc +++ b/tests/functional/ext/typing/typing_consider_using_union_py310.rc @@ -2,7 +2,4 @@ py-version=3.10 load-plugins=pylint.extensions.typing -[testoptions] -min_pyver=3.10 - [typing] diff --git a/tests/functional/i/isinstance_second_argument_py310.rc b/tests/functional/i/isinstance_second_argument_py310.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/i/isinstance_second_argument_py310.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/i/iterable_context_asyncio.rc b/tests/functional/i/iterable_context_asyncio.rc index 4e2b748313..092b342ea6 100644 --- a/tests/functional/i/iterable_context_asyncio.rc +++ b/tests/functional/i/iterable_context_asyncio.rc @@ -1,2 +1,5 @@ +[main] +py-version=3.9 + [testoptions] -max_pyver=3.10 +max_pyver=3.11 diff --git a/tests/functional/p/pattern_matching.rc b/tests/functional/p/pattern_matching.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/p/pattern_matching.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/r/regression/regression_4439.py b/tests/functional/r/regression/regression_4439.py index 3dc60cf9c0..e44a40a253 100644 --- a/tests/functional/r/regression/regression_4439.py +++ b/tests/functional/r/regression/regression_4439.py @@ -14,4 +14,4 @@ class User: name: str = attrib() age: int = attrib() - occupation = Optional[str] = attrib(default=None) # [unsupported-assignment-operation] + occupation = Optional[str] = attrib(default=None) diff --git a/tests/functional/r/regression/regression_4439.rc b/tests/functional/r/regression/regression_4439.rc index 4e2b748313..77b418f759 100644 --- a/tests/functional/r/regression/regression_4439.rc +++ b/tests/functional/r/regression/regression_4439.rc @@ -1,2 +1,2 @@ -[testoptions] -max_pyver=3.10 +[main] +py-version=3.9 diff --git a/tests/functional/r/regression/regression_4439.txt b/tests/functional/r/regression/regression_4439.txt deleted file mode 100644 index 6db65057f7..0000000000 --- a/tests/functional/r/regression/regression_4439.txt +++ /dev/null @@ -1 +0,0 @@ -unsupported-assignment-operation:17:17:17:25:User:'Optional' does not support item assignment:UNDEFINED diff --git a/tests/functional/s/super/super_init_not_called_extensions_py310.rc b/tests/functional/s/super/super_init_not_called_extensions_py310.rc index 3ab4e08e91..e73859088c 100644 --- a/tests/functional/s/super/super_init_not_called_extensions_py310.rc +++ b/tests/functional/s/super/super_init_not_called_extensions_py310.rc @@ -1,4 +1,3 @@ [testoptions] # Windows test environments on >= 3.10 don't have typing_extensions exclude_platforms=win32 -min_pyver=3.10 diff --git a/tests/functional/t/type/typealias_naming_style_default.rc b/tests/functional/t/type/typealias_naming_style_default.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/t/type/typealias_naming_style_default.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/t/type/typealias_naming_style_rgx.rc b/tests/functional/t/type/typealias_naming_style_rgx.rc index 2521a50b36..508ef15b7d 100644 --- a/tests/functional/t/type/typealias_naming_style_rgx.rc +++ b/tests/functional/t/type/typealias_naming_style_rgx.rc @@ -1,5 +1,2 @@ [BASIC] typealias-rgx=_{0,2}TypeAliasShouldBeLikeThis - -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/u/unpacking/unpacking_non_sequence_py310.rc b/tests/functional/u/unpacking/unpacking_non_sequence_py310.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/u/unpacking/unpacking_non_sequence_py310.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/u/unused/unused_name_in_string_literal_type_annotation_py310.rc b/tests/functional/u/unused/unused_name_in_string_literal_type_annotation_py310.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/u/unused/unused_name_in_string_literal_type_annotation_py310.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/u/used/used_before_assignment_py310.rc b/tests/functional/u/used/used_before_assignment_py310.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/u/used/used_before_assignment_py310.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/w/wrong_exception_operation.rc b/tests/functional/w/wrong_exception_operation.rc deleted file mode 100644 index 68a8c8ef15..0000000000 --- a/tests/functional/w/wrong_exception_operation.rc +++ /dev/null @@ -1,2 +0,0 @@ -[testoptions] -min_pyver=3.10 diff --git a/tests/functional/w/wrong_exception_operation_py37.py b/tests/functional/w/wrong_exception_operation_py37.py index 1c3c4e3803..dcc542606a 100644 --- a/tests/functional/w/wrong_exception_operation_py37.py +++ b/tests/functional/w/wrong_exception_operation_py37.py @@ -3,7 +3,7 @@ try: 1/0 -except (ValueError | TypeError): # [wrong-exception-operation] +except (ValueError | TypeError): # [wrong-exception-operation, catching-non-exception] pass try: diff --git a/tests/functional/w/wrong_exception_operation_py37.rc b/tests/functional/w/wrong_exception_operation_py37.rc index 4e2b748313..77b418f759 100644 --- a/tests/functional/w/wrong_exception_operation_py37.rc +++ b/tests/functional/w/wrong_exception_operation_py37.rc @@ -1,2 +1,2 @@ -[testoptions] -max_pyver=3.10 +[main] +py-version=3.9 diff --git a/tests/functional/w/wrong_exception_operation_py37.txt b/tests/functional/w/wrong_exception_operation_py37.txt index c92fcc2a2b..dc3c213462 100644 --- a/tests/functional/w/wrong_exception_operation_py37.txt +++ b/tests/functional/w/wrong_exception_operation_py37.txt @@ -1,3 +1,4 @@ +catching-non-exception:6:8:6:30::"Catching an exception which doesn't inherit from Exception: ValueError | TypeError":UNDEFINED wrong-exception-operation:6:8:6:30::Invalid exception operation. Did you mean '(ValueError, TypeError)' instead?:UNDEFINED wrong-exception-operation:11:8:11:30::Invalid exception operation. Did you mean '(ValueError, TypeError)' instead?:UNDEFINED wrong-exception-operation:17:8:17:30::Invalid exception operation. Did you mean '(ValueError, TypeError)' instead?:UNDEFINED diff --git a/tests/primer/packages_to_prime.json b/tests/primer/packages_to_prime.json index a0d1b38c0c..8e76cf37ed 100644 --- a/tests/primer/packages_to_prime.json +++ b/tests/primer/packages_to_prime.json @@ -29,7 +29,6 @@ "branch": "master", "directories": ["music21"], "pylintrc_relpath": ".pylintrc", - "minimum_python": "3.10", "url": "https://github.com/cuthbertLab/music21" }, "pandas": { diff --git a/tox.ini b/tox.ini index b5730ea9e3..a77a63ab23 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 3.0 -envlist = formatting, py39, py310, py311, py312, py313, pypy, benchmark +envlist = formatting, py310, py311, py312, py313, pypy, benchmark skip_missing_interpreters = true requires = pip >=21.3.1 isolated_build = true