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

Revert "Remove --min_pyver_end_position" #121

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ 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
- "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
2 changes: 0 additions & 2 deletions doc/whatsnew/fragments/9774.other
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
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: 4 additions & 0 deletions pylint/testutils/functional/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class NoFileError(Exception):
class TestFileOptions(TypedDict):
min_pyver: tuple[int, ...]
max_pyver: tuple[int, ...]
min_pyver_end_position: tuple[int, ...]
requires: list[str]
except_implementations: list[str]
exclude_platforms: list[str]
Expand All @@ -32,6 +33,7 @@ class TestFileOptions(TypedDict):
POSSIBLE_TEST_OPTIONS = {
"min_pyver",
"max_pyver",
"min_pyver_end_position",
"requires",
"except_implementations",
"exclude_platforms",
Expand All @@ -45,6 +47,7 @@ class FunctionalTestFile:
_CONVERTERS: dict[str, Callable[[str], tuple[int, ...] | list[str]]] = {
"min_pyver": parse_python_version,
"max_pyver": parse_python_version,
"min_pyver_end_position": parse_python_version,
"requires": lambda s: [i.strip() for i in s.split(",")],
"except_implementations": lambda s: [i.strip() for i in s.split(",")],
"exclude_platforms": lambda s: [i.strip() for i in s.split(",")],
Expand All @@ -58,6 +61,7 @@ def __init__(self, directory: str, filename: str) -> None:
self.options: TestFileOptions = {
"min_pyver": (2, 5),
"max_pyver": (4, 0),
"min_pyver_end_position": (3, 8),
"requires": [],
"except_implementations": [],
"exclude_platforms": [],
Expand Down
14 changes: 12 additions & 2 deletions pylint/testutils/lint_module_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ def __init__(
self._linter._arg_parser.add_argument(
"--max_pyver", type=parse_python_version, default=(4, 0)
)
self._linter._arg_parser.add_argument(
"--min_pyver_end_position", type=parse_python_version, default=(3, 8)
)
self._linter._arg_parser.add_argument(
"--requires", type=lambda s: [i.strip() for i in s.split(",")], default=[]
)
Expand All @@ -100,6 +103,10 @@ def __init__(
self._linter, args_list=args, config_file=rc_file, reporter=_test_reporter
)

self._check_end_position = (
sys.version_info >= self._linter.config.min_pyver_end_position
)

self._config = config

def setUp(self) -> None:
Expand Down Expand Up @@ -215,7 +222,8 @@ def _get_expected(self) -> tuple[MessageCounter, list[OutputLine]]:
expected_msgs = Counter()
with self._open_expected_file() as f:
expected_output_lines = [
OutputLine.from_csv(row) for row in csv.reader(f, "test")
OutputLine.from_csv(row, self._check_end_position)
for row in csv.reader(f, "test")
]
return expected_msgs, expected_output_lines

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

def _runTest(self) -> None:
Expand Down
33 changes: 26 additions & 7 deletions pylint/testutils/output_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
from __future__ import annotations

from collections.abc import Sequence
from typing import Any, NamedTuple
from typing import Any, NamedTuple, TypeVar

from astroid import nodes

from pylint.interfaces import UNDEFINED, Confidence
from pylint.message.message import Message

_T = TypeVar("_T")


class MessageTest(NamedTuple):
msg_id: str
Expand Down Expand Up @@ -39,15 +41,17 @@ class OutputLine(NamedTuple):
confidence: str

@classmethod
def from_msg(cls, msg: Message) -> OutputLine:
def from_msg(cls, msg: Message, check_endline: bool = True) -> OutputLine:
"""Create an OutputLine from a Pylint Message."""
column = cls._get_column(msg.column)
end_line = cls._get_end_line_and_end_col(msg.end_line, check_endline)
end_column = cls._get_end_line_and_end_col(msg.end_column, check_endline)
return cls(
msg.symbol,
msg.line,
column,
msg.end_line,
msg.end_column,
end_line,
end_column,
msg.obj or "",
msg.msg.replace("\r\n", "\n"),
msg.confidence.name,
Expand All @@ -58,8 +62,19 @@ def _get_column(column: str | int) -> int:
"""Handle column numbers."""
return int(column)

@staticmethod
def _get_end_line_and_end_col(value: _T, check_endline: bool) -> _T | None:
"""Used to make end_line and end_column None as indicated by our version
compared to `min_pyver_end_position`.
"""
if not check_endline:
return None # pragma: no cover
return value

@classmethod
def from_csv(cls, row: Sequence[str] | str) -> OutputLine:
def from_csv(
cls, row: Sequence[str] | str, check_endline: bool = True
) -> OutputLine:
"""Create an OutputLine from a comma separated list (the functional tests
expected output .txt files).
"""
Expand All @@ -68,8 +83,12 @@ def from_csv(cls, row: Sequence[str] | str) -> OutputLine:
try:
line = int(row[1])
column = cls._get_column(row[2])
end_line = cls._value_to_optional_int(row[3])
end_column = cls._value_to_optional_int(row[4])
end_line = cls._value_to_optional_int(
cls._get_end_line_and_end_col(row[3], check_endline)
)
end_column = cls._value_to_optional_int(
cls._get_end_line_and_end_col(row[4], check_endline)
)
# symbol, line, column, end_line, end_column, node, msg, confidences
assert len(row) == 8
return cls(
Expand Down
57 changes: 56 additions & 1 deletion tests/testutils/test_output_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,33 @@ def test_output_line_from_message(message: _MessageCallable) -> None:
assert output_line.msg == "msg"
assert output_line.confidence == "HIGH"

output_line_with_end = OutputLine.from_msg(message(), True)
assert output_line_with_end.symbol == "missing-docstring"
assert output_line_with_end.lineno == 1
assert output_line_with_end.column == 2
assert output_line_with_end.end_lineno == 1
assert output_line_with_end.end_column == 3
assert output_line_with_end.object == "obj"
assert output_line_with_end.msg == "msg"
assert output_line_with_end.confidence == "HIGH"

output_line_without_end = OutputLine.from_msg(message(), False)
assert output_line_without_end.symbol == "missing-docstring"
assert output_line_without_end.lineno == 1
assert output_line_without_end.column == 2
assert output_line_without_end.end_lineno is None
assert output_line_without_end.end_column is None
assert output_line_without_end.object == "obj"
assert output_line_without_end.msg == "msg"
assert output_line_without_end.confidence == "HIGH"


@pytest.mark.parametrize("confidence", [HIGH, INFERENCE])
def test_output_line_to_csv(confidence: Confidence, message: _MessageCallable) -> None:
"""Test that the OutputLine NamedTuple is instantiated correctly with from_msg
and then converted to csv.
"""
output_line = OutputLine.from_msg(message(confidence))
output_line = OutputLine.from_msg(message(confidence), True)
csv = output_line.to_csv()
assert csv == (
"missing-docstring",
Expand All @@ -89,6 +109,19 @@ def test_output_line_to_csv(confidence: Confidence, message: _MessageCallable) -
confidence.name,
)

output_line_without_end = OutputLine.from_msg(message(confidence), False)
csv = output_line_without_end.to_csv()
assert csv == (
"missing-docstring",
"1",
"2",
"None",
"None",
"obj",
"msg",
confidence.name,
)


def test_output_line_from_csv() -> None:
"""Test that the OutputLine NamedTuple is instantiated correctly with from_csv.
Expand All @@ -107,3 +140,25 @@ def test_output_line_from_csv() -> None:
msg="msg",
confidence="HIGH",
)
output_line_with_end = OutputLine.from_csv(proper_csv, True)
assert output_line_with_end == OutputLine(
symbol="missing-docstring",
lineno=1,
column=2,
end_lineno=1,
end_column=None,
object="obj",
msg="msg",
confidence="HIGH",
)
output_line_without_end = OutputLine.from_csv(proper_csv, False)
assert output_line_without_end == OutputLine(
symbol="missing-docstring",
lineno=1,
column=2,
end_lineno=None,
end_column=None,
object="obj",
msg="msg",
confidence="HIGH",
)
Loading