From b4569fa411ebce01b11d5da47585a5c25083505c Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Sat, 4 Mar 2023 17:38:50 +0000 Subject: [PATCH 1/8] Add test to demonstrate issue #9655 This test currently fails with this error: AssertionError: Command 3 (dmypy check -- bar.py) did not give expected output --- Captured stderr call --- Expected: bar.py:2: error: Unused "type: ignore" comment (diff) == Return code: 1 (diff) Actual: (empty) It demonstrates a bug that when an module is removed using `FineGrainedBuildManager.update` because it is not "seen" by `fine_grained_increment_follow_imports`, then "unused type: ignore" warnings disappear from subsequent checks. Ref: https://github.com/python/mypy/issues/9655 --- test-data/unit/daemon.test | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index 7586c8763d33..6753bc414ccc 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -522,3 +522,20 @@ class A: x: int class B: x: int + +[case testUnusedTypeIgnorePreservedAfterUpdate] +-- Regression test for https://github.com/python/mypy/issues/9655 +$ dmypy start -- --warn-unused-ignores --no-error-summary +Daemon started +$ dmypy check -- bar.py +bar.py:2: error: Unused "type: ignore" comment +== Return code: 1 +$ dmypy check -- bar.py +bar.py:2: error: Unused "type: ignore" comment +== Return code: 1 + +[file foo/__init__.py] +[file foo/empty.py] +[file bar.py] +from foo.empty import * +a = 1 # type: ignore From 1831cbd5e642892361252e731f1c242b20bc62dd Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Sun, 12 Mar 2023 22:23:51 +0000 Subject: [PATCH 2/8] Prove ignores without error codes also disappear This test fails with the error: AssertionError: Command 3 (dmypy check -- bar.py) did not give expected output --- Captured stderr call --- Expected: bar.py:2: error: "type: ignore" comment without error code [ignore-without-code] (diff) == Return code: 1 (diff) Actual: (empty) This test illustrates that '"type: ignore" comment without error code' errors currently disappear in the same way that 'Unused "type: ignore"' errors do as described in #9655. Ref: https://github.com/python/mypy/issues/9655 --- test-data/unit/daemon.test | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index 6753bc414ccc..dcc7ec86309f 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -539,3 +539,20 @@ bar.py:2: error: Unused "type: ignore" comment [file bar.py] from foo.empty import * a = 1 # type: ignore + +[case testTypeIgnoreWithoutCodePreservedAfterUpdate] +-- Regression test for https://github.com/python/mypy/issues/9655 +$ dmypy start -- --enable-error-code ignore-without-code --no-error-summary +Daemon started +$ dmypy check -- bar.py +bar.py:2: error: "type: ignore" comment without error code [ignore-without-code] +== Return code: 1 +$ dmypy check -- bar.py +bar.py:2: error: "type: ignore" comment without error code [ignore-without-code] +== Return code: 1 + +[file foo/__init__.py] +[file foo/empty.py] +[file bar.py] +from foo.empty import * +a = 1 # type: ignore From 6094fc46d12904eaec42c3e622645551b549e7e5 Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Sun, 12 Mar 2023 23:25:29 +0000 Subject: [PATCH 3/8] Prove possibly-undefined errors disappear This test fails with the error: AssertionError: Command 3 (dmypy check -- bar.py) did not give expected output --- Captured stderr call --- Expected: bar.py:4: error: Name "a" may be undefined [possibly-undefined] (diff) == Return code: 1 (diff) Actual: (empty) This test illustrates that possibly-undefined errors currently disappear in the same way that 'Unused "type: ignore"' errors do as described in #9655. Ref: https://github.com/python/mypy/issues/9655 --- test-data/unit/daemon.test | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index dcc7ec86309f..d4ec103db881 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -556,3 +556,22 @@ bar.py:2: error: "type: ignore" comment without error code [ignore-without-code [file bar.py] from foo.empty import * a = 1 # type: ignore + +[case testPossiblyUndefinedVarsPreservedAfterUpdate] +-- Regression test for https://github.com/python/mypy/issues/9655 +$ dmypy start -- --enable-error-code possibly-undefined --no-error-summary +Daemon started +$ dmypy check -- bar.py +bar.py:4: error: Name "a" may be undefined [possibly-undefined] +== Return code: 1 +$ dmypy check -- bar.py +bar.py:4: error: Name "a" may be undefined [possibly-undefined] +== Return code: 1 + +[file foo/__init__.py] +[file foo/empty.py] +[file bar.py] +from foo.empty import * +if False: + a = 1 +a From eac851bb6560df1bd2953aee46bd4a4c856e830a Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Mon, 13 Mar 2023 00:13:07 +0000 Subject: [PATCH 4/8] Ensure errors persist after dmypy update Before this change, if a module was removed with `update` in the `FineGrainedBuildManager`, then some errors would not re-appear. This change ensures that three types of error are maintained when running `reprocess_nodes`: - possibly undefined vars - unused ignores - ignores without codes By adding targets to ErrorInfos, this also fixes an issue where unused ignore and ignores without codes errors didn't get re-processed when they were the only issue in the file. Fixes #9655 --- mypy/errors.py | 4 ++++ mypy/server/update.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/mypy/errors.py b/mypy/errors.py index 2c2c1e5ca227..03eb4a6adf21 100644 --- a/mypy/errors.py +++ b/mypy/errors.py @@ -668,6 +668,8 @@ def generate_unused_ignore_errors(self, file: str) -> None: False, False, False, + origin=(self.file, [line]), + target=self.target_module, ) self._add_error_info(file, info) @@ -720,6 +722,8 @@ def generate_ignore_without_code_errors( False, False, False, + origin=(self.file, [line]), + target=self.target_module, ) self._add_error_info(file, info) diff --git a/mypy/server/update.py b/mypy/server/update.py index 00b823c99dfd..d87e44b97863 100644 --- a/mypy/server/update.py +++ b/mypy/server/update.py @@ -1027,6 +1027,10 @@ def key(node: FineGrainedDeferredNode) -> int: if graph[module_id].type_checker().check_second_pass(): more = True + graph[module_id].detect_possibly_undefined_vars() + graph[module_id].generate_unused_ignore_notes() + graph[module_id].generate_ignore_without_code_notes() + if manager.options.export_types: manager.all_types.update(graph[module_id].type_map()) From 5bfb6b57c4fa169e6c5b73c8c402db7893a3663a Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Fri, 31 Mar 2023 23:28:56 +0100 Subject: [PATCH 5/8] Improve test names There aren't any updates in these tests, we just re-run dmypy. --- test-data/unit/daemon.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index d4ec103db881..6dd416b1a1a0 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -523,7 +523,7 @@ class A: class B: x: int -[case testUnusedTypeIgnorePreservedAfterUpdate] +[case testUnusedTypeIgnorePreservedOnRerun] -- Regression test for https://github.com/python/mypy/issues/9655 $ dmypy start -- --warn-unused-ignores --no-error-summary Daemon started @@ -540,7 +540,7 @@ bar.py:2: error: Unused "type: ignore" comment from foo.empty import * a = 1 # type: ignore -[case testTypeIgnoreWithoutCodePreservedAfterUpdate] +[case testTypeIgnoreWithoutCodePreservedOnRerun] -- Regression test for https://github.com/python/mypy/issues/9655 $ dmypy start -- --enable-error-code ignore-without-code --no-error-summary Daemon started From 3d8d2b7275dd9ce6e72b7ee5262ce07f1af59550 Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Fri, 31 Mar 2023 23:30:08 +0100 Subject: [PATCH 6/8] Add new failing tests These tests show how some errors disappear on a re-run of dmypy after a file is altered. --- test-data/unit/daemon.test | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index 6dd416b1a1a0..34d1b2b9218d 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -557,6 +557,42 @@ bar.py:2: error: "type: ignore" comment without error code [ignore-without-code from foo.empty import * a = 1 # type: ignore +[case testUnusedTypeIgnorePreservedAfterChange] +-- Regression test for https://github.com/python/mypy/issues/9655 +$ dmypy start -- --warn-unused-ignores --no-error-summary +Daemon started +$ dmypy check -- bar.py +bar.py:2: error: Unused "type: ignore" comment +== Return code: 1 +$ echo '' >> bar.py +$ dmypy check -- bar.py +bar.py:2: error: Unused "type: ignore" comment +== Return code: 1 + +[file foo/__init__.py] +[file foo/empty.py] +[file bar.py] +from foo.empty import * +a = 1 # type: ignore + +[case testTypeIgnoreWithoutCodePreservedAfterChange] +-- Regression test for https://github.com/python/mypy/issues/9655 +$ dmypy start -- --enable-error-code ignore-without-code --no-error-summary +Daemon started +$ dmypy check -- bar.py +bar.py:2: error: "type: ignore" comment without error code [ignore-without-code] +== Return code: 1 +$ echo '' >> bar.py +$ dmypy check -- bar.py +bar.py:2: error: "type: ignore" comment without error code [ignore-without-code] +== Return code: 1 + +[file foo/__init__.py] +[file foo/empty.py] +[file bar.py] +from foo.empty import * +a = 1 # type: ignore + [case testPossiblyUndefinedVarsPreservedAfterUpdate] -- Regression test for https://github.com/python/mypy/issues/9655 $ dmypy start -- --enable-error-code possibly-undefined --no-error-summary From 520f8e81f1d24d96d1349d7d0aa20daee50c585c Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Sat, 8 Apr 2023 22:36:56 +0100 Subject: [PATCH 7/8] Ensure errors persist after file change Before this change, when a module was changed, some errors would not re-appear. This change ensures that unused-ignore and ignore-without-code errors are maintained when a module is re-analyzed after it changes. --- mypy/server/update.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mypy/server/update.py b/mypy/server/update.py index d87e44b97863..e909840d2757 100644 --- a/mypy/server/update.py +++ b/mypy/server/update.py @@ -667,6 +667,8 @@ def restore(ids: list[str]) -> None: state.type_check_first_pass() state.type_check_second_pass() state.detect_possibly_undefined_vars() + state.generate_unused_ignore_notes() + state.generate_ignore_without_code_notes() t2 = time.time() state.finish_passes() t3 = time.time() From 6c14e7db851a956142c80287c8992cd8cb314e4f Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Sun, 9 Apr 2023 18:45:17 +0100 Subject: [PATCH 8/8] Fix no-op file modification on Windows Before this change, tests failed because the way we modified a file with echoing didn't work the same way on windows. This change uses Python to print a newline to the end of the file, which doesn't run afoul of the same issues with newlines. Co-authored-by: AlexWaygood --- test-data/unit/daemon.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index 34d1b2b9218d..869f60b4e1fd 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -564,7 +564,7 @@ Daemon started $ dmypy check -- bar.py bar.py:2: error: Unused "type: ignore" comment == Return code: 1 -$ echo '' >> bar.py +$ {python} -c "print('\n')" >> bar.py $ dmypy check -- bar.py bar.py:2: error: Unused "type: ignore" comment == Return code: 1 @@ -582,7 +582,7 @@ Daemon started $ dmypy check -- bar.py bar.py:2: error: "type: ignore" comment without error code [ignore-without-code] == Return code: 1 -$ echo '' >> bar.py +$ {python} -c "print('\n')" >> bar.py $ dmypy check -- bar.py bar.py:2: error: "type: ignore" comment without error code [ignore-without-code] == Return code: 1 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy