Skip to content

Commit e81ab7b

Browse files
Revert "Remove --min_pyver_end_position" (#9784)
* Revert "Remove `--min_pyver_end_position`" This reverts commit 4b45192. * Revert "Simplify testutils" This reverts commit 833762f. * Remove PyPy special case, typing fixes * Rename method to avoid py38 reference
1 parent 52fe657 commit e81ab7b

File tree

6 files changed

+99
-12
lines changed

6 files changed

+99
-12
lines changed

doc/development_guide/contributor_guide/tests/writing_test.rst

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ test runner. The following options are currently supported:
6161

6262
- "min_pyver": Minimal python version required to run the test
6363
- "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.
64+
- "min_pyver_end_position": Minimal python version required to check the end_line and end_column attributes of the message
6465
- "requires": Packages required to be installed locally to run the test
6566
- "except_implementations": List of python implementations on which the test should not run
6667
- "exclude_platforms": List of operating systems on which the test should not run

doc/whatsnew/fragments/9774.other

-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
Remove support for launching pylint with Python 3.8.
22
Code that supports Python 3.8 can still be linted with the ``--py-version=3.8`` setting.
33

4-
``--min_pyver_end_position`` in the functional test runner is no longer relevant and is removed.
5-
64
Refs #9774

pylint/testutils/functional/test_file.py

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class NoFileError(Exception):
2222
class TestFileOptions(TypedDict):
2323
min_pyver: tuple[int, ...]
2424
max_pyver: tuple[int, ...]
25+
min_pyver_end_position: tuple[int, ...]
2526
requires: list[str]
2627
except_implementations: list[str]
2728
exclude_platforms: list[str]
@@ -32,6 +33,7 @@ class TestFileOptions(TypedDict):
3233
POSSIBLE_TEST_OPTIONS = {
3334
"min_pyver",
3435
"max_pyver",
36+
"min_pyver_end_position",
3537
"requires",
3638
"except_implementations",
3739
"exclude_platforms",
@@ -45,6 +47,7 @@ class FunctionalTestFile:
4547
_CONVERTERS: dict[str, Callable[[str], tuple[int, ...] | list[str]]] = {
4648
"min_pyver": parse_python_version,
4749
"max_pyver": parse_python_version,
50+
"min_pyver_end_position": parse_python_version,
4851
"requires": lambda s: [i.strip() for i in s.split(",")],
4952
"except_implementations": lambda s: [i.strip() for i in s.split(",")],
5053
"exclude_platforms": lambda s: [i.strip() for i in s.split(",")],
@@ -58,6 +61,7 @@ def __init__(self, directory: str, filename: str) -> None:
5861
self.options: TestFileOptions = {
5962
"min_pyver": (2, 5),
6063
"max_pyver": (4, 0),
64+
"min_pyver_end_position": (3, 8),
6165
"requires": [],
6266
"except_implementations": [],
6367
"exclude_platforms": [],

pylint/testutils/lint_module_test.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ def __init__(
7979
self._linter._arg_parser.add_argument(
8080
"--max_pyver", type=parse_python_version, default=(4, 0)
8181
)
82+
self._linter._arg_parser.add_argument(
83+
"--min_pyver_end_position", type=parse_python_version, default=(3, 8)
84+
)
8285
self._linter._arg_parser.add_argument(
8386
"--requires", type=lambda s: [i.strip() for i in s.split(",")], default=[]
8487
)
@@ -100,6 +103,10 @@ def __init__(
100103
self._linter, args_list=args, config_file=rc_file, reporter=_test_reporter
101104
)
102105

106+
self._check_end_position = (
107+
sys.version_info >= self._linter.config.min_pyver_end_position
108+
)
109+
103110
self._config = config
104111

105112
def setUp(self) -> None:
@@ -215,7 +222,8 @@ def _get_expected(self) -> tuple[MessageCounter, list[OutputLine]]:
215222
expected_msgs = Counter()
216223
with self._open_expected_file() as f:
217224
expected_output_lines = [
218-
OutputLine.from_csv(row) for row in csv.reader(f, "test")
225+
OutputLine.from_csv(row, self._check_end_position)
226+
for row in csv.reader(f, "test")
219227
]
220228
return expected_msgs, expected_output_lines
221229

@@ -229,7 +237,9 @@ def _get_actual(self) -> tuple[MessageCounter, list[OutputLine]]:
229237
msg.symbol != "fatal"
230238
), f"Pylint analysis failed because of '{msg.msg}'"
231239
received_msgs[msg.line, msg.symbol] += 1
232-
received_output_lines.append(OutputLine.from_msg(msg))
240+
received_output_lines.append(
241+
OutputLine.from_msg(msg, self._check_end_position)
242+
)
233243
return received_msgs, received_output_lines
234244

235245
def _runTest(self) -> None:

pylint/testutils/output_line.py

+26-7
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
from __future__ import annotations
66

77
from collections.abc import Sequence
8-
from typing import Any, NamedTuple
8+
from typing import Any, NamedTuple, TypeVar
99

1010
from astroid import nodes
1111

1212
from pylint.interfaces import UNDEFINED, Confidence
1313
from pylint.message.message import Message
1414

15+
_T = TypeVar("_T")
16+
1517

1618
class MessageTest(NamedTuple):
1719
msg_id: str
@@ -39,15 +41,17 @@ class OutputLine(NamedTuple):
3941
confidence: str
4042

4143
@classmethod
42-
def from_msg(cls, msg: Message) -> OutputLine:
44+
def from_msg(cls, msg: Message, check_endline: bool = True) -> OutputLine:
4345
"""Create an OutputLine from a Pylint Message."""
4446
column = cls._get_column(msg.column)
47+
end_line = cls._get_end_line_and_end_col(msg.end_line, check_endline)
48+
end_column = cls._get_end_line_and_end_col(msg.end_column, check_endline)
4549
return cls(
4650
msg.symbol,
4751
msg.line,
4852
column,
49-
msg.end_line,
50-
msg.end_column,
53+
end_line,
54+
end_column,
5155
msg.obj or "",
5256
msg.msg.replace("\r\n", "\n"),
5357
msg.confidence.name,
@@ -58,8 +62,19 @@ def _get_column(column: str | int) -> int:
5862
"""Handle column numbers."""
5963
return int(column)
6064

65+
@staticmethod
66+
def _get_end_line_and_end_col(value: _T, check_endline: bool) -> _T | None:
67+
"""Used to make end_line and end_column None as indicated by our version
68+
compared to `min_pyver_end_position`.
69+
"""
70+
if not check_endline:
71+
return None # pragma: no cover
72+
return value
73+
6174
@classmethod
62-
def from_csv(cls, row: Sequence[str] | str) -> OutputLine:
75+
def from_csv(
76+
cls, row: Sequence[str] | str, check_endline: bool = True
77+
) -> OutputLine:
6378
"""Create an OutputLine from a comma separated list (the functional tests
6479
expected output .txt files).
6580
"""
@@ -68,8 +83,12 @@ def from_csv(cls, row: Sequence[str] | str) -> OutputLine:
6883
try:
6984
line = int(row[1])
7085
column = cls._get_column(row[2])
71-
end_line = cls._value_to_optional_int(row[3])
72-
end_column = cls._value_to_optional_int(row[4])
86+
end_line = cls._value_to_optional_int(
87+
cls._get_end_line_and_end_col(row[3], check_endline)
88+
)
89+
end_column = cls._value_to_optional_int(
90+
cls._get_end_line_and_end_col(row[4], check_endline)
91+
)
7392
# symbol, line, column, end_line, end_column, node, msg, confidences
7493
assert len(row) == 8
7594
return cls(

tests/testutils/test_output_line.py

+56-1
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,33 @@ def test_output_line_from_message(message: _MessageCallable) -> None:
7070
assert output_line.msg == "msg"
7171
assert output_line.confidence == "HIGH"
7272

73+
output_line_with_end = OutputLine.from_msg(message(), True)
74+
assert output_line_with_end.symbol == "missing-docstring"
75+
assert output_line_with_end.lineno == 1
76+
assert output_line_with_end.column == 2
77+
assert output_line_with_end.end_lineno == 1
78+
assert output_line_with_end.end_column == 3
79+
assert output_line_with_end.object == "obj"
80+
assert output_line_with_end.msg == "msg"
81+
assert output_line_with_end.confidence == "HIGH"
82+
83+
output_line_without_end = OutputLine.from_msg(message(), False)
84+
assert output_line_without_end.symbol == "missing-docstring"
85+
assert output_line_without_end.lineno == 1
86+
assert output_line_without_end.column == 2
87+
assert output_line_without_end.end_lineno is None
88+
assert output_line_without_end.end_column is None
89+
assert output_line_without_end.object == "obj"
90+
assert output_line_without_end.msg == "msg"
91+
assert output_line_without_end.confidence == "HIGH"
92+
7393

7494
@pytest.mark.parametrize("confidence", [HIGH, INFERENCE])
7595
def test_output_line_to_csv(confidence: Confidence, message: _MessageCallable) -> None:
7696
"""Test that the OutputLine NamedTuple is instantiated correctly with from_msg
7797
and then converted to csv.
7898
"""
79-
output_line = OutputLine.from_msg(message(confidence))
99+
output_line = OutputLine.from_msg(message(confidence), True)
80100
csv = output_line.to_csv()
81101
assert csv == (
82102
"missing-docstring",
@@ -89,6 +109,19 @@ def test_output_line_to_csv(confidence: Confidence, message: _MessageCallable) -
89109
confidence.name,
90110
)
91111

112+
output_line_without_end = OutputLine.from_msg(message(confidence), False)
113+
csv = output_line_without_end.to_csv()
114+
assert csv == (
115+
"missing-docstring",
116+
"1",
117+
"2",
118+
"None",
119+
"None",
120+
"obj",
121+
"msg",
122+
confidence.name,
123+
)
124+
92125

93126
def test_output_line_from_csv() -> None:
94127
"""Test that the OutputLine NamedTuple is instantiated correctly with from_csv.
@@ -107,3 +140,25 @@ def test_output_line_from_csv() -> None:
107140
msg="msg",
108141
confidence="HIGH",
109142
)
143+
output_line_with_end = OutputLine.from_csv(proper_csv, True)
144+
assert output_line_with_end == OutputLine(
145+
symbol="missing-docstring",
146+
lineno=1,
147+
column=2,
148+
end_lineno=1,
149+
end_column=None,
150+
object="obj",
151+
msg="msg",
152+
confidence="HIGH",
153+
)
154+
output_line_without_end = OutputLine.from_csv(proper_csv, False)
155+
assert output_line_without_end == OutputLine(
156+
symbol="missing-docstring",
157+
lineno=1,
158+
column=2,
159+
end_lineno=None,
160+
end_column=None,
161+
object="obj",
162+
msg="msg",
163+
confidence="HIGH",
164+
)

0 commit comments

Comments
 (0)