Skip to content

Commit 3cda6ec

Browse files
Mention what codes are actually ignored in not covered by "type: ignore" comment note (#19904)
This should allow the user to more easily compare what is already there; especially if pretty is off, such as in mypy_primer diffs.
1 parent ea00101 commit 3cda6ec

File tree

2 files changed

+22
-20
lines changed

2 files changed

+22
-20
lines changed

mypy/errors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ def add_error_info(self, info: ErrorInfo, *, file: str | None = None) -> None:
810810
if ignored_codes and info.code:
811811
# Something is ignored on the line, but not this error, so maybe the error
812812
# code is incorrect.
813-
msg = f'Error code "{info.code.code}" not covered by "type: ignore" comment'
813+
msg = f"""Error code "{info.code.code}" not covered by "type: ignore[{', '.join(ignored_codes)}]" comment"""
814814
if info.code in original_error_codes:
815815
# If there seems to be a "type: ignore" with a stale error
816816
# code, report a more specific note.

test-data/unit/check-errorcodes.test

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -131,26 +131,28 @@ for v in x: # type: int, int # type: ignore[syntax]
131131
[case testErrorCodeIgnore1]
132132
'x'.foobar # type: ignore[attr-defined]
133133
'x'.foobar # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] \
134-
# N: Error code "attr-defined" not covered by "type: ignore" comment
134+
# N: Error code "attr-defined" not covered by "type: ignore[xyz]" comment
135135
'x'.foobar # type: ignore
136136

137137
[case testErrorCodeIgnore2]
138138
a = 'x'.foobar # type: int # type: ignore[attr-defined]
139139
b = 'x'.foobar # type: int # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] \
140-
# N: Error code "attr-defined" not covered by "type: ignore" comment
140+
# N: Error code "attr-defined" not covered by "type: ignore[xyz]" comment
141141
c = 'x'.foobar # type: int # type: ignore
142142

143143
[case testErrorCodeIgnoreMultiple1]
144144
a = 'x'.foobar(b) # type: ignore[name-defined, attr-defined]
145145
a = 'x'.foobar(b) # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] \
146-
# N: Error code "attr-defined" not covered by "type: ignore" comment
146+
# N: Error code "attr-defined" not covered by "type: ignore[name-defined, xyz]" comment
147147
a = 'x'.foobar(b) # type: ignore[xyz, w, attr-defined] # E: Name "b" is not defined [name-defined] \
148-
# N: Error code "name-defined" not covered by "type: ignore" comment
148+
# N: Error code "name-defined" not covered by "type: ignore[xyz, w, attr-defined]" comment
149+
a = 'x'.foobar(b) # type: ignore[ w, xyz, attr-defined] # E: Name "b" is not defined [name-defined] \
150+
# N: Error code "name-defined" not covered by "type: ignore[w, xyz, attr-defined]" comment
149151

150152
[case testErrorCodeIgnoreMultiple2]
151153
a = 'x'.foobar(c) # type: int # type: ignore[name-defined, attr-defined]
152154
b = 'x'.foobar(c) # type: int # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] \
153-
# N: Error code "attr-defined" not covered by "type: ignore" comment
155+
# N: Error code "attr-defined" not covered by "type: ignore[name-defined, xyz]" comment
154156

155157
[case testErrorCodeWarnUnusedIgnores1]
156158
# flags: --warn-unused-ignores
@@ -216,7 +218,7 @@ z # type: ignore[name-defined]
216218
"y" # type: ignore[ignore-without-code] # E: Unused "type: ignore" comment [unused-ignore]
217219
z # type: ignore[ignore-without-code] # E: Unused "type: ignore" comment [unused-ignore] \
218220
# E: Name "z" is not defined [name-defined] \
219-
# N: Error code "name-defined" not covered by "type: ignore" comment
221+
# N: Error code "name-defined" not covered by "type: ignore[ignore-without-code]" comment
220222

221223
[case testErrorCodeMissingWholeFileIgnores]
222224
# flags: --enable-error-code ignore-without-code
@@ -242,21 +244,21 @@ x2 # type: ignore [ name-defined ]
242244
x3 # type: ignore [ xyz , name-defined ]
243245
x4 # type: ignore[xyz,name-defined]
244246
y # type: ignore [xyz] # E: Name "y" is not defined [name-defined] \
245-
# N: Error code "name-defined" not covered by "type: ignore" comment
247+
# N: Error code "name-defined" not covered by "type: ignore[xyz]" comment
246248
y # type: ignore[ xyz ] # E: Name "y" is not defined [name-defined] \
247-
# N: Error code "name-defined" not covered by "type: ignore" comment
249+
# N: Error code "name-defined" not covered by "type: ignore[xyz]" comment
248250
y # type: ignore[ xyz , foo ] # E: Name "y" is not defined [name-defined] \
249-
# N: Error code "name-defined" not covered by "type: ignore" comment
251+
# N: Error code "name-defined" not covered by "type: ignore[xyz, foo]" comment
250252

251253
a = z # type: int # type: ignore [name-defined]
252254
b = z2 # type: int # type: ignore [ name-defined ]
253255
c = z2 # type: int # type: ignore [ name-defined , xyz ]
254256
d = zz # type: int # type: ignore [xyz] # E: Name "zz" is not defined [name-defined] \
255-
# N: Error code "name-defined" not covered by "type: ignore" comment
257+
# N: Error code "name-defined" not covered by "type: ignore[xyz]" comment
256258
e = zz # type: int # type: ignore [ xyz ] # E: Name "zz" is not defined [name-defined] \
257-
# N: Error code "name-defined" not covered by "type: ignore" comment
259+
# N: Error code "name-defined" not covered by "type: ignore[xyz]" comment
258260
f = zz # type: int # type: ignore [ xyz,foo ] # E: Name "zz" is not defined [name-defined] \
259-
# N: Error code "name-defined" not covered by "type: ignore" comment
261+
# N: Error code "name-defined" not covered by "type: ignore[xyz, foo]" comment
260262

261263
[case testErrorCodeIgnoreAfterArgComment]
262264
def f(x # type: xyz # type: ignore[name-defined] # Comment
@@ -270,7 +272,7 @@ def g(x # type: xyz # type: ignore # Comment
270272
pass
271273

272274
def h(x # type: xyz # type: ignore[foo] # E: Name "xyz" is not defined [name-defined] \
273-
# N: Error code "name-defined" not covered by "type: ignore" comment
275+
# N: Error code "name-defined" not covered by "type: ignore[foo]" comment
274276
):
275277
# type () -> None
276278
pass
@@ -491,7 +493,7 @@ def y() -> int: return 2
491493
def best() -> int: return 3
492494
@d # type: ignore[misc] # E: Unused "type: ignore" comment [unused-ignore] \
493495
# E: Untyped decorator makes function "z" untyped [untyped-decorator] \
494-
# N: Error code "untyped-decorator" not covered by "type: ignore" comment
496+
# N: Error code "untyped-decorator" not covered by "type: ignore[misc]" comment
495497
def z() -> int: return 4
496498

497499
[case testErrorCodeIndexing]
@@ -1127,12 +1129,12 @@ class D(TypedDict):
11271129

11281130
def f(d: D, s: str) -> None:
11291131
d[s] # type: ignore[xyz] \
1130-
# E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \
1131-
# N: Error code "literal-required" not covered by "type: ignore" comment
1132+
# E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \
1133+
# N: Error code "literal-required" not covered by "type: ignore[xyz]" comment
11321134
d[s] # E: TypedDict key must be a string literal; expected one of ("x") [literal-required]
1133-
d[s] # type: ignore[misc] \
1134-
# E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \
1135-
# N: Error code changed to literal-required; "type: ignore" comment may be out of date
1135+
d[s] # type: ignore[misc] \
1136+
# E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \
1137+
# N: Error code changed to literal-required; "type: ignore" comment may be out of date
11361138
d[s] # type: ignore[literal-required]
11371139
[builtins fixtures/dict.pyi]
11381140
[typing fixtures/typing-typeddict.pyi]

0 commit comments

Comments
 (0)