Skip to content

Require Python 3.6.2 #5068

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

Merged
merged 10 commits into from
Nov 25, 2021
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
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ Release date: TBA
..
Put bug fixes that should not wait for a new minor version here

* Require Python ``3.6.2`` to run pylint.

Closes #5065

..
Insert your changelog randomly, it will reduce merge conflicts
(Ie. not necessarilly at the end)
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Pylint can be simply installed by running::

pip install pylint

If you are using Python 3.6+, upgrade to get full support for your version::
If you are using Python 3.6.2+, upgrade to get full support for your version::

pip install pylint --upgrade

Expand Down
2 changes: 1 addition & 1 deletion doc/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ supported.
2.4 What versions of Python is Pylint supporting?
--------------------------------------------------

The supported running environment since Pylint 2.7.X is Python 3.6+.
The supported running environment since Pylint 2.12.1 is Python 3.6.2+.


3. Running Pylint
Expand Down
4 changes: 4 additions & 0 deletions doc/whatsnew/2.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ Extensions

Other Changes
=============

* Require Python ``3.6.2`` to run pylint.

Closes #5065
8 changes: 2 additions & 6 deletions pylint/checkers/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import numbers
import re
import tokenize
from typing import TYPE_CHECKING, Iterable
from typing import Counter, Iterable

import astroid
from astroid import nodes
Expand All @@ -50,9 +50,6 @@
from pylint.checkers.utils import check_messages
from pylint.interfaces import IAstroidChecker, IRawChecker, ITokenChecker

if TYPE_CHECKING:
from typing import Counter # typing.Counter added in Python 3.6.1

_AST_NODE_STR_TYPES = ("__builtin__.unicode", "__builtin__.str", "builtins.str")
# Prefixes for both strings and bytes literals per
# https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
Expand Down Expand Up @@ -774,8 +771,7 @@ def check_for_consistent_string_delimiters(
Args:
tokens: The tokens to be checked against for consistent usage.
"""
# typing.Counter added in Python 3.6.1 so this type hint must be a comment
string_delimiters = collections.Counter() # type: Counter[str]
string_delimiters: Counter[str] = collections.Counter()

# First, figure out which quote character predominates in the module
for tok_type, token, _, _, _ in tokens:
Expand Down
8 changes: 1 addition & 7 deletions pylint/message/message_id_store.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
import sys
from typing import Dict, List, Optional, Tuple
from typing import Dict, List, NoReturn, Optional, Tuple

from pylint.exceptions import InvalidMessageError, UnknownMessageError

if sys.version_info >= (3, 6, 2):
from typing import NoReturn
else:
from typing_extensions import NoReturn


class MessageIdStore:

Expand Down
8 changes: 4 additions & 4 deletions pylint/reporters/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class MessageStyle(NamedTuple):
"""The color name (see `ANSI_COLORS` for available values)
or the color number when 256 colors are available
"""
style: Tuple[str, ...]
style: Tuple[str, ...] = ()
"""Tuple of style strings (see `ANSI_COLORS` for available values).
"""

Expand Down Expand Up @@ -264,10 +264,10 @@ class ColorizedTextReporter(TextReporter):

name = "colorized"
COLOR_MAPPING: ColorMappingDict = {
"I": MessageStyle("green", ()),
"I": MessageStyle("green"),
"C": MessageStyle(None, ("bold",)),
"R": MessageStyle("magenta", ("bold", "italic")),
"W": MessageStyle("magenta", ()),
"W": MessageStyle("magenta"),
"E": MessageStyle("red", ("bold",)),
"F": MessageStyle("red", ("bold", "underline")),
"S": MessageStyle("yellow", ("inverse",)), # S stands for module Separator
Expand Down Expand Up @@ -326,7 +326,7 @@ def __init__(

def _get_decoration(self, msg_id: str) -> MessageStyle:
"""Returns the message style as defined in self.color_mapping"""
return self.color_mapping.get(msg_id[0]) or MessageStyle(None, ())
return self.color_mapping.get(msg_id[0]) or MessageStyle(None)

def handle_message(self, msg: Message) -> None:
"""manage message of different types, and colorize output
Expand Down
30 changes: 14 additions & 16 deletions pylint/testutils/lint_module_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import sys
from collections import Counter
from io import StringIO
from typing import TYPE_CHECKING, Dict, List, Optional, TextIO, Tuple
from typing import Counter as CounterType
from typing import Dict, List, Optional, TextIO, Tuple

import pytest
from _pytest.config import Config
Expand All @@ -25,10 +26,7 @@
from pylint.testutils.reporter_for_tests import FunctionalTestReporter
from pylint.utils import utils

if TYPE_CHECKING:
from typing import Counter as CounterType # typing.Counter added in Python 3.6.1

MessageCounter = CounterType[Tuple[int, str]]
MessageCounter = CounterType[Tuple[int, str]]


class LintModuleTest:
Expand Down Expand Up @@ -99,15 +97,15 @@ def __str__(self) -> str:
return f"{self._test_file.base} ({self.__class__.__module__}.{self.__class__.__name__})"

@staticmethod
def get_expected_messages(stream: TextIO) -> "MessageCounter":
def get_expected_messages(stream: TextIO) -> MessageCounter:
"""Parses a file and get expected messages.

:param stream: File-like input stream.
:type stream: enumerable
:returns: A dict mapping line,msg-symbol tuples to the count on this line.
:rtype: dict
"""
messages: "MessageCounter" = Counter()
messages: MessageCounter = Counter()
for i, line in enumerate(stream):
match = _EXPECTED_RE.search(line)
if match is None:
Expand All @@ -133,9 +131,9 @@ def get_expected_messages(stream: TextIO) -> "MessageCounter":

@staticmethod
def multiset_difference(
expected_entries: "MessageCounter",
actual_entries: "MessageCounter",
) -> Tuple["MessageCounter", Dict[Tuple[int, str], int]]:
expected_entries: MessageCounter,
actual_entries: MessageCounter,
) -> Tuple[MessageCounter, Dict[Tuple[int, str], int]]:
"""Takes two multisets and compares them.

A multiset is a dict with the cardinality of the key as the value."""
Expand All @@ -162,7 +160,7 @@ def _open_source_file(self) -> TextIO:
return open(self._test_file.source, encoding="latin1")
return open(self._test_file.source, encoding="utf8")

def _get_expected(self) -> Tuple["MessageCounter", List[OutputLine]]:
def _get_expected(self) -> Tuple[MessageCounter, List[OutputLine]]:
with self._open_source_file() as f:
expected_msgs = self.get_expected_messages(f)
if not expected_msgs:
Expand All @@ -174,10 +172,10 @@ def _get_expected(self) -> Tuple["MessageCounter", List[OutputLine]]:
]
return expected_msgs, expected_output_lines

def _get_actual(self) -> Tuple["MessageCounter", List[OutputLine]]:
def _get_actual(self) -> Tuple[MessageCounter, List[OutputLine]]:
messages: List[Message] = self._linter.reporter.messages
messages.sort(key=lambda m: (m.line, m.symbol, m.msg))
received_msgs: "MessageCounter" = Counter()
received_msgs: MessageCounter = Counter()
received_output_lines = []
for msg in messages:
assert (
Expand All @@ -204,8 +202,8 @@ def _runTest(self) -> None:

def error_msg_for_unequal_messages(
self,
actual_messages: "MessageCounter",
expected_messages: "MessageCounter",
actual_messages: MessageCounter,
expected_messages: MessageCounter,
actual_output: List[OutputLine],
) -> str:
msg = [f'Wrong results for file "{self._test_file.base}":']
Expand Down Expand Up @@ -250,7 +248,7 @@ def error_msg_for_unequal_output(

def _check_output_text(
self,
_: "MessageCounter",
_: MessageCounter,
expected_output: List[OutputLine],
actual_output: List[OutputLine],
) -> None:
Expand Down
2 changes: 1 addition & 1 deletion pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ unsafe-load-any-extension=no
extension-pkg-allow-list=

# Minimum supported python version
py-version = 3.6
py-version = 3.6.2


[MESSAGES CONTROL]
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_pre_commit.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Everything in this file should reflect the pre-commit configuration
# in .pre-commit-config.yaml
black==21.11b1;python_full_version>="3.6.2"
black==21.11b1
flake8==4.0.1
isort==5.10.1
mypy==0.910
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ install_requires =
toml>=0.9.2
colorama;sys_platform=="win32"
typing-extensions>=3.10.0;python_version<"3.10"
python_requires = ~=3.6
python_requires = >=3.6.2

[options.packages.find]
include =
Expand Down
17 changes: 0 additions & 17 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,3 @@
import sys

from setuptools import setup


class PylintIncompatiblePythonError(Exception):
def __init__(self) -> None:
super().__init__(
"The last version compatible with Python <= 3.6.2 is pylint '2.9.3'. "
f"You're using {'.'.join([str(v) for v in sys.version_info[:3]])}. "
"Please install pylint 2.9.3 explicitly or upgrade your python interpreter "
"to at least 3.6.2. Remember that Python 3.6 end life is December 2021. "
"See https://github.com/PyCQA/pylint/issues/5065 for more detail."
)


if sys.version_info < (3, 6, 2):
raise PylintIncompatiblePythonError()

setup()
8 changes: 1 addition & 7 deletions tests/lint/test_pylinter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import sys
from typing import Any
from typing import Any, NoReturn
from unittest.mock import patch

from astroid import AstroidBuildingError
Expand All @@ -9,11 +8,6 @@
from pylint.lint.pylinter import PyLinter
from pylint.utils import FileState

if sys.version_info >= (3, 6, 2):
from typing import NoReturn
else:
from typing_extensions import NoReturn


def raise_exception(*args: Any, **kwargs: Any) -> NoReturn:
raise AstroidBuildingError(modname="spam")
Expand Down