Revert "TypeForm: Enable by default (#21262)" This reverts commit dd851f559e4d77b4ab2e53c84fa43b5b383c4f39.
diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index b8e4c7c..d44c08f 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst
@@ -1211,7 +1211,7 @@ Enabling incomplete/experimental features ***************************************** -.. option:: --enable-incomplete-feature {PreciseTupleTypes,InlineTypedDict} +.. option:: --enable-incomplete-feature {PreciseTupleTypes,InlineTypedDict,TypeForm} Some features may require several mypy releases to implement, for example due to their complexity, potential for backwards incompatibility, or @@ -1266,6 +1266,8 @@ def test_values() -> {"width": int, "description": str}: return {"width": 42, "description": "test"} +* ``TypeForm``: this feature enables ``TypeForm``, as described in + `PEP 747 – Annotating Type Forms <https://peps.python.org/pep-0747/>_`. Miscellaneous
diff --git a/mypy/options.py b/mypy/options.py index 2f03cd3..4281c88 100644 --- a/mypy/options.py +++ b/mypy/options.py
@@ -94,8 +94,8 @@ NEW_GENERIC_SYNTAX: Final = "NewGenericSyntax" INLINE_TYPEDDICT: Final = "InlineTypedDict" TYPE_FORM: Final = "TypeForm" -INCOMPLETE_FEATURES: Final = frozenset((PRECISE_TUPLE_TYPES, INLINE_TYPEDDICT)) -COMPLETE_FEATURES: Final = frozenset((TYPE_VAR_TUPLE, UNPACK, NEW_GENERIC_SYNTAX, TYPE_FORM)) +INCOMPLETE_FEATURES: Final = frozenset((PRECISE_TUPLE_TYPES, INLINE_TYPEDDICT, TYPE_FORM)) +COMPLETE_FEATURES: Final = frozenset((TYPE_VAR_TUPLE, UNPACK, NEW_GENERIC_SYNTAX)) class Options:
diff --git a/mypy/semanal.py b/mypy/semanal.py index a958043..f9b52a0 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py
@@ -195,7 +195,7 @@ type_aliases_source_versions, typing_extensions_aliases, ) -from mypy.options import Options +from mypy.options import TYPE_FORM, Options from mypy.patterns import ( AsPattern, ClassPattern, @@ -3701,7 +3701,8 @@ ) def analyze_rvalue_as_type_form(self, s: AssignmentStmt) -> None: - self.try_parse_as_type_expression(s.rvalue) + if TYPE_FORM in self.options.enable_incomplete_feature: + self.try_parse_as_type_expression(s.rvalue) def apply_dynamic_class_hook(self, s: AssignmentStmt) -> None: if not isinstance(s.rvalue, CallExpr): @@ -5451,7 +5452,8 @@ self.fail('"return" not allowed in except* block', s, serious=True) if s.expr: s.expr.accept(self) - self.try_parse_as_type_expression(s.expr) + if TYPE_FORM in self.options.enable_incomplete_feature: + self.try_parse_as_type_expression(s.expr) self.statement = old def visit_raise_stmt(self, s: RaiseStmt) -> None: @@ -6054,9 +6056,11 @@ expr.analyzed.accept(self) else: # Normal call expression. + calculate_type_forms = TYPE_FORM in self.options.enable_incomplete_feature for a in expr.args: a.accept(self) - self.try_parse_as_type_expression(a) + if calculate_type_forms: + self.try_parse_as_type_expression(a) if ( isinstance(expr.callee, MemberExpr)
diff --git a/mypy/typeanal.py b/mypy/typeanal.py index db56256..3351bc1 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py
@@ -49,7 +49,7 @@ check_arg_kinds, check_param_names, ) -from mypy.options import INLINE_TYPEDDICT, Options +from mypy.options import INLINE_TYPEDDICT, TYPE_FORM, Options from mypy.plugin import AnalyzeTypeContext, Plugin, TypeAnalyzerPluginInterface from mypy.semanal_shared import ( SemanticAnalyzerCoreInterface, @@ -674,6 +674,12 @@ item = AnyType(TypeOfAny.from_error) return TypeType.make_normalized(item, line=t.line, column=t.column) elif fullname in ("typing_extensions.TypeForm", "typing.TypeForm"): + if TYPE_FORM not in self.options.enable_incomplete_feature: + self.fail( + "TypeForm is experimental," + " must be enabled with --enable-incomplete-feature=TypeForm", + t, + ) if len(t.args) == 0: any_type = self.get_omitted_any(t) return TypeType(any_type, line=t.line, column=t.column, is_type_form=True)
diff --git a/test-data/unit/check-fastparse.test b/test-data/unit/check-fastparse.test index 0897760..67ba0c9 100644 --- a/test-data/unit/check-fastparse.test +++ b/test-data/unit/check-fastparse.test
@@ -337,7 +337,7 @@ [builtins fixtures/module.pyi] [case testInvalidEscapeSequenceWarningsSuppressed] -# flags: --python-version 3.15 +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # Test that SyntaxWarnings for invalid escape sequences are suppressed # when parsing potential type expressions containing regex patterns or # similar strings. Callable arguments are always potential type expressions.
diff --git a/test-data/unit/check-typeform.test b/test-data/unit/check-typeform.test index 220f31b..6d59cb0 100644 --- a/test-data/unit/check-typeform.test +++ b/test-data/unit/check-typeform.test
@@ -1,6 +1,7 @@ -- TypeForm Type [case testRecognizesUnparameterizedTypeFormInAnnotation] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx: TypeForm = str reveal_type(typx) # N: Revealed type is "TypeForm[Any]" @@ -8,6 +9,7 @@ [typing fixtures/typing-full.pyi] [case testRecognizesParameterizedTypeFormInAnnotation] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx: TypeForm[str] = str reveal_type(typx) # N: Revealed type is "TypeForm[builtins.str]" @@ -18,24 +20,28 @@ -- Type Expression Location: Assignment [case testCanAssignTypeExpressionToTypeFormVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx: TypeForm[str] = str [builtins fixtures/primitives.pyi] [typing fixtures/typing-full.pyi] [case testCanAssignTypeExpressionToUnionTypeFormVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx: TypeForm[str | None] = str | None [builtins fixtures/primitives.pyi] [typing fixtures/typing-full.pyi] [case testCannotAssignTypeExpressionToTypeFormVariableWithIncompatibleItemType] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx: TypeForm[str] = int # E: Incompatible types in assignment (expression has type "TypeForm[int]", variable has type "TypeForm[str]") [builtins fixtures/primitives.pyi] [typing fixtures/typing-full.pyi] [case testCanAssignValueExpressionToTypeFormVariableIfValueIsATypeForm1] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx1: TypeForm = str typx2: TypeForm = typx1 # looks like a type expression: name @@ -43,6 +49,7 @@ [typing fixtures/typing-full.pyi] [case testCanAssignValueExpressionToTypeFormVariableIfValueIsATypeForm2] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm def identity_tf(x: TypeForm) -> TypeForm: return x @@ -52,6 +59,7 @@ [typing fixtures/typing-full.pyi] [case testCannotAssignValueExpressionToTypeFormVariableIfValueIsNotATypeForm] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm val: int = 42 typx: TypeForm = val # E: Incompatible types in assignment (expression has type "int", variable has type "TypeForm[Any]") @@ -59,6 +67,7 @@ [typing fixtures/typing-full.pyi] [case testCanAssignNoneTypeExpressionToTypeFormVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx: TypeForm = None reveal_type(typx) # N: Revealed type is "TypeForm[Any]" @@ -66,6 +75,7 @@ [typing fixtures/typing-full.pyi] [case testCanAssignTypeExpressionToTypeFormVariableDeclaredEarlier] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import Type, TypeForm typ: Type typ = int | None # E: Incompatible types in assignment (expression has type "object", variable has type "type[Any]") @@ -75,6 +85,7 @@ [typing fixtures/typing-full.pyi] [case testCanAssignTypeExpressionWithStringAnnotationToTypeFormVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx: TypeForm[str | None] = 'str | None' [builtins fixtures/primitives.pyi] @@ -84,6 +95,7 @@ -- Type Expression Location: Function Parameter [case testCanPassTypeExpressionToTypeFormParameterInFunction] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm def is_type(typx: TypeForm) -> bool: return isinstance(typx, type) @@ -92,6 +104,7 @@ [typing fixtures/typing-full.pyi] [case testCannotPassTypeExpressionToTypeParameter] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm def is_type(typ: type) -> bool: return isinstance(typ, type) is_type(int | None) # E: Argument 1 to "is_type" has incompatible type "object"; expected "type" @@ -99,6 +112,7 @@ [typing fixtures/typing-full.pyi] [case testCanPassTypeExpressionToTypeFormParameterInMethod] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm class C: def is_type(self, typx: TypeForm) -> bool: @@ -108,6 +122,7 @@ [typing fixtures/typing-full.pyi] [case testCanPassTypeExpressionToTypeFormParameterInOverload] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import overload, TypeForm @overload def is_type(typx: TypeForm) -> bool: ... @@ -120,6 +135,7 @@ [typing fixtures/typing-full.pyi] [case testCanPassTypeExpressionToTypeFormParameterInDecorator] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import Callable, TypeForm, TypeVar P = TypeVar('P') R = TypeVar('R') @@ -135,6 +151,7 @@ [typing fixtures/typing-full.pyi] [case testCanPassTypeExpressionToTypeFormVarargsParameter] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import Callable, ParamSpec, TypeForm, TypeVar P = ParamSpec('P') R = TypeVar('R') @@ -150,6 +167,7 @@ [typing fixtures/typing-full.pyi] [case testCanPassTypeExpressionWithStringAnnotationToTypeFormParameter] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm def is_type(typx: TypeForm) -> bool: return isinstance(typx, type) @@ -161,6 +179,7 @@ -- Type Expression Location: Return Statement [case testCanReturnTypeExpressionInFunctionWithTypeFormReturnType] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm def maybe_int_type() -> TypeForm: return int | None @@ -169,6 +188,7 @@ [typing fixtures/typing-full.pyi] [case testCanReturnTypeExpressionWithStringAnnotationInFunctionWithTypeFormReturnType] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm def maybe_int_type() -> TypeForm: return 'int | None' @@ -184,6 +204,7 @@ -- have the same rich context as SemanticAnalyzer.try_parse_as_type_expression(). [case testTypeExpressionWithoutStringAnnotationRecognizedInOtherSyntacticLocations] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import Dict, List, TypeForm list_of_typx: List[TypeForm] = [int | str] dict_with_typx_keys: Dict[TypeForm, int] = { @@ -195,6 +216,7 @@ [typing fixtures/typing-full.pyi] [case testTypeExpressionWithStringAnnotationNotRecognizedInOtherSyntacticLocations] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import Dict, List, TypeForm 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]" @@ -210,6 +232,7 @@ [typing fixtures/typing-full.pyi] [case testValueExpressionWithStringInTypeFormContextEmitsConservativeWarning] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import Any, Dict, List, TypeForm types: Dict[str, TypeForm] = {'any': Any} # Ensure warning can be ignored if does not apply. @@ -223,6 +246,7 @@ [typing fixtures/typing-full.pyi] [case testSelfRecognizedInOtherSyntacticLocations] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import List, Self, TypeForm class C: def foo(self) -> None: @@ -236,6 +260,7 @@ [typing fixtures/typing-full.pyi] [case testNameOrDottedNameRecognizedInOtherSyntacticLocations] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm import typing from typing import List, TypeForm list_of_typx: List[TypeForm] = [List | typing.Optional[str]] @@ -244,6 +269,7 @@ [typing fixtures/typing-full.pyi] [case testInvalidNameOrDottedNameRecognizedInOtherSyntacticLocations] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import List, TypeForm list_of_typx1: List[TypeForm] = [NoSuchType] # E: Name "NoSuchType" is not defined list_of_typx2: List[TypeForm] = [no_such_module.NoSuchType] # E: Name "no_such_module" is not defined @@ -256,6 +282,7 @@ -- Type Expression Context: Union[TypeForm, <non-TypeForm>] [case testAcceptsTypeFormLiteralAssignedToUnionOfTypeFormAndNonStr] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx_or_int1: TypeForm[int | None] | int = int | None # No error; interpret as TypeForm typx_or_int2: TypeForm[int | None] | int = str | None # E: Incompatible types in assignment (expression has type "object", variable has type "TypeForm[int | None] | int") @@ -265,6 +292,7 @@ [typing fixtures/typing-full.pyi] [case testAcceptsTypeFormLiteralAssignedToUnionOfTypeFormAndStr] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx_or_str1: TypeForm[int | None] | str = 'int | None' typx_or_str2: TypeForm[int | None] | str = 'str | None' # No error; interpret as str @@ -274,6 +302,7 @@ [typing fixtures/typing-full.pyi] [case testValueExpressionWithStringInTypeFormUnionContextEmitsConservativeWarning1] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import List, TypeForm list_of_typx1: List[TypeForm[int | None] | str] = ['int | None'] # E: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. list_of_typx2: List[TypeForm[int | None] | str] = ['str | None'] # E: TypeForm containing a string annotation cannot be recognized here. Surround with TypeForm(...) to recognize. @@ -281,6 +310,7 @@ [typing fixtures/typing-full.pyi] [case testValueExpressionWithStringInTypeFormUnionContextEmitsConservativeWarning2] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import List, TypeForm list_of_typx3: List[TypeForm[int | None] | int] = ['int | None'] # 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[int | None] | int" @@ -293,6 +323,7 @@ -- Assignability (is_subtype) [case testTypeFormToTypeFormAssignability] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - TypeForm[T1] is assignable to TypeForm[T2] iff T1 is assignable to T2. # - In particular TypeForm[Any] is assignable to TypeForm[Any]. from typing_extensions import TypeForm @@ -316,6 +347,7 @@ [typing fixtures/typing-full.pyi] [case testTypeToTypeFormAssignability] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - Type[C] is assignable to TypeForm[T] iff C is assignable to T. # - In particular Type[Any] is assignable to TypeForm[Any]. from typing import Type, TypeForm @@ -336,6 +368,7 @@ [typing fixtures/typing-full.pyi] [case testTypeFormToTypeAssignability] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - TypeForm[T] is NOT assignable to Type[C]. # - In particular TypeForm[Any] is NOT assignable to Type[Any]. from typing import Type, TypeForm @@ -361,6 +394,7 @@ # NOTE: This test doesn't involve TypeForm at all, but is still illustrative # when compared with similarly structured TypeForm-related tests above. [case testTypeToTypeAssignability] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - Type[C1] is assignable to Type[C2] iff C1 is assignable to C2. # - In particular Type[Any] is assignable to Type[Any]. from typing import Type @@ -381,6 +415,7 @@ [typing fixtures/typing-full.pyi] [case testTypeFormToObjectAssignability] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - TypeForm[T] is assignable to object and Any. from typing import Any, TypeForm INT_TF: TypeForm[int] = int @@ -400,6 +435,7 @@ -- Join (join_types) [case testTypeFormToTypeFormJoin] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - TypeForm[T1] join TypeForm[T2] == TypeForm[T1 join T2] from typing_extensions import TypeForm class AB: @@ -415,6 +451,7 @@ [typing fixtures/typing-full.pyi] [case testTypeToTypeFormJoin] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - TypeForm[T1] join Type[T2] == TypeForm[T1 join T2] from typing import Type, TypeForm class AB: @@ -430,6 +467,7 @@ [typing fixtures/typing-full.pyi] [case testTypeFormToTypeJoin] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - TypeForm[T1] join Type[T2] == TypeForm[T1 join T2] from typing import Type, TypeForm class AB: @@ -447,6 +485,7 @@ # NOTE: This test doesn't involve TypeForm at all, but is still illustrative # when compared with similarly structured TypeForm-related tests above. [case testTypeToTypeJoin] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - Type[T1] join Type[T2] == Type[T1 join T2] from typing import Type, TypeForm class AB: @@ -465,6 +504,7 @@ -- Meet (meet_types) [case testTypeFormToTypeFormMeet] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - TypeForm[T1] meet TypeForm[T2] == TypeForm[T1 meet T2] from typing import Callable, TypeForm, TypeVar class AB: @@ -483,6 +523,7 @@ [typing fixtures/typing-full.pyi] [case testTypeToTypeFormMeet] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - TypeForm[T1] meet Type[T2] == Type[T1 meet T2] from typing import Callable, Type, TypeForm, TypeVar class AB: @@ -501,6 +542,7 @@ [typing fixtures/typing-full.pyi] [case testTypeFormToTypeMeet] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - TypeForm[T1] meet Type[T2] == Type[T1 meet T2] from typing import Callable, Type, TypeForm, TypeVar class AB: @@ -521,6 +563,7 @@ # NOTE: This test doesn't involve TypeForm at all, but is still illustrative # when compared with similarly structured TypeForm-related tests above. [case testTypeToTypeMeet] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # - Type[T1] meet Type[T2] == Type[T1 meet T2] from typing import Callable, Type, TypedDict, TypeForm, TypeVar class AB(TypedDict): @@ -540,6 +583,7 @@ -- TypeForm(...) Expression [case testTypeFormExpression] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm tf1 = TypeForm(int | str) reveal_type(tf1) # N: Revealed type is "TypeForm[builtins.int | builtins.str]" @@ -557,6 +601,7 @@ -- isinstance [case testTypeFormAndTypeIsinstance] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx: TypeForm[str] = str if isinstance(typx, type): @@ -570,6 +615,7 @@ -- Type Variables [case testLinkTypeFormToTypeFormWithTypeVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm, TypeVar T = TypeVar('T') def as_typeform(typx: TypeForm[T]) -> TypeForm[T]: @@ -579,6 +625,7 @@ [typing fixtures/typing-full.pyi] [case testLinkTypeFormToTypeWithTypeVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import Type, TypeForm, TypeVar T = TypeVar('T') def as_type(typx: TypeForm[T]) -> Type[T] | None: @@ -592,6 +639,7 @@ [typing fixtures/typing-full.pyi] [case testLinkTypeFormToInstanceWithTypeVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm, TypeVar T = TypeVar('T') def as_instance(typx: TypeForm[T]) -> T | None: @@ -605,6 +653,7 @@ [typing fixtures/typing-full.pyi] [case testLinkTypeFormToTypeIsWithTypeVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm, TypeVar from typing_extensions import TypeIs T = TypeVar('T') @@ -619,6 +668,7 @@ [typing fixtures/typing-full.pyi] [case testLinkTypeFormToTypeGuardWithTypeVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm, TypeVar from typing_extensions import TypeGuard T = TypeVar('T') @@ -636,13 +686,14 @@ -- Type Expressions Assignable To TypeForm Variable [case testEveryKindOfTypeExpressionIsAssignableToATypeFormVariable] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm # NOTE: Importing Callable from collections.abc also works OK from typing import ( - Any, Callable, Dict, List, Literal, NoReturn, + Any, Callable, Dict, List, Literal, LiteralString, NoReturn, Optional, ParamSpec, Self, Type, TypeGuard, TypeVar, Union, ) from typing_extensions import ( - Annotated, Concatenate, LiteralString, Never, TypeAlias, TypeForm, TypeIs, + Annotated, Concatenate, Never, TypeAlias, TypeForm, TypeIs, TypeVarTuple, Unpack, ) # @@ -734,6 +785,7 @@ -- Misc [case testTypeFormHasAllObjectAttributesAndMethods] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm typx: TypeForm[int | str] = int | str print(typx.__class__) # OK @@ -757,6 +809,7 @@ [typing fixtures/typing-full.pyi] [case testDottedTypeFormsAreRecognized] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing_extensions import TypeForm import typing class C1: @@ -770,6 +823,7 @@ -- mypy already refused to recognize TypeVars in value expressions before -- the TypeForm feature was introduced. [case testTypeVarTypeFormsAreOnlyRecognizedInStringAnnotation] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import Generic, List, TypeForm, TypeVar E = TypeVar('E') class Box(Generic[E]): @@ -781,6 +835,7 @@ [typing fixtures/typing-full.pyi] [case testIncompleteTypeFormsAreNotRecognized] +# flags: --python-version 3.14 --enable-incomplete-feature=TypeForm from typing import Optional, TypeForm typx: TypeForm = Optional # E: Incompatible types in assignment (expression has type "int", variable has type "TypeForm[Any]") [builtins fixtures/primitives.pyi]