Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e59c310
[PEP 747] Recognize TypeForm[T] type and values (#9773)
davidfstr Sep 29, 2024
9a1992a
Fix multiple issues broken by upstream
davidfstr Jul 24, 2025
06fc9e4
Apply feedback: Change MAYBE_UNRECOGNIZED_STR_TYPEFORM from unaccompa…
davidfstr Jul 27, 2025
c7a5e1f
Apply feedback: Refactor extract save/restore of SemanticAnalyzer sta…
davidfstr Jul 27, 2025
20df001
Apply feedback: Suppress SyntaxWarnings when parsing strings as types
davidfstr Jul 28, 2025
07009a9
Apply feedback: Add TypeForm profiling counters to SemanticAnalyzer a…
davidfstr Jul 28, 2025
0104ce5
Increase efficiency of quick rejection heuristic from 85.8% -> 99.6%
davidfstr Jul 29, 2025
a958b45
Apply feedback: Recognize assignment to union of TypeForm with non-Ty…
davidfstr Jul 30, 2025
e4e5530
Add comment explaining safety of empty tvar scope in TypeAnalyser use…
davidfstr Jul 30, 2025
8e130ba
Allow TypeAlias and PlaceholderNode to be stringified/printed
davidfstr Aug 5, 2025
502e1a5
Apply feedback: Alter primitives.pyi fixture rather than tuple.pyi an…
davidfstr Aug 5, 2025
d8c59f5
NOMERGE: mypy_primer: Enable --enable-incomplete-feature=TypeForm whe…
davidfstr Mar 8, 2025
3521896
Merge branch 'master' into f/typeform4
davidfstr Aug 5, 2025
5a64c78
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 5, 2025
cc4fc23
SQ -> Allow TypeAlias and PlaceholderNode to be stringified/printed
davidfstr Aug 5, 2025
f14b163
SQ -> Merge branch 'master' into f/typeform4 -- Fix bad merge
davidfstr Aug 6, 2025
f4cb3f9
Fix test: testUnionOrSyntaxWithinRuntimeContextNotAllowed
davidfstr Aug 6, 2025
53174d4
Fix error: Never apply isinstance() to unexpanded types
davidfstr Aug 6, 2025
4cc1b18
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 6, 2025
45d9379
Make ruff happy
davidfstr Aug 6, 2025
e91d02d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 6, 2025
80d84b6
Fix {NameAndMemberCollector, all_name_and_member_expressions} to visi…
davidfstr Oct 23, 2025
f191c95
Alter TypeForm tests to import TypeForm from typing_extensions
davidfstr Oct 23, 2025
84d87cb
Merge remote-tracking branch 'origin/master' into f/typeform4
davidfstr Oct 23, 2025
690af88
Revert "NOMERGE: mypy_primer: Enable --enable-incomplete-feature=Type…
davidfstr Oct 23, 2025
e19533a
Fix test that was missing: --enable-incomplete-feature=TypeForm
davidfstr Oct 23, 2025
3dfb36a
Fix test 2 that was missing: --enable-incomplete-feature=TypeForm
davidfstr Oct 25, 2025
fadc994
Fix recognition of several typing special forms, including: Optional,…
davidfstr Oct 25, 2025
820d58f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 25, 2025
ca6f8a5
SQ -> Fix recognition of several typing special forms, including: Opt…
davidfstr Oct 25, 2025
e704c07
Downgrade syntax related to type statement, TypeVarTuple, and Unpack,…
davidfstr Oct 25, 2025
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Apply feedback: Change MAYBE_UNRECOGNIZED_STR_TYPEFORM from unaccompa…
…nied note to standalone error
  • Loading branch information
davidfstr committed Aug 5, 2025
commit 06fc9e47321eb1a186e3a172dec05bbefb0efd27
12 changes: 6 additions & 6 deletions docs/source/error_code_list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1313,31 +1313,31 @@ by mypy in the following locations:

If you try to use a string annotation in some other location
which expects a TypeForm, the string value will always be treated as a ``str``
even if a ``TypeForm`` would be more appropriate and this note code
even if a ``TypeForm`` would be more appropriate and this error code
will be generated:

.. code-block:: python

# Note: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. [maybe-unrecognized-str-typeform]
# Error: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. [maybe-unrecognized-str-typeform]
# Error: List item 0 has incompatible type "str"; expected "TypeForm[Any]" [list-item]
list_of_typx: list[TypeForm] = ['str | None', float]

Fix the note by surrounding the entire type with ``TypeForm(...)``:
Fix the error by surrounding the entire type with ``TypeForm(...)``:

.. code-block:: python

list_of_typx: list[TypeForm] = [TypeForm('str | None'), float] # OK

Similarly, if you try to use a string literal in a location which expects a
TypeForm, this note code will be generated:
TypeForm, this error code will be generated:

.. code-block:: python

dict_of_typx = {'str_or_none': TypeForm(str | None)}
# Note: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. [maybe-unrecognized-str-typeform]
# Error: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. [maybe-unrecognized-str-typeform]
list_of_typx: list[TypeForm] = [dict_of_typx['str_or_none']]

Fix the note by adding ``# type: ignore[maybe-unrecognized-str-typeform]``
Fix the error by adding ``# type: ignore[maybe-unrecognized-str-typeform]``
to the line with the string literal:

.. code-block:: python
Expand Down
2 changes: 1 addition & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -6358,7 +6358,7 @@ def try_parse_as_type_expression(self, maybe_type_expr: Expression) -> Type | No
# don't try to parse it because there isn't enough information
# available to the TypeChecker pass to resolve string annotations
if has_str_expression(maybe_type_expr):
self.chk.note(
self.chk.fail(
"TypeForm containing a string annotation cannot be recognized here. "
"Surround with TypeForm(...) to recognize.",
maybe_type_expr,
Expand Down
2 changes: 1 addition & 1 deletion mypy/errorcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def __hash__(self) -> int:
METACLASS: Final[ErrorCode] = ErrorCode("metaclass", "Ensure that metaclass is valid", "General")
MAYBE_UNRECOGNIZED_STR_TYPEFORM: Final[ErrorCode] = ErrorCode(
"maybe-unrecognized-str-typeform",
"Warn when a string is used where a TypeForm is expected but a string annotation cannot be recognized",
"Error when a string is used where a TypeForm is expected but a string annotation cannot be recognized",
"General",
)

Expand Down
1 change: 0 additions & 1 deletion mypy/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
SHOW_NOTE_CODES: Final = {
codes.ANNOTATION_UNCHECKED,
codes.DEPRECATED,
codes.MAYBE_UNRECOGNIZED_STR_TYPEFORM,
}

# Do not add notes with links to error code docs to errors with these codes.
Expand Down
12 changes: 6 additions & 6 deletions test-data/unit/check-typeform.test
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,15 @@ dict_with_typx_keys[int | str] += 1
[case testTypeExpressionWithStringAnnotationNotRecognizedInOtherSyntacticLocations]
# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm
from typing import Dict, List, TypeForm
list_of_typx: List[TypeForm] = ['int | str'] # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
list_of_typx: List[TypeForm] = ['int | str'] # E: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
# E: List item 0 has incompatible type "str"; expected "TypeForm[Any]"
dict_with_typx_keys: Dict[TypeForm, int] = {
'int | str': 1, # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
'int | str': 1, # E: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
# E: Dict entry 0 has incompatible type "str": "int"; expected "TypeForm[Any]": "int"
'str | None': 2, # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
'str | None': 2, # E: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
# E: Dict entry 1 has incompatible type "str": "int"; expected "TypeForm[Any]": "int"
}
dict_with_typx_keys['int | str'] += 1 # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
dict_with_typx_keys['int | str'] += 1 # E: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
# E: Invalid index type "str" for "dict[TypeForm[Any], int]"; expected type "TypeForm[Any]"
[builtins fixtures/dict.pyi]
[typing fixtures/typing-full.pyi]
Expand All @@ -235,10 +235,10 @@ dict_with_typx_keys['int | str'] += 1 # N: TypeForm containing a string annotat
from typing import Any, Dict, List, TypeForm
types: Dict[str, TypeForm] = {'any': Any}
# Ensure warning can be ignored if does not apply.
list_of_typx1: List[TypeForm] = [types['any']] # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize.
list_of_typx1: List[TypeForm] = [types['any']] # E: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize.
list_of_typx2: List[TypeForm] = [types['any']] # type: ignore[maybe-unrecognized-str-typeform]
# Ensure warning can be fixed using the suggested fix in the warning message.
list_of_typx3: List[TypeForm] = ['Any'] # N: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
list_of_typx3: List[TypeForm] = ['Any'] # E: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. \
# E: List item 0 has incompatible type "str"; expected "TypeForm[Any]"
list_of_typx4: List[TypeForm] = [TypeForm('Any')]
[builtins fixtures/dict.pyi]
Expand Down