Skip to content

Commit a9c1017

Browse files
Require Python 3.6.2 (#5068)
* Bump python_requires to >= 3.6.2 * Import typing names directly * Use typing.NamedTuple for MessageTest * Add default value to MessageStyle * Revert "Add an exception at install for python < 3.6.2 (#5171)" This reverts commit 37e330c. Co-authored-by: Pierre Sassoulas <[email protected]>
1 parent 1f7f2e9 commit a9c1017

File tree

12 files changed

+34
-61
lines changed

12 files changed

+34
-61
lines changed

ChangeLog

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Release date: TBA
2222
..
2323
Put bug fixes that should not wait for a new minor version here
2424

25+
* Require Python ``3.6.2`` to run pylint.
26+
27+
Closes #5065
28+
2529
..
2630
Insert your changelog randomly, it will reduce merge conflicts
2731
(Ie. not necessarily at the end)

README.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Pylint can be simply installed by running::
7575

7676
pip install pylint
7777

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

8080
pip install pylint --upgrade
8181

doc/faq.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ supported.
4848
2.4 What versions of Python is Pylint supporting?
4949
--------------------------------------------------
5050

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

5353

5454
3. Running Pylint

doc/whatsnew/2.13.rst

+4
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ Extensions
1919

2020
Other Changes
2121
=============
22+
23+
* Require Python ``3.6.2`` to run pylint.
24+
25+
Closes #5065

pylint/checkers/strings.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import numbers
4242
import re
4343
import tokenize
44-
from typing import TYPE_CHECKING, Iterable
44+
from typing import Counter, Iterable
4545

4646
import astroid
4747
from astroid import nodes
@@ -50,9 +50,6 @@
5050
from pylint.checkers.utils import check_messages
5151
from pylint.interfaces import IAstroidChecker, IRawChecker, ITokenChecker
5252

53-
if TYPE_CHECKING:
54-
from typing import Counter # typing.Counter added in Python 3.6.1
55-
5653
_AST_NODE_STR_TYPES = ("__builtin__.unicode", "__builtin__.str", "builtins.str")
5754
# Prefixes for both strings and bytes literals per
5855
# https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
@@ -774,8 +771,7 @@ def check_for_consistent_string_delimiters(
774771
Args:
775772
tokens: The tokens to be checked against for consistent usage.
776773
"""
777-
# typing.Counter added in Python 3.6.1 so this type hint must be a comment
778-
string_delimiters = collections.Counter() # type: Counter[str]
774+
string_delimiters: Counter[str] = collections.Counter()
779775

780776
# First, figure out which quote character predominates in the module
781777
for tok_type, token, _, _, _ in tokens:

pylint/message/message_id_store.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
3-
import sys
4-
from typing import Dict, List, Optional, Tuple
3+
from typing import Dict, List, NoReturn, Optional, Tuple
54

65
from pylint.exceptions import InvalidMessageError, UnknownMessageError
76

8-
if sys.version_info >= (3, 6, 2):
9-
from typing import NoReturn
10-
else:
11-
from typing_extensions import NoReturn
12-
137

148
class MessageIdStore:
159

pylint/reporters/text.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class MessageStyle(NamedTuple):
5959
"""The color name (see `ANSI_COLORS` for available values)
6060
or the color number when 256 colors are available
6161
"""
62-
style: Tuple[str, ...]
62+
style: Tuple[str, ...] = ()
6363
"""Tuple of style strings (see `ANSI_COLORS` for available values).
6464
"""
6565

@@ -264,10 +264,10 @@ class ColorizedTextReporter(TextReporter):
264264

265265
name = "colorized"
266266
COLOR_MAPPING: ColorMappingDict = {
267-
"I": MessageStyle("green", ()),
267+
"I": MessageStyle("green"),
268268
"C": MessageStyle(None, ("bold",)),
269269
"R": MessageStyle("magenta", ("bold", "italic")),
270-
"W": MessageStyle("magenta", ()),
270+
"W": MessageStyle("magenta"),
271271
"E": MessageStyle("red", ("bold",)),
272272
"F": MessageStyle("red", ("bold", "underline")),
273273
"S": MessageStyle("yellow", ("inverse",)), # S stands for module Separator
@@ -326,7 +326,7 @@ def __init__(
326326

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

331331
def handle_message(self, msg: Message) -> None:
332332
"""manage message of different types, and colorize output

pylint/testutils/lint_module_test.py

+14-16
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
import sys
88
from collections import Counter
99
from io import StringIO
10-
from typing import TYPE_CHECKING, Dict, List, Optional, TextIO, Tuple
10+
from typing import Counter as CounterType
11+
from typing import Dict, List, Optional, TextIO, Tuple
1112

1213
import pytest
1314
from _pytest.config import Config
@@ -25,10 +26,7 @@
2526
from pylint.testutils.reporter_for_tests import FunctionalTestReporter
2627
from pylint.utils import utils
2728

28-
if TYPE_CHECKING:
29-
from typing import Counter as CounterType # typing.Counter added in Python 3.6.1
30-
31-
MessageCounter = CounterType[Tuple[int, str]]
29+
MessageCounter = CounterType[Tuple[int, str]]
3230

3331

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

10199
@staticmethod
102-
def get_expected_messages(stream: TextIO) -> "MessageCounter":
100+
def get_expected_messages(stream: TextIO) -> MessageCounter:
103101
"""Parses a file and get expected messages.
104102
105103
:param stream: File-like input stream.
106104
:type stream: enumerable
107105
:returns: A dict mapping line,msg-symbol tuples to the count on this line.
108106
:rtype: dict
109107
"""
110-
messages: "MessageCounter" = Counter()
108+
messages: MessageCounter = Counter()
111109
for i, line in enumerate(stream):
112110
match = _EXPECTED_RE.search(line)
113111
if match is None:
@@ -133,9 +131,9 @@ def get_expected_messages(stream: TextIO) -> "MessageCounter":
133131

134132
@staticmethod
135133
def multiset_difference(
136-
expected_entries: "MessageCounter",
137-
actual_entries: "MessageCounter",
138-
) -> Tuple["MessageCounter", Dict[Tuple[int, str], int]]:
134+
expected_entries: MessageCounter,
135+
actual_entries: MessageCounter,
136+
) -> Tuple[MessageCounter, Dict[Tuple[int, str], int]]:
139137
"""Takes two multisets and compares them.
140138
141139
A multiset is a dict with the cardinality of the key as the value."""
@@ -162,7 +160,7 @@ def _open_source_file(self) -> TextIO:
162160
return open(self._test_file.source, encoding="latin1")
163161
return open(self._test_file.source, encoding="utf8")
164162

165-
def _get_expected(self) -> Tuple["MessageCounter", List[OutputLine]]:
163+
def _get_expected(self) -> Tuple[MessageCounter, List[OutputLine]]:
166164
with self._open_source_file() as f:
167165
expected_msgs = self.get_expected_messages(f)
168166
if not expected_msgs:
@@ -174,10 +172,10 @@ def _get_expected(self) -> Tuple["MessageCounter", List[OutputLine]]:
174172
]
175173
return expected_msgs, expected_output_lines
176174

177-
def _get_actual(self) -> Tuple["MessageCounter", List[OutputLine]]:
175+
def _get_actual(self) -> Tuple[MessageCounter, List[OutputLine]]:
178176
messages: List[Message] = self._linter.reporter.messages
179177
messages.sort(key=lambda m: (m.line, m.symbol, m.msg))
180-
received_msgs: "MessageCounter" = Counter()
178+
received_msgs: MessageCounter = Counter()
181179
received_output_lines = []
182180
for msg in messages:
183181
assert (
@@ -204,8 +202,8 @@ def _runTest(self) -> None:
204202

205203
def error_msg_for_unequal_messages(
206204
self,
207-
actual_messages: "MessageCounter",
208-
expected_messages: "MessageCounter",
205+
actual_messages: MessageCounter,
206+
expected_messages: MessageCounter,
209207
actual_output: List[OutputLine],
210208
) -> str:
211209
msg = [f'Wrong results for file "{self._test_file.base}":']
@@ -250,7 +248,7 @@ def error_msg_for_unequal_output(
250248

251249
def _check_output_text(
252250
self,
253-
_: "MessageCounter",
251+
_: MessageCounter,
254252
expected_output: List[OutputLine],
255253
actual_output: List[OutputLine],
256254
) -> None:

pylintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ unsafe-load-any-extension=no
4444
extension-pkg-allow-list=
4545

4646
# Minimum supported python version
47-
py-version = 3.6
47+
py-version = 3.6.2
4848

4949

5050
[MESSAGES CONTROL]

requirements_test_pre_commit.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Everything in this file should reflect the pre-commit configuration
22
# in .pre-commit-config.yaml
3-
black==21.11b1;python_full_version>="3.6.2"
3+
black==21.11b1
44
flake8==4.0.1
55
flake8-typing-imports==1.10.1
66
isort==5.10.1

setup.py

-17
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,3 @@
1-
import sys
2-
31
from setuptools import setup
42

5-
6-
class PylintIncompatiblePythonError(Exception):
7-
def __init__(self) -> None:
8-
super().__init__(
9-
"The last version compatible with Python <= 3.6.2 is pylint '2.9.3'. "
10-
f"You're using {'.'.join([str(v) for v in sys.version_info[:3]])}. "
11-
"Please install pylint 2.9.3 explicitly or upgrade your python interpreter "
12-
"to at least 3.6.2. Remember that Python 3.6 end life is December 2021. "
13-
"See https://github.com/PyCQA/pylint/issues/5065 for more detail."
14-
)
15-
16-
17-
if sys.version_info < (3, 6, 2):
18-
raise PylintIncompatiblePythonError()
19-
203
setup()

tests/lint/test_pylinter.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import sys
2-
from typing import Any
1+
from typing import Any, NoReturn
32
from unittest.mock import patch
43

54
from astroid import AstroidBuildingError
@@ -9,11 +8,6 @@
98
from pylint.lint.pylinter import PyLinter
109
from pylint.utils import FileState
1110

12-
if sys.version_info >= (3, 6, 2):
13-
from typing import NoReturn
14-
else:
15-
from typing_extensions import NoReturn
16-
1711

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

0 commit comments

Comments
 (0)