diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index ace8f09bee48..fc0acf55be19 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4420,7 +4420,7 @@ def visit_index_with_type( elif isinstance(left_type, FunctionLike) and left_type.is_type_obj(): if left_type.type_object().is_enum: return self.visit_enum_index_expr(left_type.type_object(), e.index, e) - elif self.chk.options.python_version >= (3, 9) and ( + elif ( left_type.type_object().type_vars or left_type.type_object().fullname == "builtins.type" ): diff --git a/mypy/semanal.py b/mypy/semanal.py index 855c279756e8..5cd58966f619 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -265,6 +265,7 @@ TPDICT_NAMES, TYPE_ALIAS_NAMES, TYPE_CHECK_ONLY_NAMES, + TYPE_NAMES, TYPE_VAR_LIKE_NAMES, TYPED_NAMEDTUPLE_NAMES, UNPACK_TYPE_NAMES, @@ -1116,21 +1117,7 @@ def is_expected_self_type(self, typ: Type, is_classmethod: bool) -> bool: return self.is_expected_self_type(typ.item, is_classmethod=False) if isinstance(typ, UnboundType): sym = self.lookup_qualified(typ.name, typ, suppress_errors=True) - if ( - sym is not None - and ( - sym.fullname == "typing.Type" - or ( - sym.fullname == "builtins.type" - and ( - self.is_stub_file - or self.is_future_flag_set("annotations") - or self.options.python_version >= (3, 9) - ) - ) - ) - and typ.args - ): + if sym is not None and sym.fullname in TYPE_NAMES and typ.args: return self.is_expected_self_type(typ.args[0], is_classmethod=False) return False if isinstance(typ, TypeVarType): diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 40e62e04740d..a8d5f1b304fe 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -65,7 +65,9 @@ FINAL_TYPE_NAMES, LITERAL_TYPE_NAMES, NEVER_NAMES, + TUPLE_NAMES, TYPE_ALIAS_NAMES, + TYPE_NAMES, UNPACK_TYPE_NAMES, AnyType, BoolTypeQuery, @@ -607,10 +609,7 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Typ code=codes.VALID_TYPE, ) return AnyType(TypeOfAny.from_error) - elif fullname == "typing.Tuple" or ( - fullname == "builtins.tuple" - and (self.always_allow_new_syntax or self.options.python_version >= (3, 9)) - ): + elif fullname in TUPLE_NAMES: # Tuple is special because it is involved in builtin import cycle # and may be not ready when used. sym = self.api.lookup_fully_qualified_or_none("builtins.tuple") @@ -645,10 +644,7 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Typ return make_optional_type(item) elif fullname == "typing.Callable": return self.analyze_callable_type(t) - elif fullname == "typing.Type" or ( - fullname == "builtins.type" - and (self.always_allow_new_syntax or self.options.python_version >= (3, 9)) - ): + elif fullname in TYPE_NAMES: if len(t.args) == 0: if fullname == "typing.Type": any_type = self.get_omitted_any(t) diff --git a/mypy/types.py b/mypy/types.py index 5b8302de1ea1..d2094cd15774 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -84,6 +84,9 @@ TypeVisitor as TypeVisitor, ) +TUPLE_NAMES: Final = ("builtins.tuple", "typing.Tuple") +TYPE_NAMES: Final = ("builtins.type", "typing.Type") + TYPE_VAR_LIKE_NAMES: Final = ( "typing.TypeVar", "typing_extensions.TypeVar", diff --git a/mypyc/irbuild/classdef.py b/mypyc/irbuild/classdef.py index 1e53df92fcfe..13121707773a 100644 --- a/mypyc/irbuild/classdef.py +++ b/mypyc/irbuild/classdef.py @@ -564,11 +564,11 @@ def find_non_ext_metaclass(builder: IRBuilder, cdef: ClassDef, bases: Value) -> if cdef.metaclass: declared_metaclass = builder.accept(cdef.metaclass) else: - if cdef.info.typeddict_type is not None and builder.options.capi_version >= (3, 9): + if cdef.info.typeddict_type is not None: # In Python 3.9, the metaclass for class-based TypedDict is typing._TypedDictMeta. # We can't easily calculate it generically, so special case it. return builder.get_module_attr("typing", "_TypedDictMeta", cdef.line) - elif cdef.info.is_named_tuple and builder.options.capi_version >= (3, 9): + elif cdef.info.is_named_tuple: # In Python 3.9, the metaclass for class-based NamedTuple is typing.NamedTupleMeta. # We can't easily calculate it generically, so special case it. return builder.get_module_attr("typing", "NamedTupleMeta", cdef.line) diff --git a/test-data/unit/check-selftype.test b/test-data/unit/check-selftype.test index 5f337f773e6f..cb7e5a9fac71 100644 --- a/test-data/unit/check-selftype.test +++ b/test-data/unit/check-selftype.test @@ -1707,7 +1707,6 @@ class C: [builtins fixtures/classmethod.pyi] [case testTypingSelfRedundantAllowed_pep585] -# flags: --python-version 3.9 from typing import Self class C: @@ -1742,7 +1741,6 @@ class C: [builtins fixtures/classmethod.pyi] [case testTypingSelfRedundantWarning_pep585] -# flags: --python-version 3.9 # mypy: enable-error-code="redundant-self" from typing import Self diff --git a/test-data/unit/check-union-or-syntax.test b/test-data/unit/check-union-or-syntax.test index 924c12658851..35af44c62800 100644 --- a/test-data/unit/check-union-or-syntax.test +++ b/test-data/unit/check-union-or-syntax.test @@ -67,8 +67,7 @@ x: List[int | str] reveal_type(x) # N: Revealed type is "builtins.list[Union[builtins.int, builtins.str]]" [builtins fixtures/list.pyi] -[case testUnionOrSyntaxWithQuotedFunctionTypesPre310] -# flags: --python-version 3.9 +[case testUnionOrSyntaxWithQuotedFunctionTypes] from typing import Union def f(x: 'Union[int, str, None]') -> 'Union[int, None]': reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str, None]" @@ -80,8 +79,7 @@ def g(x: "int | str | None") -> "int | None": return 42 reveal_type(g) # N: Revealed type is "def (x: Union[builtins.int, builtins.str, None]) -> Union[builtins.int, None]" -[case testUnionOrSyntaxWithQuotedVariableTypesPre310] -# flags: --python-version 3.9 +[case testUnionOrSyntaxWithQuotedVariableTypes] y: "int | str" = 42 reveal_type(y) # N: Revealed type is "Union[builtins.int, builtins.str]" @@ -137,7 +135,6 @@ x: int | None x: int | None # E: X | Y syntax for unions requires Python 3.10 [case testUnionOrSyntaxInStubFile] -# flags: --python-version 3.9 from lib import x [file lib.pyi] x: int | None @@ -187,7 +184,6 @@ def g(x: int | str | tuple[int, str] | C) -> None: [builtins fixtures/isinstance_python3_10.pyi] [case testUnionOrSyntaxInIsinstanceNotSupported] -# flags: --python-version 3.9 from typing import Union def f(x: Union[int, str, None]) -> None: if isinstance(x, int | str):