diff --git a/CHANGELOG.md b/CHANGELOG.md index 47f1f2ccd9cce..84d39e54a9d11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Next Release +### Drop Support for Targeting Python 3.9 + +Mypy no longer supports type checking code with `--python-version 3.9`. +Use `--python-version 3.10` or newer. + ## Mypy 1.20 We’ve just uploaded mypy 1.20.0 to the Python Package Index ([PyPI](https://pypi.org/project/mypy/)). diff --git a/docs/source/builtin_types.rst b/docs/source/builtin_types.rst index 37b56169d879c..4e7a6ae8d045d 100644 --- a/docs/source/builtin_types.rst +++ b/docs/source/builtin_types.rst @@ -40,8 +40,7 @@ See :ref:`dynamic-typing` for more details. Generic types ............. -In Python 3.9 and later, built-in collection type objects support -indexing: +Built-in collection type objects support indexing: ====================== =============================== Type Description @@ -65,13 +64,11 @@ strings and ``dict[Any, Any]`` is a dictionary of dynamically typed Python protocols. For example, a ``str`` object or a ``list[str]`` object is valid when ``Iterable[str]`` or ``Sequence[str]`` is expected. You can import them from :py:mod:`collections.abc` instead of importing from -:py:mod:`typing` in Python 3.9. +:py:mod:`typing`. -See :ref:`generic-builtins` for more details, including how you can -use these in annotations also in Python 3.7 and 3.8. +See :ref:`generic-builtins` for more details. -These legacy types defined in :py:mod:`typing` are needed if you need to support -Python 3.8 and earlier: +These legacy types defined in :py:mod:`typing` are also supported: ====================== =============================== Type Description @@ -80,17 +77,5 @@ Type Description ``Tuple[int, int]`` tuple of two ``int`` objects (``Tuple[()]`` is the empty tuple) ``Tuple[int, ...]`` tuple of an arbitrary number of ``int`` objects ``Dict[str, int]`` dictionary from ``str`` keys to ``int`` values -``Iterable[int]`` iterable object containing ints -``Sequence[bool]`` sequence of booleans (read-only) -``Mapping[str, int]`` mapping from ``str`` keys to ``int`` values (read-only) ``Type[C]`` type object of ``C`` (``C`` is a class/type variable/union of types) ====================== =============================== - -``List`` is an alias for the built-in type ``list`` that supports -indexing (and similarly for ``dict``/``Dict`` and -``tuple``/``Tuple``). - -Note that even though ``Iterable``, ``Sequence`` and ``Mapping`` look -similar to abstract base classes defined in :py:mod:`collections.abc` -(formerly ``collections``), they are not identical, since the latter -don't support indexing prior to Python 3.9. diff --git a/docs/source/cheat_sheet_py3.rst b/docs/source/cheat_sheet_py3.rst index 7385a66863bf6..231eefb45dc40 100644 --- a/docs/source/cheat_sheet_py3.rst +++ b/docs/source/cheat_sheet_py3.rst @@ -43,18 +43,18 @@ Useful built-in types x: str = "test" x: bytes = b"test" - # For collections on Python 3.9+, the type of the collection item is in brackets + # For collections, the type of the collection item is in brackets x: list[int] = [1] x: set[int] = {6, 7} # For mappings, we need the types of both keys and values - x: dict[str, float] = {"field": 2.0} # Python 3.9+ + x: dict[str, float] = {"field": 2.0} # For tuples of fixed size, we specify the types of all the elements - x: tuple[int, str, float] = (3, "yes", 7.5) # Python 3.9+ + x: tuple[int, str, float] = (3, "yes", 7.5) # For tuples of variable size, we use one type and ellipsis - x: tuple[int, ...] = (1, 2, 3) # Python 3.9+ + x: tuple[int, ...] = (1, 2, 3) # On Python 3.8 and earlier, the name of the collection type is # capitalized, and the type is imported from the 'typing' module @@ -67,13 +67,12 @@ Useful built-in types from typing import Union, Optional - # On Python 3.10+, use the | operator when something could be one of a few types - x: list[int | str] = [3, 5, "test", "fun"] # Python 3.10+ - # On earlier versions, use Union + # Use the | operator when something could be one of a few types + x: list[int | str] = [3, 5, "test", "fun"] + # Union is equivalent x: list[Union[int, str]] = [3, 5, "test", "fun"] - # Use X | None for a value that could be None on Python 3.10+ - # Use Optional[X] on 3.9 and earlier; Optional[X] is the same as 'X | None' + # Use X | None for a value that could be None; Optional[X] is the same as X | None x: str | None = "something" if some_condition() else None if x is not None: # Mypy understands x won't be None here because of the if-statement diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index a48c4405084ec..99060ff8bc1b2 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -671,7 +671,7 @@ subtly different, and it's important to understand how they differ to avoid pitf .. code-block:: python - from typing import TypeAlias # "from typing_extensions" in Python 3.9 and earlier + from typing import TypeAlias class A: ... Alias: TypeAlias = A diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index e9a195e2da777..bb81dc6ade355 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -432,7 +432,7 @@ Platform configuration Specifies the Python version used to parse and check the target program. The string should be in the format ``MAJOR.MINOR`` -- - for example ``3.9``. The default is the version of the Python + for example ``3.10``. The default is the version of the Python interpreter used to run mypy. This option may only be set in the global section (``[mypy]``). @@ -1255,7 +1255,7 @@ of your repo (or append it to the end of an existing ``pyproject.toml`` file) an # mypy global options: [tool.mypy] - python_version = "3.9" + python_version = "3.10" warn_return_any = true warn_unused_configs = true exclude = [ diff --git a/docs/source/generics.rst b/docs/source/generics.rst index 0d340613aba5d..14706d9e80c0e 100644 --- a/docs/source/generics.rst +++ b/docs/source/generics.rst @@ -1419,8 +1419,7 @@ class in more recent versions of Python: .. code-block:: python - >>> # Only relevant for Python 3.8 and below - >>> # If using Python 3.9 or newer, prefer the 'list[int]' syntax + >>> # Prefer the 'list[int]' syntax >>> from typing import List >>> List[int] typing.List[int] diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 2a578f9748642..3fcb7543443f7 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -197,12 +197,6 @@ union type. For example, ``int`` is a subtype of ``int | str``: else: return user_id -.. note:: - - If using Python 3.9 or earlier, use ``typing.Union[int, str]`` instead of - ``int | str``, or use ``from __future__ import annotations`` at the top of - the file (see :ref:`runtime_troubles`). - The :py:mod:`typing` module contains many other useful types. For a quick overview, look through the :ref:`mypy cheatsheet `. diff --git a/docs/source/kinds_of_types.rst b/docs/source/kinds_of_types.rst index 23ebc14e8670e..26c2f002231e6 100644 --- a/docs/source/kinds_of_types.rst +++ b/docs/source/kinds_of_types.rst @@ -315,9 +315,8 @@ such as ``int | None``. This is called an *optional type*: return None # Error: None not compatible with int return len(s) -To support Python 3.9 and earlier, you can use the :py:data:`~typing.Optional` -type modifier instead, such as ``Optional[int]`` (``Optional[X]`` is -the preferred shorthand for ``Union[X, None]``): +You can also use the :py:data:`~typing.Optional` type modifier, such as +``Optional[int]`` (``Optional[X]`` is the shorthand for ``Union[X, None]``): .. code-block:: python @@ -515,12 +514,11 @@ distinguish them from implicit type aliases: it can't be used in contexts which require a class object. For example, it's not valid as a base class and it can't be used to construct instances. -There is also use an older syntax for defining explicit type aliases, which was -introduced in Python 3.10 (:pep:`613`): +There is also use an older syntax for defining explicit type aliases (:pep:`613`): .. code-block:: python - from typing import TypeAlias # "from typing_extensions" in Python 3.9 and earlier + from typing import TypeAlias AliasType: TypeAlias = list[dict[tuple[int, str], set[int]]] | tuple[str, list[str]] diff --git a/docs/source/protocols.rst b/docs/source/protocols.rst index 258cd4b0de564..53942c522d040 100644 --- a/docs/source/protocols.rst +++ b/docs/source/protocols.rst @@ -66,11 +66,6 @@ you need to define to implement each protocol. .. note:: ``typing`` also contains deprecated aliases to protocols and ABCs defined in :py:mod:`collections.abc`, such as :py:class:`Iterable[T] `. - These are only necessary in Python 3.8 and earlier, since the protocols in - ``collections.abc`` didn't yet support subscripting (``[]``) in Python 3.8, - but the aliases in ``typing`` have always supported - subscripting. In Python 3.9 and later, the aliases in ``typing`` don't provide - any extra functionality. Simple user-defined protocols ***************************** diff --git a/docs/source/type_inference_and_annotations.rst b/docs/source/type_inference_and_annotations.rst index 8c6150e72497c..88d9b2ddda5ca 100644 --- a/docs/source/type_inference_and_annotations.rst +++ b/docs/source/type_inference_and_annotations.rst @@ -94,14 +94,6 @@ In these cases you can give the type explicitly using a type annotation: l: list[int] = [] # Create empty list of int d: dict[str, int] = {} # Create empty dictionary (str -> int) -.. note:: - - Using type arguments (e.g. ``list[int]``) on builtin collections like - :py:class:`list`, :py:class:`dict`, :py:class:`tuple`, and :py:class:`set` - only works in Python 3.9 and later. For Python 3.8 and earlier, you must use - :py:class:`~typing.List` (e.g. ``List[int]``), :py:class:`~typing.Dict`, and - so on. - Compatibility of container types ******************************** diff --git a/docs/source/type_narrowing.rst b/docs/source/type_narrowing.rst index ccd16ffbc0a35..6602d6303d1eb 100644 --- a/docs/source/type_narrowing.rst +++ b/docs/source/type_narrowing.rst @@ -225,7 +225,7 @@ The same example with ``TypeGuard``: .. code-block:: python - from typing import TypeGuard # use `typing_extensions` for Python 3.9 and below + from typing import TypeGuard def is_str_list(val: list[object]) -> TypeGuard[list[str]]: """Determines whether all objects in the list are strings""" diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 84cb146ce6f3c..e3e2fc3d86ec1 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -555,13 +555,7 @@ def visit_call_expr_inner(self, e: CallExpr, allow_none_return: bool = False) -> and node and isinstance(node.node, TypeAlias) and not node.node.no_args - and not ( - isinstance(union_target := get_proper_type(node.node.target), UnionType) - and ( - union_target.uses_pep604_syntax - or self.chk.options.python_version >= (3, 10) - ) - ) + and not isinstance(get_proper_type(node.node.target), UnionType) ): self.msg.type_arguments_not_allowed(e) if isinstance(typ, RefExpr) and isinstance(typ.node, TypeInfo): @@ -5021,11 +5015,7 @@ class LongName(Generic[T]): ... return TypeType(item, line=item.line, column=item.column) elif isinstance(item, AnyType): return AnyType(TypeOfAny.from_another_any, source_any=item) - elif ( - isinstance(item, UnionType) - and item.uses_pep604_syntax - and self.chk.options.python_version >= (3, 10) - ): + elif isinstance(item, UnionType) and item.uses_pep604_syntax: return self.chk.named_generic_type("types.UnionType", item.items) else: if alias_definition: diff --git a/mypy/defaults.py b/mypy/defaults.py index 749879861fbf7..6ea3b3645db57 100644 --- a/mypy/defaults.py +++ b/mypy/defaults.py @@ -10,7 +10,7 @@ # Earliest Python 3.x version supported via --python-version 3.x. To run # mypy, at least version PYTHON3_VERSION is needed. -PYTHON3_VERSION_MIN: Final = (3, 9) # Keep in sync with typeshed's python support +PYTHON3_VERSION_MIN: Final = (3, 10) # Keep in sync with supported target versions CACHE_DIR: Final = ".mypy_cache" diff --git a/mypy/exprtotype.py b/mypy/exprtotype.py index ae36fc8adde09..5a22b9c3c759a 100644 --- a/mypy/exprtotype.py +++ b/mypy/exprtotype.py @@ -145,11 +145,7 @@ def expr_to_unanalyzed_type( return base else: raise TypeTranslationError() - elif ( - isinstance(expr, OpExpr) - and expr.op == "|" - and ((options.python_version >= (3, 10)) or allow_new_syntax) - ): + elif isinstance(expr, OpExpr) and expr.op == "|": return UnionType( [ expr_to_unanalyzed_type( diff --git a/mypy/modulefinder.py b/mypy/modulefinder.py index b3b88e5aac657..bf9b833bab871 100644 --- a/mypy/modulefinder.py +++ b/mypy/modulefinder.py @@ -997,6 +997,4 @@ def parse_version(version: str) -> tuple[int, int]: def typeshed_py_version(options: Options) -> tuple[int, int]: """Return Python version used for checking whether module supports typeshed.""" - # Typeshed no longer covers Python 3.x versions before 3.9, so 3.9 is - # the earliest we can support. - return max(options.python_version, (3, 9)) + return max(options.python_version, (3, 10)) diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index f664acfc9ce8c..a921ab52c30cd 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -370,9 +370,7 @@ def attr_class_maker_callback_impl( _add_attrs_magic_attribute(ctx, [(attr.name, info[attr.name].type) for attr in attributes]) if slots: _add_slots(ctx, attributes) - if match_args and ctx.api.options.python_version[:2] >= (3, 10): - # `.__match_args__` is only added for python3.10+, but the argument - # exists for earlier versions as well. + if match_args: _add_match_args(ctx, attributes) # Save the attributes so that subclasses can reuse them. diff --git a/mypy/plugins/dataclasses.py b/mypy/plugins/dataclasses.py index 97faadbad0642..cb87378e54263 100644 --- a/mypy/plugins/dataclasses.py +++ b/mypy/plugins/dataclasses.py @@ -249,7 +249,6 @@ def transform(self) -> bool: "slots": self._get_bool_arg("slots", False), "match_args": self._get_bool_arg("match_args", True), } - py_version = self._api.options.python_version # If there are no attributes, it may be that the semantic analyzer has not # processed them yet. In order to work around this, we can simply skip generating @@ -368,16 +367,12 @@ def transform(self) -> bool: self._propertize_callables(attributes) if decorator_arguments["slots"]: - self.add_slots(info, attributes, correct_version=py_version >= (3, 10)) + self.add_slots(info, attributes) self.reset_init_only_vars(info, attributes) - if ( - decorator_arguments["match_args"] - and ( - "__match_args__" not in info.names or info.names["__match_args__"].plugin_generated - ) - and py_version >= (3, 10) + if decorator_arguments["match_args"] and ( + "__match_args__" not in info.names or info.names["__match_args__"].plugin_generated ): str_type = self._api.named_type("builtins.str") literals: list[Type] = [ @@ -445,18 +440,7 @@ def _add_internal_post_init_method(self, attributes: list[DataclassAttribute]) - return_type=NoneType(), ) - def add_slots( - self, info: TypeInfo, attributes: list[DataclassAttribute], *, correct_version: bool - ) -> None: - if not correct_version: - # This means that version is lower than `3.10`, - # it is just a non-existent argument for `dataclass` function. - self._api.fail( - 'Keyword argument "slots" for "dataclass" is only valid in Python 3.10 and higher', - self._reason, - ) - return - + def add_slots(self, info: TypeInfo, attributes: list[DataclassAttribute]) -> None: existing_slots = info.names.get("__slots__") slots_defined_by_plugin = existing_slots is not None and existing_slots.plugin_generated if existing_slots is not None and not slots_defined_by_plugin: diff --git a/mypy/pyinfo.py b/mypy/pyinfo.py index 98350f46363ca..0563e16eda718 100644 --- a/mypy/pyinfo.py +++ b/mypy/pyinfo.py @@ -2,9 +2,9 @@ """Utilities to find the site and prefix information of a Python executable. -This file MUST remain compatible with all Python 3.9+ versions. Since we cannot make any +This file MUST remain compatible with all Python 3.10+ versions. Since we cannot make any assumptions about the Python being executed, this module should not use *any* dependencies outside -of the standard library found in Python 3.9. This file is run each mypy run, so it should be kept +of the standard library found in Python 3.10. This file is run each mypy run, so it should be kept as fast as possible. """ import sys diff --git a/mypy/semanal.py b/mypy/semanal.py index aa74122be2553..8fd09f5381aa5 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -4206,10 +4206,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: eager=eager, python_3_12_type_alias=pep_695, ) - if isinstance(s.rvalue, (IndexExpr, CallExpr, OpExpr)) and ( - not isinstance(rvalue, OpExpr) - or (self.options.python_version >= (3, 10) or self.is_stub_file) - ): + if isinstance(s.rvalue, (IndexExpr, CallExpr, OpExpr)): # Note: CallExpr is for "void = type(None)" and OpExpr is for "X | Y" union syntax. if not isinstance(s.rvalue.analyzed, TypeAliasExpr): # Any existing node will be updated in-place below. diff --git a/mypy/semanal_namedtuple.py b/mypy/semanal_namedtuple.py index 9a51bced4885d..08fc3e2bb7725 100644 --- a/mypy/semanal_namedtuple.py +++ b/mypy/semanal_namedtuple.py @@ -569,8 +569,7 @@ def add_field( add_field(Var("_source", strtype), is_initialized_in_class=True) add_field(Var("__annotations__", ordereddictype), is_initialized_in_class=True) add_field(Var("__doc__", strtype), is_initialized_in_class=True) - if self.options.python_version >= (3, 10): - add_field(Var("__match_args__", match_args_type), is_initialized_in_class=True) + add_field(Var("__match_args__", match_args_type), is_initialized_in_class=True) assert info.tuple_type is not None # Set by update_tuple_type() above. shared_self_type = TypeVarType( diff --git a/mypy/semanal_pass1.py b/mypy/semanal_pass1.py index 266fd236a01f6..23f3365b843aa 100644 --- a/mypy/semanal_pass1.py +++ b/mypy/semanal_pass1.py @@ -46,13 +46,13 @@ class SemanticAnalyzerPreAnalysis(TraverserVisitor): import sys def do_stuff() -> None: - if sys.version_info >= (3, 10): - import xyz # Only available in Python 3.10+ + if sys.version_info >= (3, 11): + import xyz # Only available in Python 3.11+ xyz.whatever() ... - The block containing 'import xyz' is unreachable in Python 3 mode. The import - shouldn't be processed in Python 3 mode, even if the module happens to exist. + The block containing 'import xyz' is unreachable in Python 3.10 mode. The import + shouldn't be processed in Python 3.10 mode, even if the module happens to exist. """ def visit_file(self, file: MypyFile, fnam: str, mod_id: str, options: Options) -> None: diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 6bf3c0617dadd..ac0378cc54689 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -1716,9 +1716,7 @@ def verify_typealias( return if isinstance(stub_target, mypy.types.UnionType): # complain if runtime is not a Union or UnionType - if runtime_origin is not Union and ( - not (sys.version_info >= (3, 10) and isinstance(runtime, types.UnionType)) - ): + if runtime_origin is not Union and not isinstance(runtime, types.UnionType): yield Error(object_path, "is not a Union", stub, runtime, stub_desc=str(stub_target)) # could check Union contents here... return diff --git a/mypy/test/testpep561.py b/mypy/test/testpep561.py index 0afb69bc0c998..c37f97b214202 100644 --- a/mypy/test/testpep561.py +++ b/mypy/test/testpep561.py @@ -48,11 +48,7 @@ def virtualenv(python_executable: str = sys.executable) -> Iterator[tuple[str, s def upgrade_pip(python_executable: str) -> None: """Install pip>=21.3.1. Required for editable installs with PEP 660.""" - if ( - sys.version_info >= (3, 11) - or (3, 10, 3) <= sys.version_info < (3, 11) - or (3, 9, 11) <= sys.version_info < (3, 10) - ): + if sys.version_info >= (3, 11) or (3, 10, 3) <= sys.version_info < (3, 11): # Skip for more recent Python releases which come with pip>=21.3.1 # out of the box - for performance reasons. return diff --git a/mypy/typeanal.py b/mypy/typeanal.py index a685ea2383cb5..dfcfb51d361ed 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -233,11 +233,6 @@ def __init__( self.allow_tuple_literal = allow_tuple_literal # Positive if we are analyzing arguments of another (outer) type self.nesting_level = 0 - # Should we allow new type syntax when targeting older Python versions - # like 'list[int]' or 'X | Y' (allowed in stubs and with `__future__` import)? - self.always_allow_new_syntax = self.api.is_stub_file or self.api.is_future_flag_set( - "annotations" - ) # Should we accept unbound type variables? This is currently used for class bases, # and alias right hand sides (before they are analyzed as type aliases). self.allow_unbound_tvars = allow_unbound_tvars @@ -1412,13 +1407,6 @@ def visit_literal_type(self, t: LiteralType) -> Type: return t def visit_union_type(self, t: UnionType) -> Type: - if ( - t.uses_pep604_syntax is True - and t.is_evaluated is True - and not self.always_allow_new_syntax - and not self.options.python_version >= (3, 10) - ): - self.fail("X | Y syntax for unions requires Python 3.10", t, code=codes.SYNTAX) return UnionType(self.anal_array(t.items), t.line, uses_pep604_syntax=t.uses_pep604_syntax) def visit_partial_type(self, t: PartialType) -> Type: diff --git a/mypyc/irbuild/classdef.py b/mypyc/irbuild/classdef.py index 66363a06f0c1b..f5d094d142317 100644 --- a/mypyc/irbuild/classdef.py +++ b/mypyc/irbuild/classdef.py @@ -620,11 +620,11 @@ def find_non_ext_metaclass(builder: IRBuilder, cdef: ClassDef, bases: Value) -> declared_metaclass = builder.accept(cdef.metaclass) else: if cdef.info.typeddict_type is not None: - # In Python 3.9, the metaclass for class-based TypedDict is typing._TypedDictMeta. + # 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: - # In Python 3.9, the metaclass for class-based NamedTuple is typing.NamedTupleMeta. + # 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/mypyc/primitives/generic_ops.py b/mypyc/primitives/generic_ops.py index 1003fda8d9ae8..87b1f4ff309b2 100644 --- a/mypyc/primitives/generic_ops.py +++ b/mypyc/primitives/generic_ops.py @@ -286,7 +286,7 @@ error_kind=ERR_MAGIC, ) -# Call method using positional and/or keyword arguments (Python 3.9+) +# Call method using positional and/or keyword arguments. py_vectorcall_method_op = custom_op( arg_types=[ object_rprimitive, # Method name diff --git a/mypyc/test/testutil.py b/mypyc/test/testutil.py index 072d1811c2a4c..0a558d0d0b8ec 100644 --- a/mypyc/test/testutil.py +++ b/mypyc/test/testutil.py @@ -104,13 +104,13 @@ def build_ir_for_single_file2( # By default generate IR compatible with the earliest supported Python C API. # If a test needs more recent API features, this should be overridden. - compiler_options = compiler_options or CompilerOptions(capi_version=(3, 9)) + compiler_options = compiler_options or CompilerOptions(capi_version=(3, 10)) options = Options() options.show_traceback = True options.hide_error_codes = True options.use_builtins_fixtures = True options.strict_optional = True - options.python_version = compiler_options.python_version or (3, 9) + options.python_version = compiler_options.python_version or (3, 10) options.export_types = True options.preserve_asts = True options.allow_empty_bodies = True @@ -266,8 +266,8 @@ def infer_ir_build_options_from_test_name(name: str) -> CompilerOptions | None: Run test case only on 64-bit platforms *_32bit*: Run test caseonly on 32-bit platforms - *_python3_8* (or for any Python version): - Use Python 3.8+ C API features (default: lowest supported version) + *_python3_10* (or for any Python version): + Use Python 3.10+ C API features (default: lowest supported version) *StripAssert*: Don't generate code for assert statements """ @@ -277,12 +277,14 @@ def infer_ir_build_options_from_test_name(name: str) -> CompilerOptions | None: if "_32bit" in name and not IS_32_BIT_PLATFORM: return None options = CompilerOptions( - strip_asserts="StripAssert" in name, capi_version=(3, 9), strict_traceback_checks=True + strip_asserts="StripAssert" in name, capi_version=(3, 10), strict_traceback_checks=True ) - # A suffix like _python3_9 is used to set the target C API version. - m = re.search(r"_python([3-9]+)_([0-9]+)(_|\b)", name) + # A suffix like _python3_10 is used to set the target C API version. + m = re.search(r"_python([0-9]+)_([0-9]+)(_|\b)", name) if m: - options.capi_version = (int(m.group(1)), int(m.group(2))) + version = (int(m.group(1)), int(m.group(2))) + assert version >= (3, 10), f"Unsupported _python* suffix: {name}" + options.capi_version = version options.python_version = options.capi_version elif "_py" in name or "_Python" in name: assert False, f"Invalid _py* suffix (should be _pythonX_Y): {name}" diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index 758d20ca394b3..5ff20fe971ce6 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1497,22 +1497,6 @@ class DynamicDef: # E: "DynamicDef" both defines "__slots__" and is used with " x: int [builtins fixtures/dataclasses.pyi] -[case testDataclassWithSlotsArgBefore310] -# flags: --python-version 3.9 -from dataclasses import dataclass - -@dataclass(slots=True) # E: Keyword argument "slots" for "dataclass" is only valid in Python 3.10 and higher -class Some: - x: int - -# Possible conflict: -@dataclass(slots=True) # E: Keyword argument "slots" for "dataclass" is only valid in Python 3.10 and higher -class Other: - __slots__ = ('x',) - x: int -[builtins fixtures/dataclasses.pyi] - - [case testDataclassWithSlotsRuntimeAttr] # flags: --python-version 3.10 from dataclasses import dataclass @@ -1892,23 +1876,6 @@ reveal_type(o.__match_args__) # E: "One" has no attribute "__match_args__" \ # N: Revealed type is "Any" [builtins fixtures/dataclasses.pyi] -[case testDataclassWithMatchArgsOldVersion] -# flags: --python-version 3.9 -from dataclasses import dataclass -@dataclass(match_args=True) -class One: - bar: int -o: One -reveal_type(o.__match_args__) # E: "One" has no attribute "__match_args__" \ - # N: Revealed type is "Any" -@dataclass -class Two: - bar: int -t: Two -reveal_type(t.__match_args__) # E: "Two" has no attribute "__match_args__" \ - # N: Revealed type is "Any" -[builtins fixtures/dataclasses.pyi] - [case testFinalInDataclass] from dataclasses import dataclass from typing import Final diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 5a2933c68b88e..e43fe07143db0 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -3746,8 +3746,8 @@ cache_fine_grained = False [file mypy.ini.2] \[mypy] cache_fine_grained = True -[rechecked _typeshed, a, builtins, typing] -[stale _typeshed, a, builtins, typing] +[rechecked _typeshed, a, builtins, types, typing] +[stale _typeshed, a, builtins, types, typing] [builtins fixtures/tuple.pyi] [case testIncrementalPackageNameOverload] @@ -3788,7 +3788,7 @@ import b [file b.py] -- This is a heinous hack, but we simulate having a invalid cache by clobbering -- the proto deps file with something with mtime mismatches. -[file ../.mypy_cache/3.9/@deps.meta.json.2] +[file ../.mypy_cache/3.10/@deps.meta.json.2] {"snapshot": {"__main__": "a7c958b001a45bd6a2a320f4e53c4c16", "a": "d41d8cd98f00b204e9800998ecf8427e", "b": "d41d8cd98f00b204e9800998ecf8427e", "builtins": "c532c89da517a4b779bcf7a964478d67"}, "deps_meta": {"@root": {"path": "@root.deps.json", "mtime": 0}, "__main__": {"path": "__main__.deps.json", "mtime": 0}, "a": {"path": "a.deps.json", "mtime": 0}, "b": {"path": "b.deps.json", "mtime": 0}, "builtins": {"path": "builtins.deps.json", "mtime": 0}}} [file ../.mypy_cache/.gitignore] # Another hack to not trigger a .gitignore creation failure "false positive" @@ -3798,8 +3798,8 @@ Signature: 8a477f597d28d172789f06886806bc55 [file b.py.2] # uh -- Every file should get reloaded, since the cache was invalidated -[stale _typeshed, a, b, builtins, typing] -[rechecked _typeshed, a, b, builtins, typing] +[stale _typeshed, a, b, builtins, types, typing] +[rechecked _typeshed, a, b, builtins, types, typing] [builtins fixtures/tuple.pyi] [case testIncrementalBustedFineGrainedCache2] @@ -3811,8 +3811,8 @@ import b [file b.py.2] # uh -- Every file should get reloaded, since the settings changed -[stale _typeshed, a, b, builtins, typing] -[rechecked _typeshed, a, b, builtins, typing] +[stale _typeshed, a, b, builtins, types, typing] +[rechecked _typeshed, a, b, builtins, types, typing] [builtins fixtures/tuple.pyi] [case testIncrementalBustedFineGrainedCache3] @@ -3823,12 +3823,12 @@ import b [file b.py] -- This is a heinous hack, but we simulate having a invalid cache by deleting -- the proto deps file. -[delete ../.mypy_cache/3.9/@deps.meta.json.2] +[delete ../.mypy_cache/3.10/@deps.meta.json.2] [file b.py.2] # uh -- Every file should get reloaded, since the cache was invalidated -[stale _typeshed, a, b, builtins, typing] -[rechecked _typeshed, a, b, builtins, typing] +[stale _typeshed, a, b, builtins, types, typing] +[rechecked _typeshed, a, b, builtins, types, typing] [builtins fixtures/tuple.pyi] [case testIncrementalWorkingFineGrainedCache] diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 6eb1c322cee69..71acabb026e66 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -1165,18 +1165,6 @@ reveal_type(o.__match_args__) # N: Revealed type is "tuple[Literal['bar'], Lite [builtins fixtures/tuple.pyi] [typing fixtures/typing-namedtuple.pyi] -[case testNamedTupleHasNoMatchArgsOldVersion] -# flags: --python-version 3.9 -from typing import NamedTuple -class One(NamedTuple): - bar: int - baz: str -o: One -reveal_type(o.__match_args__) # E: "One" has no attribute "__match_args__" \ - # N: Revealed type is "Any" -[builtins fixtures/tuple.pyi] -[typing fixtures/typing-namedtuple.pyi] - [case testNamedTupleNoBytes] from collections import namedtuple from typing import NamedTuple diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index 00924cb3f8889..721ca52f59eed 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -5543,7 +5543,7 @@ reveal_type(f5(C())) # N: Revealed type is "__main__.C" reveal_type(f5(D())) # N: Revealed type is "__main__.D" [case testOverloadIfSysVersion] -# flags: --python-version 3.9 +# flags: --python-version 3.10 from typing import overload import sys @@ -5558,7 +5558,7 @@ class C: ... @overload def f1(g: A) -> A: ... -if sys.version_info >= (3, 9): +if sys.version_info >= (3, 10): @overload def f1(g: B) -> B: ... def f1(g): ... @@ -5569,7 +5569,7 @@ reveal_type(f1(B())) # N: Revealed type is "__main__.B" def f2(g: A) -> A: ... @overload def f2(g: B) -> B: ... -if sys.version_info >= (3, 10): +if sys.version_info >= (3, 11): @overload def f2(g: C) -> C: ... def f2(g): ... diff --git a/test-data/unit/check-plugin-attrs.test b/test-data/unit/check-plugin-attrs.test index e5bb1d3f446f0..251d6744e24ae 100644 --- a/test-data/unit/check-plugin-attrs.test +++ b/test-data/unit/check-plugin-attrs.test @@ -1847,20 +1847,6 @@ class WithoutMatch: reveal_type(WithoutMatch(x=1, y=2).__match_args__) # N: Revealed type is "tuple[Literal['a']?, Literal['b']?]" [builtins fixtures/plugin_attrs.pyi] -[case testAttrsWithMatchArgsOldVersion] -# flags: --python-version 3.9 -import attr - -@attr.s(match_args=True) -class NoMatchArgs: - ... - -n: NoMatchArgs - -reveal_type(n.__match_args__) # E: "NoMatchArgs" has no attribute "__match_args__" \ - # N: Revealed type is "Any" -[builtins fixtures/plugin_attrs.pyi] - [case testAttrsMultipleInheritance] # flags: --python-version 3.10 import attr diff --git a/test-data/unit/check-python39.test b/test-data/unit/check-python39.test index 236482229a6ee..1e96fe67ffcd0 100644 --- a/test-data/unit/check-python39.test +++ b/test-data/unit/check-python39.test @@ -1,7 +1,5 @@ [case testGivingSameKeywordArgumentTwice_no_native_parse] # This test was originally in check-kwargs.test -# Python 3.9's new parser started producing a different error message here. Since this isn't the -# most important test, to deal with this we'll only run this test with Python 3.9 and later. import typing def f(a: 'A', b: 'B') -> None: pass class A: pass diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test index b9ea7cdeae657..cb445cf4a1a2b 100644 --- a/test-data/unit/check-statements.test +++ b/test-data/unit/check-statements.test @@ -521,9 +521,11 @@ if object(): [case testRaiseNotImplementedFails] if object(): - raise NotImplemented # E: Exception must be derived from BaseException; did you mean "NotImplementedError"? + raise NotImplemented # E: Exception must be derived from BaseException \ + # E: Exception must be derived from BaseException; did you mean "NotImplementedError"? if object(): - raise NotImplemented() # E: Exception must be derived from BaseException; did you mean "NotImplementedError"? + raise NotImplemented() # E: Exception must be derived from BaseException; did you mean "NotImplementedError"? \ + # E: "NotImplementedType" not callable [builtins fixtures/notimplemented.pyi] [case testTryFinallyStatement] diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 43fcf13e7be17..622004758364b 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -142,7 +142,7 @@ reveal_type(p) # N: Revealed type is "TypedDict('__main__.EmptyDict', {})" [typing fixtures/typing-typeddict.pyi] -[case testCanCreateTypedDictWithClassOldVersion] +[case testCanCreateTypedDictWithClassFunctionBases] # Test that we can use class-syntax to merge function-based TypedDicts from typing import TypedDict diff --git a/test-data/unit/check-union-or-syntax.test b/test-data/unit/check-union-or-syntax.test index 91eac5b7eec8b..c67a68588a028 100644 --- a/test-data/unit/check-union-or-syntax.test +++ b/test-data/unit/check-union-or-syntax.test @@ -102,26 +102,6 @@ b: X # E: Variable "__main__.X" is not valid as a type \ # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases [builtins fixtures/type.pyi] -[case testUnionOrSyntaxWithinRuntimeContextNotAllowed] -# flags: --python-version 3.9 -from __future__ import annotations -from typing import List -T = int | str # E: Invalid type alias: expression is not a valid type \ - # E: Unsupported left operand type for | ("type[int]") -class C(List[int | str]): # E: Type expected within [...] \ - # E: Invalid base class "List" - pass -C() -[builtins fixtures/tuple.pyi] - -[case testUnionOrSyntaxWithinRuntimeContextNotAllowed2] -# flags: --python-version 3.9 -from __future__ import annotations -from typing import cast -cast(str | int, 'x') # E: Cast target is not a type -[builtins fixtures/tuple.pyi] -[typing fixtures/typing-full.pyi] - [case testUnionOrSyntaxInComment] x = 1 # type: int | str @@ -130,10 +110,6 @@ from __future__ import annotations x: int | None [builtins fixtures/tuple.pyi] -[case testUnionOrSyntaxMissingFutureImport] -# flags: --python-version 3.9 -x: int | None # E: X | Y syntax for unions requires Python 3.10 - [case testUnionOrSyntaxInStubFile] from lib import x [file lib.pyi] @@ -164,7 +140,7 @@ B = list[int | None] y: B class C(list[int | None]): pass -[builtins fixtures/list.pyi] +[builtins fixtures/type.pyi] [case testUnionOrSyntaxInIsinstance] # flags: --python-version 3.10 diff --git a/test-data/unit/check-unions.test b/test-data/unit/check-unions.test index 1838ec5d145b5..84d78cd14d90b 100644 --- a/test-data/unit/check-unions.test +++ b/test-data/unit/check-unions.test @@ -1345,17 +1345,3 @@ def foo(x: Union[int, str, tuple]): else: reveal_type(x) # N: Revealed type is "builtins.int | builtins.str | builtins.tuple[Any, ...]" [builtins fixtures/tuple.pyi] - - -[case testTypeAliasWithOldUnionIsInstancePython39] -# flags: --python-version 3.9 -from typing import Union -SimpleAlias = Union[int, str] - -def foo(x: Union[int, str, tuple]): - if isinstance(x, SimpleAlias): # E: Parameterized generics cannot be used with class or instance checks \ - # E: Argument 2 to "isinstance" has incompatible type ""; expected "type" - reveal_type(x) # N: Revealed type is "builtins.int | builtins.str | builtins.tuple[Any, ...]" - else: - reveal_type(x) # N: Revealed type is "builtins.int | builtins.str | builtins.tuple[Any, ...]" -[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/check-unreachable-code.test b/test-data/unit/check-unreachable-code.test index 1888a6595b61b..257478c517f39 100644 --- a/test-data/unit/check-unreachable-code.test +++ b/test-data/unit/check-unreachable-code.test @@ -888,7 +888,7 @@ def baz(x: int) -> int: [builtins fixtures/exception.pyi] [case testUnreachableFlagIgnoresSemanticAnalysisUnreachable_no_native_parse] -# flags: --warn-unreachable --python-version 3.9 --platform win32 --always-false FOOBAR +# flags: --warn-unreachable --python-version 3.10 --platform win32 --always-false FOOBAR import sys from typing import TYPE_CHECKING @@ -923,12 +923,12 @@ def f5(x: int) -> None: reveal_type(x) # N: Revealed type is "builtins.int" def f6(x: int) -> None: - if sys.version_info >= (3, 9): + if sys.version_info >= (3, 10): reveal_type(x) # N: Revealed type is "builtins.int" else: reveal_type(x) - if sys.version_info >= (3, 10): + if sys.version_info >= (3, 11): reveal_type(x) else: reveal_type(x) # N: Revealed type is "builtins.int" diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test index babdb84bdb8a2..c3440fda74a01 100644 --- a/test-data/unit/cmdline.test +++ b/test-data/unit/cmdline.test @@ -315,7 +315,7 @@ main.py:1: error: Cannot find implementation or library stub for module named "a \[tool.mypy] python_version = 3.10 [out] -pyproject.toml: [mypy]: python_version: Python 3.1 is not supported (must be 3.9 or higher). You may need to put quotes around your Python version +pyproject.toml: [mypy]: python_version: Python 3.1 is not supported (must be 3.10 or higher). You may need to put quotes around your Python version == Return code: 0 [case testPythonVersionTooOld10] @@ -327,13 +327,13 @@ python_version = 1.0 mypy.ini: [mypy]: python_version: Python major version '1' out of range (must be 3) == Return code: 0 -[case testPythonVersionTooOld38] +[case testPythonVersionTooOld39] # cmd: mypy -c pass [file mypy.ini] \[mypy] -python_version = 3.8 +python_version = 3.9 [out] -mypy.ini: [mypy]: python_version: Python 3.8 is not supported (must be 3.9 or higher) +mypy.ini: [mypy]: python_version: Python 3.9 is not supported (must be 3.10 or higher) == Return code: 0 [case testPythonVersionTooNew40] @@ -356,11 +356,11 @@ usage: mypy [-h] [-v] [-V] [more options; see below] mypy: error: Mypy no longer supports checking Python 2 code. Consider pinning to mypy<0.980 if you need to check Python 2 code. == Return code: 2 -[case testPythonVersionAccepted39] +[case testPythonVersionAccepted310] # cmd: mypy -c pass [file mypy.ini] \[mypy] -python_version = 3.9 +python_version = 3.10 [out] [case testPythonVersionAccepted314] @@ -374,13 +374,13 @@ python_version = 3.14 # cmd: mypy main.py [file main.py] import sys -if sys.version_info < (3, 10): # Update here when bumping the min Python version! +if sys.version_info < (3, 11): # Update here when bumping the min Python version! reveal_type("good") [file mypy.ini] \[mypy] -python_version = 3.8 +python_version = 3.9 [out] -mypy.ini: [mypy]: python_version: Python 3.8 is not supported (must be 3.9 or higher) +mypy.ini: [mypy]: python_version: Python 3.9 is not supported (must be 3.10 or higher) main.py:3: note: Revealed type is "Literal['good']?" == Return code: 0 diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index 5f6510094148c..448af5d080029 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -420,7 +420,7 @@ a: int a: str [case testDaemonGetType] -$ dmypy start --log-file log.txt -- --follow-imports=error --no-error-summary --python-version 3.9 +$ dmypy start --log-file log.txt -- --follow-imports=error --no-error-summary --python-version 3.10 Daemon started $ dmypy inspect foo:1:2:3:4 Command "inspect" is only valid after a "check" command (that produces no parse errors) diff --git a/test-data/unit/deps.test b/test-data/unit/deps.test index 2c231c9afff6e..4221c16025654 100644 --- a/test-data/unit/deps.test +++ b/test-data/unit/deps.test @@ -1373,39 +1373,7 @@ def h() -> None: -> m.h -> m.D, m.h -[case testDataclassDepsOldVersion] -from dataclasses import dataclass - -Z = int - -@dataclass -class A: - x: Z - -@dataclass -class B(A): - y: int -[builtins fixtures/dataclasses.pyi] - -[out] - -> , m - -> - -> , m.B.__init__ - -> , m, m.B.__mypy-replace - -> - -> - -> - -> m, m.A, m.B - -> m - -> m - -> m - -> m.B - -> m - -> m - -> m - [case testDataclassDeps] -# flags: --python-version 3.10 from dataclasses import dataclass Z = int diff --git a/test-data/unit/exportjson.test b/test-data/unit/exportjson.test index 2d6a8c56b20f7..3a8508dd39ef1 100644 --- a/test-data/unit/exportjson.test +++ b/test-data/unit/exportjson.test @@ -321,3 +321,36 @@ from typing_extensions import Final "ignore_all": false, "plugin_data": null } +{ + "id": "types", + "path": ..., + "mtime": ..., + "size": 372, + "hash": "7542ae4787693f5598d0e8fc9efe396bd6f9af0c", + "data_mtime": ..., + "dependencies": [ + "typing", + "builtins" + ], + "suppressed": [], + "options": { + "other_options": "", + "platform": ... + }, + "dep_prios": [ + 5, + 5 + ], + "dep_lines": [ + 1, + 1 + ], + "dep_hashes": [ + "", + "" + ], + "interface_hash": "", + "version_id": ..., + "ignore_all": true, + "plugin_data": null +} diff --git a/test-data/unit/fine-grained-cache-incremental.test b/test-data/unit/fine-grained-cache-incremental.test index 2a9514ca4984e..721dd432be2fe 100644 --- a/test-data/unit/fine-grained-cache-incremental.test +++ b/test-data/unit/fine-grained-cache-incremental.test @@ -202,7 +202,7 @@ a.py:8: note: x: expected "int", got "str" [file b.py] -- This is a heinous hack, but we simulate having a invalid cache by clobbering -- the proto deps file with something with mtime mismatches. -[file ../.mypy_cache/3.9/@deps.meta.json.2] +[file ../.mypy_cache/3.10/@deps.meta.json.2] {"snapshot": {"__main__": "a7c958b001a45bd6a2a320f4e53c4c16", "a": "d41d8cd98f00b204e9800998ecf8427e", "b": "d41d8cd98f00b204e9800998ecf8427e", "builtins": "c532c89da517a4b779bcf7a964478d67"}, "deps_meta": {"@root": {"path": "@root.deps.json", "mtime": 0}, "__main__": {"path": "__main__.deps.json", "mtime": 0}, "a": {"path": "a.deps.json", "mtime": 0}, "b": {"path": "b.deps.json", "mtime": 0}, "builtins": {"path": "builtins.deps.json", "mtime": 0}}} [file b.py.2] @@ -234,8 +234,8 @@ x = 10 [file p/c.py] class C: pass -[delete ../.mypy_cache/3.9/b.meta.ff.2] -[delete ../.mypy_cache/3.9/p/c.meta.ff.2] +[delete ../.mypy_cache/3.10/b.meta.ff.2] +[delete ../.mypy_cache/3.10/p/c.meta.ff.2] [out] == diff --git a/test-data/unit/fixtures/isinstancelist.pyi b/test-data/unit/fixtures/isinstancelist.pyi index 54d6e9e38b499..0426b4e0cbfb1 100644 --- a/test-data/unit/fixtures/isinstancelist.pyi +++ b/test-data/unit/fixtures/isinstancelist.pyi @@ -1,6 +1,7 @@ from typing import ( Iterable, Iterator, TypeVar, List, Mapping, overload, Tuple, Set, Union, Generic, Sequence ) +import types class object: def __init__(self) -> None: pass diff --git a/test-data/unit/fixtures/notimplemented.pyi b/test-data/unit/fixtures/notimplemented.pyi index 9f3f276a7d48c..9442c21aa464f 100644 --- a/test-data/unit/fixtures/notimplemented.pyi +++ b/test-data/unit/fixtures/notimplemented.pyi @@ -1,5 +1,4 @@ # builtins stub used in NotImplemented related cases. -from typing import Any class object: def __init__(self) -> None: pass @@ -14,13 +13,7 @@ class tuple: pass class ellipsis: pass class list: pass -import sys - -if sys.version_info >= (3, 10): # type: ignore - from types import NotImplementedType - NotImplemented: NotImplementedType -else: - class _NotImplementedType(Any): ... - NotImplemented: _NotImplementedType +from types import NotImplementedType +NotImplemented: NotImplementedType class BaseException: pass diff --git a/test-data/unit/fixtures/tuple.pyi b/test-data/unit/fixtures/tuple.pyi index 06dfcf5d0fbc1..1e37ada08e521 100644 --- a/test-data/unit/fixtures/tuple.pyi +++ b/test-data/unit/fixtures/tuple.pyi @@ -1,6 +1,7 @@ # Builtins stub used in tuple-related test cases. import _typeshed +import types from typing import Iterable, Iterator, TypeVar, Generic, Sequence, Optional, overload, Tuple, Type, Self _T = TypeVar("_T") diff --git a/test-data/unit/fixtures/type.pyi b/test-data/unit/fixtures/type.pyi index 55d84c3b3360a..83c54b558ccf1 100644 --- a/test-data/unit/fixtures/type.pyi +++ b/test-data/unit/fixtures/type.pyi @@ -1,7 +1,6 @@ # builtins stub used in type-related test cases. from typing import Any, Generic, TypeVar, List, Union -import sys import types T = TypeVar("T") @@ -30,7 +29,4 @@ class str: pass class ellipsis: pass class float: pass -if sys.version_info >= (3, 10): # type: ignore - def isinstance(obj: object, class_or_tuple: type | types.UnionType, /) -> bool: ... -else: - def isinstance(obj: object, class_or_tuple: type, /) -> bool: ... +def isinstance(obj: object, class_or_tuple: type | types.UnionType, /) -> bool: ... diff --git a/test-data/unit/lib-stub/types.pyi b/test-data/unit/lib-stub/types.pyi index 6670b7cace0df..28a45366dbea3 100644 --- a/test-data/unit/lib-stub/types.pyi +++ b/test-data/unit/lib-stub/types.pyi @@ -1,5 +1,4 @@ from typing import Any, TypeVar -import sys _T = TypeVar('_T') @@ -13,11 +12,10 @@ class GenericAlias: def __or__(self, o): ... def __ror__(self, o): ... -if sys.version_info >= (3, 10): - class NoneType: - ... +class NoneType: + ... - class UnionType: - def __or__(self, x) -> UnionType: ... +class UnionType: + def __or__(self, x) -> UnionType: ... - class NotImplementedType: ... +class NotImplementedType: ... diff --git a/test-data/unit/merge.test b/test-data/unit/merge.test index 79c3efbc304bb..3e02b9aa9b93c 100644 --- a/test-data/unit/merge.test +++ b/test-data/unit/merge.test @@ -646,7 +646,6 @@ TypeInfo<2>( f<3>)) [case testNamedTuple_typeinfo] -# flags: --python-version 3.10 import target [file target.py] from typing import NamedTuple @@ -707,65 +706,6 @@ TypeInfo<2>( x<20> (target.A<0>) y<21> (target.A<0>))) -[case testNamedTupleOldVersion_typeinfo] -import target -[file target.py] -from typing import NamedTuple -class A: pass -N = NamedTuple('N', [('x', A)]) -[file target.py.next] -from typing import NamedTuple -class A: pass -N = NamedTuple('N', [('x', A), ('y', A)]) -[builtins fixtures/tuple.pyi] -[out] -TypeInfo<0>( - Name(target.A) - Bases(builtins.object<1>) - Mro(target.A<0>, builtins.object<1>) - Names()) -TypeInfo<2>( - Name(target.N) - Bases(builtins.tuple[target.A<0>, ...]<3>) - Mro(target.N<2>, builtins.tuple<3>, typing.Sequence<4>, typing.Iterable<5>, builtins.object<1>) - Names( - _NT<6> - __annotations__<7> (builtins.dict[builtins.str<8>, Any]<9>) - __doc__<10> (builtins.str<8>) - __new__<11> - _asdict<12> - _field_defaults<13> (builtins.dict[builtins.str<8>, Any]<9>) - _field_types<14> (builtins.dict[builtins.str<8>, Any]<9>) - _fields<15> (tuple[builtins.str<8>]) - _make<16> - _replace<17> - _source<18> (builtins.str<8>) - x<19> (target.A<0>))) -==> -TypeInfo<0>( - Name(target.A) - Bases(builtins.object<1>) - Mro(target.A<0>, builtins.object<1>) - Names()) -TypeInfo<2>( - Name(target.N) - Bases(builtins.tuple[target.A<0>, ...]<3>) - Mro(target.N<2>, builtins.tuple<3>, typing.Sequence<4>, typing.Iterable<5>, builtins.object<1>) - Names( - _NT<6> - __annotations__<7> (builtins.dict[builtins.str<8>, Any]<9>) - __doc__<10> (builtins.str<8>) - __new__<11> - _asdict<12> - _field_defaults<13> (builtins.dict[builtins.str<8>, Any]<9>) - _field_types<14> (builtins.dict[builtins.str<8>, Any]<9>) - _fields<15> (tuple[builtins.str<8>, builtins.str<8>]) - _make<16> - _replace<17> - _source<18> (builtins.str<8>) - x<19> (target.A<0>) - y<20> (target.A<0>))) - [case testUnionType_types] import target [file target.py] diff --git a/test-data/unit/native-parser-imports.test b/test-data/unit/native-parser-imports.test index b8dcac283a525..71704788ff7dc 100644 --- a/test-data/unit/native-parser-imports.test +++ b/test-data/unit/native-parser-imports.test @@ -636,13 +636,13 @@ else: 4: import reachable_exactly_310 [case testVersionInfoNotEquals] -# sys.version_info != (3, 9) should be always true for Python 3.10 +# sys.version_info != (3, 11) should be always true for Python 3.10 import sys -if sys.version_info != (3, 9): - import reachable_not_39 +if sys.version_info != (3, 11): + import reachable_not_311 [out] 2: import sys -4: import reachable_not_39 +4: import reachable_not_311 [case testVersionInfoNotEqualsExact] # sys.version_info != (3, 10) should be always false for Python 3.10 diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 4303477549cf3..6038208f98b96 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1735,23 +1735,6 @@ _testEnumNameWorkCorrectlyOn311.py:13: note: Revealed type is "Literal['X']?" _testEnumNameWorkCorrectlyOn311.py:14: note: Revealed type is "int" _testEnumNameWorkCorrectlyOn311.py:15: note: Revealed type is "int" -[case testTypeAliasNotSupportedWithNewStyleUnion] -# flags: --python-version 3.9 -from typing_extensions import TypeAlias -A = type[int] | str -B = str | type[int] -C = str | int -D: TypeAlias = str | int -[out] -_testTypeAliasNotSupportedWithNewStyleUnion.py:3: error: Invalid type alias: expression is not a valid type -_testTypeAliasNotSupportedWithNewStyleUnion.py:3: error: Unsupported left operand type for | ("GenericAlias") -_testTypeAliasNotSupportedWithNewStyleUnion.py:4: error: Invalid type alias: expression is not a valid type -_testTypeAliasNotSupportedWithNewStyleUnion.py:4: error: Unsupported left operand type for | ("type[str]") -_testTypeAliasNotSupportedWithNewStyleUnion.py:5: error: Invalid type alias: expression is not a valid type -_testTypeAliasNotSupportedWithNewStyleUnion.py:5: error: Unsupported left operand type for | ("type[str]") -_testTypeAliasNotSupportedWithNewStyleUnion.py:6: error: Invalid type alias: expression is not a valid type -_testTypeAliasNotSupportedWithNewStyleUnion.py:6: error: Unsupported left operand type for | ("type[str]") - [case testTypedDictUnionGetFull] from typing import Dict from typing_extensions import TypedDict