Skip to content

Commit d1aafcd

Browse files
committed
Improve warning message when string annotation used in TypeForm context
1 parent 4162a35 commit d1aafcd

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

mypy/checkexpr.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6352,8 +6352,9 @@ def try_parse_as_type_expression(self, maybe_type_expr: Expression) -> Type | No
63526352
if has_str_expression(maybe_type_expr):
63536353
self.chk.note(
63546354
"TypeForm containing a string annotation cannot be recognized here. "
6355-
"Try assigning the TypeForm to a variable and use the variable here instead.",
6355+
"Surround with TypeForm(...) to recognize.",
63566356
maybe_type_expr,
6357+
code=codes.MAYBE_UNRECOGNIZED_STR_TYPEFORM,
63576358
)
63586359
return None
63596360

mypy/errorcodes.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,11 @@ def __hash__(self) -> int:
264264
"General",
265265
default_enabled=False,
266266
)
267+
MAYBE_UNRECOGNIZED_STR_TYPEFORM: Final[ErrorCode] = ErrorCode(
268+
"maybe-unrecognized-str-typeform",
269+
"Warn when a string is used where a TypeForm is expected but a string annotation cannot be recognized",
270+
"General",
271+
)
267272

268273
# Syntax errors are often blocking.
269274
SYNTAX: Final[ErrorCode] = ErrorCode("syntax", "Report syntax errors", "General")

test-data/unit/check-typeform.test

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,19 +218,32 @@ dict_with_typx_keys[int | str] += 1
218218
[case testTypeExpressionWithStringAnnotationNotRecognizedInOtherSyntacticLocations]
219219
# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm
220220
from typing import Dict, List, TypeForm
221-
list_of_typx: List[TypeForm] = ['int | str'] # N: TypeForm containing a string annotation cannot be recognized here. Try assigning the TypeForm to a variable and use the variable here instead. \
221+
list_of_typx: List[TypeForm] = ['int | str'] # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
222222
# E: List item 0 has incompatible type "str"; expected "TypeForm[Any]"
223223
dict_with_typx_keys: Dict[TypeForm, int] = {
224-
'int | str': 1, # N: TypeForm containing a string annotation cannot be recognized here. Try assigning the TypeForm to a variable and use the variable here instead. \
224+
'int | str': 1, # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
225225
# E: Dict entry 0 has incompatible type "str": "int"; expected "TypeForm[Any]": "int"
226-
'str | None': 2, # N: TypeForm containing a string annotation cannot be recognized here. Try assigning the TypeForm to a variable and use the variable here instead. \
226+
'str | None': 2, # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
227227
# E: Dict entry 1 has incompatible type "str": "int"; expected "TypeForm[Any]": "int"
228228
}
229-
dict_with_typx_keys['int | str'] += 1 # N: TypeForm containing a string annotation cannot be recognized here. Try assigning the TypeForm to a variable and use the variable here instead. \
229+
dict_with_typx_keys['int | str'] += 1 # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
230230
# E: Invalid index type "str" for "Dict[TypeForm[Any], int]"; expected type "TypeForm[Any]"
231231
[builtins fixtures/dict.pyi]
232232
[typing fixtures/typing-full.pyi]
233233

234+
[case testValueExpressionWithStringInTypeFormContextEmitsConservativeWarning]
235+
from typing import Any, Dict, List, TypeForm
236+
types: Dict[str, TypeForm] = {'any': Any}
237+
# Ensure warning can be ignored if does not apply.
238+
list_of_typx1: List[TypeForm] = [types['any']] # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize.
239+
list_of_typx2: List[TypeForm] = [types['any']] # type: ignore[maybe-unrecognized-str-typeform]
240+
# Ensure warning can be fixed using the suggested fix in the warning message.
241+
list_of_typx3: List[TypeForm] = ['Any'] # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
242+
# E: List item 0 has incompatible type "str"; expected "TypeForm[Any]"
243+
list_of_typx4: List[TypeForm] = [TypeForm('Any')]
244+
[builtins fixtures/dict.pyi]
245+
[typing fixtures/typing-full.pyi]
246+
234247
[case testSelfRecognizedInOtherSyntacticLocations]
235248
# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm
236249
from typing import List, Self, TypeForm

0 commit comments

Comments
 (0)