Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop support for Python 3.8 #9774

Merged
merged 14 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/ISSUE_TEMPLATE/BUG-REPORT.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/primer-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/primer_run_main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/primer_run_pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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/[email protected]
with:
name: pr_number
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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/[email protected]
Expand Down Expand Up @@ -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/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas Jul 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we should remove this, sometime there's a new column/line in a new version. In particular when a bug is fixed or a nodes end is adjusted (in cpython). When this is the case we choose the newer version. This is still true in new interpreters. (Introduced when dealing with 3.9 only column change afair ?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation, will revert.

- "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
Expand Down
6 changes: 3 additions & 3 deletions doc/exts/pylint_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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).
"""
Expand Down
4 changes: 2 additions & 2 deletions doc/exts/pylint_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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."""
Expand Down
18 changes: 3 additions & 15 deletions doc/test_messages_documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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]]:
Expand Down
3 changes: 1 addition & 2 deletions doc/user_guide/checkers/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions doc/whatsnew/fragments/9774.other
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions pylint/checkers/base/name_checker/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 = {
Expand Down
4 changes: 2 additions & 2 deletions pylint/checkers/imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"},
Expand Down
1 change: 0 additions & 1 deletion pylint/checkers/method_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we replace this with a py-version check ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, but if my library supports 3.7 - 3.12, and I'm using a 3.8 function with positional-only arguments in the wrong manner, wouldn't I rather continue to see the message even if --py-version=3.7, because I certainly have bigger problems anyway if I'm using a 3.8+ function when I supposedly support 3.7?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought --py-version was most helpful for ensuring we silence suggestion-style messages that don't make sense on lower versions, like consider-using-f-string, but here we have a message that won't ever get raised on a lower version anyway, so I don't think we need to add a --py-version workaround for it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Jacob's second comment. I don't think it will add much benefit to spend the time to add support for that edge case. Removing this line is fine.

),
}
options = (
Expand Down
5 changes: 2 additions & 3 deletions pylint/checkers/nested_min_max.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions pylint/checkers/stdlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
Expand Down
20 changes: 5 additions & 15 deletions pylint/checkers/symilar.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand All @@ -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:
Expand Down Expand Up @@ -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(
Expand Down
9 changes: 3 additions & 6 deletions pylint/checkers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
19 changes: 1 addition & 18 deletions pylint/checkers/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
Loading
Loading