From c9fe2c38c61287f808307dd901f6d8f64d456949 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Sat, 28 Oct 2023 18:37:10 +0100 Subject: [PATCH 1/2] Fix dmypy inspect on Windows --- mypy/inspections.py | 24 ++++++++++++++++-------- mypy/test/testutil.py | 5 +++++ test-data/unit/daemon.test | 3 +++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/mypy/inspections.py b/mypy/inspections.py index cb695a80eef2..e3fad033d904 100644 --- a/mypy/inspections.py +++ b/mypy/inspections.py @@ -219,13 +219,6 @@ def __init__( # Module for which inspection was requested. self.module: State | None = None - def parse_location(self, location: str) -> tuple[str, list[int]]: - if location.count(":") not in [2, 4]: - raise ValueError("Format should be file:line:column[:end_line:end_column]") - parts = location.split(":") - module, *rest = parts - return module, [int(p) for p in rest] - def reload_module(self, state: State) -> None: """Reload given module while temporary exporting types.""" old = self.fg_manager.manager.options.export_types @@ -581,7 +574,7 @@ def run_inspection( This can be re-used by various simple inspections. """ try: - file, pos = self.parse_location(location) + file, pos = parse_location(location) except ValueError as err: return {"error": str(err)} @@ -623,3 +616,18 @@ def get_definition(self, location: str) -> dict[str, object]: result["out"] = f"No name or member expressions at {location}" result["status"] = 1 return result + + +def parse_location(location: str) -> tuple[str, list[int]]: + if location.count(":") < 2: + raise ValueError("Format should be file:line:column[:end_line:end_column]") + parts = location.rsplit(":", maxsplit=2) + start, *rest = parts + # Note: we must allow drive prefix like `C:` on Windows. + if start.count(":") < 2: + return start, [int(p) for p in rest] + parts = start.rsplit(":", maxsplit=2) + start, *start_rest = parts + if start.count(":") < 2: + return start, [int(p) for p in start_rest + rest] + raise ValueError("Format should be file:line:column[:end_line:end_column]") diff --git a/mypy/test/testutil.py b/mypy/test/testutil.py index 89184b11a826..f861083f994a 100644 --- a/mypy/test/testutil.py +++ b/mypy/test/testutil.py @@ -4,6 +4,7 @@ from unittest import TestCase, mock from mypy.util import get_terminal_width +from mypy.inspections import parse_location class TestGetTerminalSize(TestCase): @@ -15,3 +16,7 @@ def test_get_terminal_size_in_pty_defaults_to_80(self) -> None: with mock.patch.object(os, "get_terminal_size", return_value=ret): with mock.patch.dict(os.environ, values=mock_environ, clear=True): assert get_terminal_width() == 80 + + def test_parse_location_windows(self) -> None: + assert parse_location(r"C:\test.py:1:1") == (r"C:\test.py", [1, 1]) + assert parse_location(r"C:\test.py:1:1:1:1") == (r"C:\test.py", [1, 1, 1, 1]) diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index 18a03a92207d..61dc345e2c49 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -372,6 +372,9 @@ foo.py:3: error: Incompatible types in assignment (expression has type "str", va $ dmypy inspect foo:1 Format should be file:line:column[:end_line:end_column] == Return code: 2 +$ dmypy inspect foo:1:2:3 +Source file is not a Python file +== Return code: 2 $ dmypy inspect foo.py:1:2:a:b invalid literal for int() with base 10: 'a' == Return code: 2 From e303a257ddc2bc193bd3ee3b01bd3b8bca62ac00 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 28 Oct 2023 17:41:03 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/test/testutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/test/testutil.py b/mypy/test/testutil.py index f861083f994a..571e4d0b11f2 100644 --- a/mypy/test/testutil.py +++ b/mypy/test/testutil.py @@ -3,8 +3,8 @@ import os from unittest import TestCase, mock -from mypy.util import get_terminal_width from mypy.inspections import parse_location +from mypy.util import get_terminal_width class TestGetTerminalSize(TestCase):