summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>2021-11-22 22:40:26 +0100
committerGitHub <noreply@github.com>2021-11-22 22:40:26 +0100
commitee70d41881600b67c3d98d41c060b81a22a45210 (patch)
tree603f49c38007f4a52410059d4796c5185574844a
parente4fd27544c04c9637b89fb678c1df19166506a10 (diff)
downloadpylint-git-ee70d41881600b67c3d98d41c060b81a22a45210.tar.gz
Add ``end_lineno`` and ``end_col_offset`` to ``MessageLocationTuple`` (#5343)
-rw-r--r--pylint/checkers/base_checker.py6
-rw-r--r--pylint/lint/pylinter.py44
-rw-r--r--pylint/message/message.py8
-rw-r--r--pylint/testutils/unittest_linter.py4
-rw-r--r--pylint/typing.py2
-rw-r--r--tests/lint/unittest_lint.py20
-rw-r--r--tests/message/unittest_message.py4
-rw-r--r--tests/testutils/test_output_line.py7
8 files changed, 79 insertions, 16 deletions
diff --git a/pylint/checkers/base_checker.py b/pylint/checkers/base_checker.py
index 328adcb4d..269979daf 100644
--- a/pylint/checkers/base_checker.py
+++ b/pylint/checkers/base_checker.py
@@ -116,8 +116,12 @@ class BaseChecker(OptionsProviderMixIn):
args: Any = None,
confidence: Optional[Confidence] = None,
col_offset: Optional[int] = None,
+ end_lineno: Optional[int] = None,
+ end_col_offset: Optional[int] = None,
) -> None:
- self.linter.add_message(msgid, line, node, args, confidence, col_offset)
+ self.linter.add_message(
+ msgid, line, node, args, confidence, col_offset, end_lineno, end_col_offset
+ )
def check_consistency(self):
"""Check the consistency of msgid.
diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py
index 913bc4a22..53453af40 100644
--- a/pylint/lint/pylinter.py
+++ b/pylint/lint/pylinter.py
@@ -1413,14 +1413,30 @@ class PyLinter(
args: Optional[Any],
confidence: Optional[interfaces.Confidence],
col_offset: Optional[int],
+ end_lineno: Optional[int],
+ end_col_offset: Optional[int],
) -> None:
"""After various checks have passed a single Message is
passed to the reporter and added to stats"""
message_definition.check_message_definition(line, node)
- if line is None and node is not None:
- line = node.fromlineno
- if col_offset is None and hasattr(node, "col_offset"):
- col_offset = node.col_offset # type: ignore[union-attr]
+
+ # Look up "location" data of node if not yet supplied
+ if node:
+ if not line:
+ line = node.fromlineno
+ # pylint: disable=fixme
+ # TODO: Initialize col_offset on every node (can be None) -> astroid
+ if not col_offset and hasattr(node, "col_offset"):
+ col_offset = node.col_offset
+ # pylint: disable=fixme
+ # TODO: Initialize end_lineno on every node (can be None) -> astroid
+ # See https://github.com/PyCQA/astroid/issues/1273
+ if not end_lineno and hasattr(node, "end_lineno"):
+ end_lineno = node.end_lineno
+ # pylint: disable=fixme
+ # TODO: Initialize end_col_offset on every node (can be None) -> astroid
+ if not end_col_offset and hasattr(node, "end_col_offset"):
+ end_col_offset = node.end_col_offset
# should this message be displayed
if not self.is_message_enabled(message_definition.msgid, line, confidence):
@@ -1463,7 +1479,14 @@ class PyLinter(
message_definition.msgid,
message_definition.symbol,
MessageLocationTuple(
- abspath, path, module or "", obj, line or 1, col_offset or 0
+ abspath,
+ path,
+ module or "",
+ obj,
+ line or 1,
+ col_offset or 0,
+ end_lineno,
+ end_col_offset,
),
msg,
confidence,
@@ -1478,6 +1501,8 @@ class PyLinter(
args: Optional[Any] = None,
confidence: Optional[interfaces.Confidence] = None,
col_offset: Optional[int] = None,
+ end_lineno: Optional[int] = None,
+ end_col_offset: Optional[int] = None,
) -> None:
"""Adds a message given by ID or name.
@@ -1492,7 +1517,14 @@ class PyLinter(
message_definitions = self.msgs_store.get_message_definitions(msgid)
for message_definition in message_definitions:
self._add_one_message(
- message_definition, line, node, args, confidence, col_offset
+ message_definition,
+ line,
+ node,
+ args,
+ confidence,
+ col_offset,
+ end_lineno,
+ end_col_offset,
)
def add_ignored_message(
diff --git a/pylint/message/message.py b/pylint/message/message.py
index 178079223..b431d502b 100644
--- a/pylint/message/message.py
+++ b/pylint/message/message.py
@@ -25,6 +25,8 @@ _MsgBase = collections.namedtuple(
"obj",
"line",
"column",
+ "end_line",
+ "end_column",
],
)
@@ -59,7 +61,10 @@ class Message(_MsgBase):
cls,
msg_id: str,
symbol: str,
- location: Union[Tuple[str, str, str, str, int, int], MessageLocationTuple],
+ location: Union[
+ Tuple[str, str, str, str, int, int],
+ MessageLocationTuple,
+ ],
msg: str,
confidence: Optional[Confidence],
) -> "Message":
@@ -68,6 +73,7 @@ class Message(_MsgBase):
"In pylint 3.0, Messages will only accept a MessageLocationTuple as location parameter",
DeprecationWarning,
)
+ location = location + (None, None) # type: ignore[assignment] # Temporary fix until deprecation
return _MsgBase.__new__(
cls,
msg_id,
diff --git a/pylint/testutils/unittest_linter.py b/pylint/testutils/unittest_linter.py
index 2d9e42e65..b8fbb8c91 100644
--- a/pylint/testutils/unittest_linter.py
+++ b/pylint/testutils/unittest_linter.py
@@ -34,8 +34,12 @@ class UnittestLinter:
args: Any = None,
confidence: Optional[Confidence] = None,
col_offset: Optional[int] = None,
+ end_lineno: Optional[int] = None,
+ end_col_offset: Optional[int] = None,
) -> None:
# Do not test col_offset for now since changing Message breaks everything
+ # pylint: disable=fixme
+ # TODO: Test end_lineno and end_col_offset :)
self._messages.append(MessageTest(msg_id, line, node, args, confidence))
@staticmethod
diff --git a/pylint/typing.py b/pylint/typing.py
index 7ea72cff3..5f1524180 100644
--- a/pylint/typing.py
+++ b/pylint/typing.py
@@ -52,6 +52,8 @@ class MessageLocationTuple(NamedTuple):
obj: str
line: int
column: int
+ end_line: Optional[int] = None
+ end_column: Optional[int] = None
class ManagedMessage(NamedTuple):
diff --git a/tests/lint/unittest_lint.py b/tests/lint/unittest_lint.py
index a167b03fd..865d7640b 100644
--- a/tests/lint/unittest_lint.py
+++ b/tests/lint/unittest_lint.py
@@ -500,7 +500,14 @@ def test_addmessage(linter: PyLinter) -> None:
description="Warning without any associated confidence level.",
),
location=MessageLocationTuple(
- abspath="0123", path="0123", module="0123", obj="", line=1, column=0
+ abspath="0123",
+ path="0123",
+ module="0123",
+ obj="",
+ line=1,
+ column=0,
+ end_line=None,
+ end_column=None,
),
)
assert linter.reporter.messages[1] == Message(
@@ -512,7 +519,14 @@ def test_addmessage(linter: PyLinter) -> None:
description="Warning without any associated confidence level.",
),
location=MessageLocationTuple(
- abspath="0123", path="0123", module="0123", obj="", line=2, column=0
+ abspath="0123",
+ path="0123",
+ module="0123",
+ obj="",
+ line=2,
+ column=0,
+ end_line=None,
+ end_column=None,
),
)
@@ -616,6 +630,8 @@ def test_analyze_explicit_script(linter: PyLinter) -> None:
obj="",
line=2,
column=0,
+ end_line=None,
+ end_column=None,
),
)
diff --git a/tests/message/unittest_message.py b/tests/message/unittest_message.py
index 321453150..64cadf91a 100644
--- a/tests/message/unittest_message.py
+++ b/tests/message/unittest_message.py
@@ -34,6 +34,8 @@ def test_new_message(message_definitions: ValuesView[MessageDefinition]) -> None
obj="4",
line=5,
column=6,
+ end_line=5,
+ end_column=9,
)
w1234_location_values = MessageLocationTuple(
abspath="7",
@@ -42,6 +44,8 @@ def test_new_message(message_definitions: ValuesView[MessageDefinition]) -> None
obj="10",
line=11,
column=12,
+ end_line=11,
+ end_column=14,
)
expected = (
"2:5:6: E1234: Duplicate keyword argument %r in %s call (duplicate-keyword-arg)"
diff --git a/tests/testutils/test_output_line.py b/tests/testutils/test_output_line.py
index d13db4978..928083508 100644
--- a/tests/testutils/test_output_line.py
+++ b/tests/testutils/test_output_line.py
@@ -21,12 +21,7 @@ def message() -> Callable:
symbol="missing-docstring",
msg_id="C0123",
location=MessageLocationTuple(
- "abspath",
- "path",
- "module",
- "obj",
- 1,
- 2,
+ "abspath", "path", "module", "obj", 1, 2, 1, 3
),
msg="msg",
confidence=confidence,