Skip to content

Commit ee70d41

Browse files
authored
Add end_lineno and end_col_offset to MessageLocationTuple (#5343)
1 parent e4fd275 commit ee70d41

File tree

8 files changed

+79
-16
lines changed

8 files changed

+79
-16
lines changed

pylint/checkers/base_checker.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,12 @@ def add_message(
116116
args: Any = None,
117117
confidence: Optional[Confidence] = None,
118118
col_offset: Optional[int] = None,
119+
end_lineno: Optional[int] = None,
120+
end_col_offset: Optional[int] = None,
119121
) -> None:
120-
self.linter.add_message(msgid, line, node, args, confidence, col_offset)
122+
self.linter.add_message(
123+
msgid, line, node, args, confidence, col_offset, end_lineno, end_col_offset
124+
)
121125

122126
def check_consistency(self):
123127
"""Check the consistency of msgid.

pylint/lint/pylinter.py

+38-6
Original file line numberDiff line numberDiff line change
@@ -1413,14 +1413,30 @@ def _add_one_message(
14131413
args: Optional[Any],
14141414
confidence: Optional[interfaces.Confidence],
14151415
col_offset: Optional[int],
1416+
end_lineno: Optional[int],
1417+
end_col_offset: Optional[int],
14161418
) -> None:
14171419
"""After various checks have passed a single Message is
14181420
passed to the reporter and added to stats"""
14191421
message_definition.check_message_definition(line, node)
1420-
if line is None and node is not None:
1421-
line = node.fromlineno
1422-
if col_offset is None and hasattr(node, "col_offset"):
1423-
col_offset = node.col_offset # type: ignore[union-attr]
1422+
1423+
# Look up "location" data of node if not yet supplied
1424+
if node:
1425+
if not line:
1426+
line = node.fromlineno
1427+
# pylint: disable=fixme
1428+
# TODO: Initialize col_offset on every node (can be None) -> astroid
1429+
if not col_offset and hasattr(node, "col_offset"):
1430+
col_offset = node.col_offset
1431+
# pylint: disable=fixme
1432+
# TODO: Initialize end_lineno on every node (can be None) -> astroid
1433+
# See https://github.com/PyCQA/astroid/issues/1273
1434+
if not end_lineno and hasattr(node, "end_lineno"):
1435+
end_lineno = node.end_lineno
1436+
# pylint: disable=fixme
1437+
# TODO: Initialize end_col_offset on every node (can be None) -> astroid
1438+
if not end_col_offset and hasattr(node, "end_col_offset"):
1439+
end_col_offset = node.end_col_offset
14241440

14251441
# should this message be displayed
14261442
if not self.is_message_enabled(message_definition.msgid, line, confidence):
@@ -1463,7 +1479,14 @@ def _add_one_message(
14631479
message_definition.msgid,
14641480
message_definition.symbol,
14651481
MessageLocationTuple(
1466-
abspath, path, module or "", obj, line or 1, col_offset or 0
1482+
abspath,
1483+
path,
1484+
module or "",
1485+
obj,
1486+
line or 1,
1487+
col_offset or 0,
1488+
end_lineno,
1489+
end_col_offset,
14671490
),
14681491
msg,
14691492
confidence,
@@ -1478,6 +1501,8 @@ def add_message(
14781501
args: Optional[Any] = None,
14791502
confidence: Optional[interfaces.Confidence] = None,
14801503
col_offset: Optional[int] = None,
1504+
end_lineno: Optional[int] = None,
1505+
end_col_offset: Optional[int] = None,
14811506
) -> None:
14821507
"""Adds a message given by ID or name.
14831508
@@ -1492,7 +1517,14 @@ def add_message(
14921517
message_definitions = self.msgs_store.get_message_definitions(msgid)
14931518
for message_definition in message_definitions:
14941519
self._add_one_message(
1495-
message_definition, line, node, args, confidence, col_offset
1520+
message_definition,
1521+
line,
1522+
node,
1523+
args,
1524+
confidence,
1525+
col_offset,
1526+
end_lineno,
1527+
end_col_offset,
14961528
)
14971529

14981530
def add_ignored_message(

pylint/message/message.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
"obj",
2626
"line",
2727
"column",
28+
"end_line",
29+
"end_column",
2830
],
2931
)
3032

@@ -59,7 +61,10 @@ def __new__(
5961
cls,
6062
msg_id: str,
6163
symbol: str,
62-
location: Union[Tuple[str, str, str, str, int, int], MessageLocationTuple],
64+
location: Union[
65+
Tuple[str, str, str, str, int, int],
66+
MessageLocationTuple,
67+
],
6368
msg: str,
6469
confidence: Optional[Confidence],
6570
) -> "Message":
@@ -68,6 +73,7 @@ def __new__(
6873
"In pylint 3.0, Messages will only accept a MessageLocationTuple as location parameter",
6974
DeprecationWarning,
7075
)
76+
location = location + (None, None) # type: ignore[assignment] # Temporary fix until deprecation
7177
return _MsgBase.__new__(
7278
cls,
7379
msg_id,

pylint/testutils/unittest_linter.py

+4
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@ def add_message(
3434
args: Any = None,
3535
confidence: Optional[Confidence] = None,
3636
col_offset: Optional[int] = None,
37+
end_lineno: Optional[int] = None,
38+
end_col_offset: Optional[int] = None,
3739
) -> None:
3840
# Do not test col_offset for now since changing Message breaks everything
41+
# pylint: disable=fixme
42+
# TODO: Test end_lineno and end_col_offset :)
3943
self._messages.append(MessageTest(msg_id, line, node, args, confidence))
4044

4145
@staticmethod

pylint/typing.py

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class MessageLocationTuple(NamedTuple):
5252
obj: str
5353
line: int
5454
column: int
55+
end_line: Optional[int] = None
56+
end_column: Optional[int] = None
5557

5658

5759
class ManagedMessage(NamedTuple):

tests/lint/unittest_lint.py

+18-2
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,14 @@ def test_addmessage(linter: PyLinter) -> None:
500500
description="Warning without any associated confidence level.",
501501
),
502502
location=MessageLocationTuple(
503-
abspath="0123", path="0123", module="0123", obj="", line=1, column=0
503+
abspath="0123",
504+
path="0123",
505+
module="0123",
506+
obj="",
507+
line=1,
508+
column=0,
509+
end_line=None,
510+
end_column=None,
504511
),
505512
)
506513
assert linter.reporter.messages[1] == Message(
@@ -512,7 +519,14 @@ def test_addmessage(linter: PyLinter) -> None:
512519
description="Warning without any associated confidence level.",
513520
),
514521
location=MessageLocationTuple(
515-
abspath="0123", path="0123", module="0123", obj="", line=2, column=0
522+
abspath="0123",
523+
path="0123",
524+
module="0123",
525+
obj="",
526+
line=2,
527+
column=0,
528+
end_line=None,
529+
end_column=None,
516530
),
517531
)
518532

@@ -616,6 +630,8 @@ def test_analyze_explicit_script(linter: PyLinter) -> None:
616630
obj="",
617631
line=2,
618632
column=0,
633+
end_line=None,
634+
end_column=None,
619635
),
620636
)
621637

tests/message/unittest_message.py

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ def build_message(
3434
obj="4",
3535
line=5,
3636
column=6,
37+
end_line=5,
38+
end_column=9,
3739
)
3840
w1234_location_values = MessageLocationTuple(
3941
abspath="7",
@@ -42,6 +44,8 @@ def build_message(
4244
obj="10",
4345
line=11,
4446
column=12,
47+
end_line=11,
48+
end_column=14,
4549
)
4650
expected = (
4751
"2:5:6: E1234: Duplicate keyword argument %r in %s call (duplicate-keyword-arg)"

tests/testutils/test_output_line.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,7 @@ def inner(confidence: Confidence = HIGH) -> Message:
2121
symbol="missing-docstring",
2222
msg_id="C0123",
2323
location=MessageLocationTuple(
24-
"abspath",
25-
"path",
26-
"module",
27-
"obj",
28-
1,
29-
2,
24+
"abspath", "path", "module", "obj", 1, 2, 1, 3
3025
),
3126
msg="msg",
3227
confidence=confidence,

0 commit comments

Comments
 (0)