diff --git a/mypy/errors.py b/mypy/errors.py index f1b2faf67401..47969d1c64af 100644 --- a/mypy/errors.py +++ b/mypy/errors.py @@ -645,7 +645,7 @@ def add_error_info(self, info: ErrorInfo) -> None: if ignored_codes and info.code: # Something is ignored on the line, but not this error, so maybe the error # code is incorrect. - msg = f'Error code "{info.code.code}" not covered by "type: ignore" comment' + msg = f"""Error code "{info.code.code}" not covered by "type: ignore[{', '.join(ignored_codes)}]" comment""" if info.code in original_error_codes: # If there seems to be a "type: ignore" with a stale error # code, report a more specific note. diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index bb5f658ebb50..99f8f76b6ae2 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -60,26 +60,28 @@ for v in x: # type: int, int # type: ignore[syntax] [case testErrorCodeIgnore1] 'x'.foobar # type: ignore[attr-defined] 'x'.foobar # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] \ - # N: Error code "attr-defined" not covered by "type: ignore" comment + # N: Error code "attr-defined" not covered by "type: ignore[xyz]" comment 'x'.foobar # type: ignore [case testErrorCodeIgnore2] a = 'x'.foobar # type: int # type: ignore[attr-defined] b = 'x'.foobar # type: int # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] \ - # N: Error code "attr-defined" not covered by "type: ignore" comment + # N: Error code "attr-defined" not covered by "type: ignore[xyz]" comment c = 'x'.foobar # type: int # type: ignore [case testErrorCodeIgnoreMultiple1] a = 'x'.foobar(b) # type: ignore[name-defined, attr-defined] a = 'x'.foobar(b) # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] \ - # N: Error code "attr-defined" not covered by "type: ignore" comment + # N: Error code "attr-defined" not covered by "type: ignore[name-defined, xyz]" comment a = 'x'.foobar(b) # type: ignore[xyz, w, attr-defined] # E: Name "b" is not defined [name-defined] \ - # N: Error code "name-defined" not covered by "type: ignore" comment + # N: Error code "name-defined" not covered by "type: ignore[xyz, w, attr-defined]" comment +a = 'x'.foobar(b) # type: ignore[ w, xyz, attr-defined] # E: Name "b" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore[w, xyz, attr-defined]" comment [case testErrorCodeIgnoreMultiple2] a = 'x'.foobar(c) # type: int # type: ignore[name-defined, attr-defined] b = 'x'.foobar(c) # type: int # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] \ - # N: Error code "attr-defined" not covered by "type: ignore" comment + # N: Error code "attr-defined" not covered by "type: ignore[name-defined, xyz]" comment [case testErrorCodeWarnUnusedIgnores1] # flags: --warn-unused-ignores @@ -131,7 +133,7 @@ z # type: ignore[name-defined] "y" # type: ignore[ignore-without-code] # E: Unused "type: ignore" comment [unused-ignore] z # type: ignore[ignore-without-code] # E: Unused "type: ignore" comment [unused-ignore] \ # E: Name "z" is not defined [name-defined] \ - # N: Error code "name-defined" not covered by "type: ignore" comment + # N: Error code "name-defined" not covered by "type: ignore[ignore-without-code]" comment [case testErrorCodeMissingWholeFileIgnores] # flags: --enable-error-code ignore-without-code @@ -157,21 +159,21 @@ x2 # type: ignore [ name-defined ] x3 # type: ignore [ xyz , name-defined ] x4 # type: ignore[xyz,name-defined] y # type: ignore [xyz] # E: Name "y" is not defined [name-defined] \ - # N: Error code "name-defined" not covered by "type: ignore" comment + # N: Error code "name-defined" not covered by "type: ignore[xyz]" comment y # type: ignore[ xyz ] # E: Name "y" is not defined [name-defined] \ - # N: Error code "name-defined" not covered by "type: ignore" comment + # N: Error code "name-defined" not covered by "type: ignore[xyz]" comment y # type: ignore[ xyz , foo ] # E: Name "y" is not defined [name-defined] \ - # N: Error code "name-defined" not covered by "type: ignore" comment + # N: Error code "name-defined" not covered by "type: ignore[xyz, foo]" comment a = z # type: int # type: ignore [name-defined] b = z2 # type: int # type: ignore [ name-defined ] c = z2 # type: int # type: ignore [ name-defined , xyz ] d = zz # type: int # type: ignore [xyz] # E: Name "zz" is not defined [name-defined] \ - # N: Error code "name-defined" not covered by "type: ignore" comment + # N: Error code "name-defined" not covered by "type: ignore[xyz]" comment e = zz # type: int # type: ignore [ xyz ] # E: Name "zz" is not defined [name-defined] \ - # N: Error code "name-defined" not covered by "type: ignore" comment + # N: Error code "name-defined" not covered by "type: ignore[xyz]" comment f = zz # type: int # type: ignore [ xyz,foo ] # E: Name "zz" is not defined [name-defined] \ - # N: Error code "name-defined" not covered by "type: ignore" comment + # N: Error code "name-defined" not covered by "type: ignore[xyz, foo]" comment [case testErrorCodeIgnoreAfterArgComment] def f(x # type: xyz # type: ignore[name-defined] # Comment @@ -185,7 +187,7 @@ def g(x # type: xyz # type: ignore # Comment pass def h(x # type: xyz # type: ignore[foo] # E: Name "xyz" is not defined [name-defined] \ - # N: Error code "name-defined" not covered by "type: ignore" comment + # N: Error code "name-defined" not covered by "type: ignore[foo]" comment ): # type () -> None pass @@ -1011,25 +1013,23 @@ class D(TypedDict): x: int def f(d: D, s: str) -> None: - d[s] # type: ignore[xyz] \ - # E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \ - # N: Error code "literal-required" not covered by "type: ignore" comment + d[s] # type: ignore[xyz] # E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \ + # N: Error code "literal-required" not covered by "type: ignore[xyz]" comment d[s] # E: TypedDict key must be a string literal; expected one of ("x") [literal-required] - d[s] # type: ignore[misc] \ - # E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \ - # N: Error code changed to literal-required; "type: ignore" comment may be out of date + d[s] # type: ignore[misc] # E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \ + # N: Error code changed to literal-required; "type: ignore" comment may be out of date d[s] # type: ignore[literal-required] [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [case testRecommendErrorCode] # type: ignore[whatever] # E: type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever"` [syntax] \ - # N: Error code "syntax" not covered by "type: ignore" comment + # N: Error code "syntax" not covered by "type: ignore[whatever]" comment 1 + "asdf" [case testRecommendErrorCode2] # type: ignore[whatever, other] # E: type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever, other"` [syntax] \ - # N: Error code "syntax" not covered by "type: ignore" comment + # N: Error code "syntax" not covered by "type: ignore[whatever, other]" comment 1 + "asdf" [case testShowErrorCodesInConfig]