From 90182240ec239ff0d811c55fea2e08714a46455d Mon Sep 17 00:00:00 2001 From: wyattscarpenter Date: Fri, 26 Sep 2025 18:25:09 -0700 Subject: [PATCH 1/3] fix a string backslash usages mistake, which also exposes the whitespace problem in the test --- mypy/test/meta/test_update_data.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mypy/test/meta/test_update_data.py b/mypy/test/meta/test_update_data.py index 820fd359893e..960f8c77e36d 100644 --- a/mypy/test/meta/test_update_data.py +++ b/mypy/test/meta/test_update_data.py @@ -21,7 +21,7 @@ def test_update_data(self) -> None: # Note: We test multiple testcases rather than 'test case per test case' # so we could also exercise rewriting multiple testcases at once. result = _run_pytest_update_data( - """ + r""" [case testCorrect] s: str = 42 # E: Incompatible types in assignment (expression has type "int", variable has type "str") @@ -79,7 +79,7 @@ def test_update_data(self) -> None: # Assert expected = dedent_docstring( - """ + r""" [case testCorrect] s: str = 42 # E: Incompatible types in assignment (expression has type "int", variable has type "str") @@ -93,7 +93,7 @@ def test_update_data(self) -> None: s: str = 42 # E: Incompatible types in assignment (expression has type "int", variable has type "str") [case testMissingMultiline] - s: str = 42; i: int = 'foo' # E: Incompatible types in assignment (expression has type "int", variable has type "str") \\ + s: str = 42; i: int = 'foo' # E: Incompatible types in assignment (expression has type "int", variable has type "str") \ # E: Incompatible types in assignment (expression has type "str", variable has type "int") [case testExtraneous] From 505694481906c7c51a867188ef943a9f205ea393 Mon Sep 17 00:00:00 2001 From: wyattscarpenter Date: Sat, 27 Sep 2025 08:47:10 -0700 Subject: [PATCH 2/3] test and documentation changes --- mypy/test/data.py | 2 +- mypy/test/meta/test_update_data.py | 32 ++++++++++++++++++++++++++++++ mypy/test/update_data.py | 16 ++++++++------- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/mypy/test/data.py b/mypy/test/data.py index 5b0ad84c0ba7..fab201d7cc59 100644 --- a/mypy/test/data.py +++ b/mypy/test/data.py @@ -445,7 +445,7 @@ def trimmed_newlines(self) -> int: # compensates for strip_list def parse_test_data(raw_data: str, name: str) -> list[TestItem]: - """Parse a list of lines that represent a sequence of test items.""" + """Parse a multi-line text that represents a sequence of test items in a single test case.""" lines = ["", "[case " + name + "]"] + raw_data.split("\n") ret: list[TestItem] = [] diff --git a/mypy/test/meta/test_update_data.py b/mypy/test/meta/test_update_data.py index 960f8c77e36d..383d8c7b7bbf 100644 --- a/mypy/test/meta/test_update_data.py +++ b/mypy/test/meta/test_update_data.py @@ -49,11 +49,27 @@ def test_update_data(self) -> None: s: str = 'foo' # W: foo \ # N: bar + [case testIndentationOfMultiline] + s: str = 42; i: int = 'foo' # E: Incompatible types in assignment (expression has type "int", variable has type "str")\ + # E: Incompatible types in assignment (expression has type "int", variable has type "str") + s2: str = 42; i2: int = 'foo' # E: Incompatible types in assignment (expression has type "int", variable has type "str")\ + # E: Incompatible types in assignment (expression has type "int", variable has type "str") + [case testOutCorrect] s: str = 42 [out] main:1: error: Incompatible types in assignment (expression has type "int", variable has type "str") + [case testOutWithMuchTraillingWhitespace] + s: str = 42 + [out] + main:1: error: Incompatible types in assignment (expression has type "int", variable has type "str") + + + + + + [case testOutWrong] s: str = 42 [out] @@ -105,11 +121,27 @@ def test_update_data(self) -> None: [case testExtraneousMultilineNonError] s: str = 'foo' + [case testIndentationOfMultiline] + s: str = 42; i: int = 'foo' # E: Incompatible types in assignment (expression has type "int", variable has type "str") \ + # E: Incompatible types in assignment (expression has type "str", variable has type "int") + s2: str = 42; i2: int = 'foo' # E: Incompatible types in assignment (expression has type "int", variable has type "str") \ + # E: Incompatible types in assignment (expression has type "str", variable has type "int") + [case testOutCorrect] s: str = 42 [out] main:1: error: Incompatible types in assignment (expression has type "int", variable has type "str") + [case testOutWithMuchTraillingWhitespace] + s: str = 42 + [out] + main:1: error: Incompatible types in assignment (expression has type "int", variable has type "str") + + + + + + [case testOutWrong] s: str = 42 [out] diff --git a/mypy/test/update_data.py b/mypy/test/update_data.py index 84b6383b3f0c..e26c6610b7c7 100644 --- a/mypy/test/update_data.py +++ b/mypy/test/update_data.py @@ -63,17 +63,19 @@ def _iter_fixes( fix_lines = [] for lineno, source_line in enumerate(source_lines, start=1): - reports = reports_by_line.get((file_path, lineno)) + reports_on_this_line = reports_by_line.get((file_path, lineno)) comment_match = re.search(r"(?P\s+)(?P# [EWN]: .+)$", source_line) if comment_match: source_line = source_line[: comment_match.start("indent")] # strip old comment - if reports: + if reports_on_this_line: indent = comment_match.group("indent") if comment_match else " " - # multiline comments are on the first line and then on subsequent lines empty lines - # with a continuation backslash - for j, (severity, msg) in enumerate(reports): - out_l = source_line if j == 0 else " " * len(source_line) - is_last = j == len(reports) - 1 + # Multiple info reports for the same line are represented in these + # comments with the first on the relevant line, then the subsequent + # ones on subsequent empty (indented) lines + # using continuation backslashes + for i, (severity, msg) in enumerate(reports_on_this_line): + out_l = source_line if i == 0 else " " * len(source_line) + is_last = (i == len(reports_on_this_line) - 1) severity_char = severity[0].upper() continuation = "" if is_last else " \\" fix_lines.append(f"{out_l}{indent}# {severity_char}: {msg}{continuation}") From 791ee52e82f47ed4f6b0d2b6e12c018383f05459 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 27 Sep 2025 15:53:48 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/test/update_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/test/update_data.py b/mypy/test/update_data.py index e26c6610b7c7..c3f02641aae2 100644 --- a/mypy/test/update_data.py +++ b/mypy/test/update_data.py @@ -75,7 +75,7 @@ def _iter_fixes( # using continuation backslashes for i, (severity, msg) in enumerate(reports_on_this_line): out_l = source_line if i == 0 else " " * len(source_line) - is_last = (i == len(reports_on_this_line) - 1) + is_last = i == len(reports_on_this_line) - 1 severity_char = severity[0].upper() continuation = "" if is_last else " \\" fix_lines.append(f"{out_l}{indent}# {severity_char}: {msg}{continuation}")