From ba06eb51b1f694d3eeee64fe0e076cfd1fbec4d0 Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Fri, 28 Mar 2025 14:14:47 -0400 Subject: [PATCH 1/2] Warn about unused `type: ignore` comments when error code is disabled --- mypy/errors.py | 9 ++++++--- test-data/unit/check-errorcodes.test | 5 +++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/mypy/errors.py b/mypy/errors.py index 58ef17b69e96..c9510ae5f1eb 100644 --- a/mypy/errors.py +++ b/mypy/errors.py @@ -506,10 +506,13 @@ def add_error_info(self, info: ErrorInfo) -> None: # line == end_line for most nodes, so we only loop once. for scope_line in lines: if self.is_ignored_error(scope_line, info, self.ignored_lines[file]): + err_code = info.code or codes.MISC + if not self.is_error_code_enabled(err_code): + # Error code is disabled - don't mark the current + # "type: ignore" comment as used. + return # Annotation requests us to ignore all errors on this line. - self.used_ignored_lines[file][scope_line].append( - (info.code or codes.MISC).code - ) + self.used_ignored_lines[file][scope_line].append(err_code.code) return if file in self.ignored_files: return diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 6ec246fb3a13..aade71871caa 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -105,6 +105,11 @@ x # type: ignore[name-defined, attr-defined] # E: Unused "type: ignore[attr-defi # flags: --warn-unused-ignores "x" # type: ignore[name-defined] # E: Unused "type: ignore" comment [unused-ignore] +[case testErrorCodeWarnUnusedIgnores7_WarnWhenErrorCodeDisabled] +# flags: --warn-unused-ignores --disable-error-code name-defined +x # type: ignore[name-defined] # E: Unused "type: ignore" comment [unused-ignore] +"x".foobar(y) # type: ignore[name-defined, attr-defined] # E: Unused "type: ignore[name-defined]" comment [unused-ignore] + [case testErrorCodeMissingWhenRequired] # flags: --enable-error-code ignore-without-code "x" # type: ignore # E: "type: ignore" comment without error code [ignore-without-code] From 73115d91cfe74e61484f2624063ac12f72e08751 Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Sun, 30 Mar 2025 17:12:38 -0400 Subject: [PATCH 2/2] Add test cases for "type: ignore[unused-ignore]" interaction --- test-data/unit/check-errorcodes.test | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index aade71871caa..21112b7d85a2 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -107,9 +107,17 @@ x # type: ignore[name-defined, attr-defined] # E: Unused "type: ignore[attr-defi [case testErrorCodeWarnUnusedIgnores7_WarnWhenErrorCodeDisabled] # flags: --warn-unused-ignores --disable-error-code name-defined +x # type: ignore # E: Unused "type: ignore" comment [unused-ignore] x # type: ignore[name-defined] # E: Unused "type: ignore" comment [unused-ignore] "x".foobar(y) # type: ignore[name-defined, attr-defined] # E: Unused "type: ignore[name-defined]" comment [unused-ignore] +[case testErrorCodeWarnUnusedIgnores8_IgnoreUnusedIgnore] +# flags: --warn-unused-ignores --disable-error-code name-defined +"x" # type: ignore[unused-ignore] +"x" # type: ignore[name-defined, unused-ignore] +"x" # type: ignore[xyz, unused-ignore] +x # type: ignore[name-defined, unused-ignore] + [case testErrorCodeMissingWhenRequired] # flags: --enable-error-code ignore-without-code "x" # type: ignore # E: "type: ignore" comment without error code [ignore-without-code]