From 9cedc4fc252ef703ae68fefbf0f81d72a3882869 Mon Sep 17 00:00:00 2001 From: Gatsik <74517072+Gatsik@users.noreply.github.com> Date: Sat, 19 Jul 2025 03:31:01 +0300 Subject: [PATCH 1/7] Add TupleGetterType type --- mypy/checkmember.py | 9 ++++ mypy/constraints.py | 4 ++ mypy/copytype.py | 4 ++ mypy/erasetype.py | 4 ++ mypy/expandtype.py | 4 ++ mypy/fixup.py | 4 ++ mypy/indirection.py | 3 ++ mypy/join.py | 4 ++ mypy/meet.py | 4 ++ mypy/messages.py | 3 ++ mypy/semanal_namedtuple.py | 3 +- mypy/semanal_typeargs.py | 4 ++ mypy/server/astdiff.py | 4 ++ mypy/server/astmerge.py | 4 ++ mypy/server/deps.py | 4 ++ mypy/subtypes.py | 9 ++++ mypy/type_visitor.py | 14 +++++++ mypy/typeanal.py | 7 ++++ mypy/types.py | 22 ++++++++++ mypy/typetraverser.py | 4 ++ test-data/unit/check-class-namedtuple.test | 49 ++++++++++++++++++++++ test-data/unit/fine-grained.test | 2 +- test-data/unit/merge.test | 12 +++--- 23 files changed, 173 insertions(+), 8 deletions(-) diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 7ce7e69e21d8..70bb38c15eba 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -61,6 +61,7 @@ ParamSpecType, PartialType, ProperType, + TupleGetterType, TupleType, Type, TypedDictType, @@ -935,12 +936,20 @@ def analyze_var( return result +def expand_tuplegetter_type_if_needed(typ: Type) -> Type: + proper = get_proper_type(typ) + if isinstance(proper, TupleGetterType): + return proper.typ + return typ + + def expand_without_binding( typ: Type, var: Var, itype: Instance, original_itype: Instance, mx: MemberContext ) -> Type: if not mx.preserve_type_var_ids: typ = freshen_all_functions_type_vars(typ) typ = expand_self_type_if_needed(typ, mx, var, original_itype) + typ = expand_tuplegetter_type_if_needed(typ) expanded = expand_type_by_instance(typ, itype) freeze_all_type_vars(expanded) return expanded diff --git a/mypy/constraints.py b/mypy/constraints.py index 9eeea3cb2c26..e5cc36bd7a41 100644 --- a/mypy/constraints.py +++ b/mypy/constraints.py @@ -36,6 +36,7 @@ ParamSpecType, PartialType, ProperType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -1244,6 +1245,9 @@ def infer_against_overloaded( item = find_matching_overload_item(overloaded, template) return infer_constraints(template, item, self.direction) + def visit_tuplegetter_type(self, template: TupleGetterType) -> list[Constraint]: + raise NotImplementedError + def visit_tuple_type(self, template: TupleType) -> list[Constraint]: actual = self.actual unpack_index = find_unpack_in_list(template.items) diff --git a/mypy/copytype.py b/mypy/copytype.py index ecb1a89759b6..9e4fbd1311bf 100644 --- a/mypy/copytype.py +++ b/mypy/copytype.py @@ -15,6 +15,7 @@ ParamSpecType, PartialType, ProperType, + TupleGetterType, TupleType, TypeAliasType, TypedDictType, @@ -103,6 +104,9 @@ def visit_partial_type(self, t: PartialType) -> ProperType: def visit_callable_type(self, t: CallableType) -> ProperType: return self.copy_common(t, t.copy_modified()) + def visit_tuplegetter_type(self, t: TupleGetterType) -> ProperType: + return self.copy_common(t, TupleGetterType(t.typ)) + def visit_tuple_type(self, t: TupleType) -> ProperType: return self.copy_common(t, TupleType(t.items, t.partial_fallback, implicit=t.implicit)) diff --git a/mypy/erasetype.py b/mypy/erasetype.py index 6c47670d6687..260daf0895a3 100644 --- a/mypy/erasetype.py +++ b/mypy/erasetype.py @@ -17,6 +17,7 @@ ParamSpecType, PartialType, ProperType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -115,6 +116,9 @@ def visit_callable_type(self, t: CallableType) -> ProperType: def visit_overloaded(self, t: Overloaded) -> ProperType: return t.fallback.accept(self) + def visit_tuplegetter_type(self, t: TupleGetterType) -> ProperType: + raise NotImplementedError + def visit_tuple_type(self, t: TupleType) -> ProperType: return t.partial_fallback.accept(self) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index f704df3b010e..36e60b6d2d34 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -23,6 +23,7 @@ PartialType, ProperType, TrivialSyntheticTypeTranslator, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -456,6 +457,9 @@ def expand_type_tuple_with_unpack(self, typs: tuple[Type, ...]) -> list[Type]: items.append(item.accept(self)) return items + def visit_tuplegetter_type(self, t: TupleGetterType) -> Type: + return TupleGetterType(t.typ.accept(self)) + def visit_tuple_type(self, t: TupleType) -> Type: items = self.expand_type_list_with_unpack(t.items) if len(items) == 1: diff --git a/mypy/fixup.py b/mypy/fixup.py index 0e9c186fd42a..47f32ccb9a0c 100644 --- a/mypy/fixup.py +++ b/mypy/fixup.py @@ -29,6 +29,7 @@ Overloaded, Parameters, ParamSpecType, + TupleGetterType, TupleType, TypeAliasType, TypedDictType, @@ -296,6 +297,9 @@ def visit_uninhabited_type(self, o: Any) -> None: def visit_partial_type(self, o: Any) -> None: raise RuntimeError("Shouldn't get here", o) + def visit_tuplegetter_type(self, tgt: TupleGetterType) -> None: + tgt.typ.accept(self) + def visit_tuple_type(self, tt: TupleType) -> None: if tt.items: for it in tt.items: diff --git a/mypy/indirection.py b/mypy/indirection.py index 06a158818fbe..948042fbd34b 100644 --- a/mypy/indirection.py +++ b/mypy/indirection.py @@ -128,6 +128,9 @@ def visit_overloaded(self, t: types.Overloaded) -> None: self._visit_type_list(list(t.items)) self._visit(t.fallback) + def visit_tuplegetter_type(self, t: types.TupleGetterType) -> None: + self._visit(t.typ) + def visit_tuple_type(self, t: types.TupleType) -> None: self._visit_type_list(t.items) self._visit(t.partial_fallback) diff --git a/mypy/join.py b/mypy/join.py index 099df02680f0..83418c10b880 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -32,6 +32,7 @@ ParamSpecType, PartialType, ProperType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -559,6 +560,9 @@ def join_tuples(self, s: TupleType, t: TupleType) -> list[Type] | None: items.append(join_types(fi, vi)) return items + def visit_tuplegetter_type(self, t: TupleGetterType) -> ProperType: + raise NotImplementedError + def visit_tuple_type(self, t: TupleType) -> ProperType: # When given two fixed-length tuples: # * If they have the same length, join their subtypes item-wise: diff --git a/mypy/meet.py b/mypy/meet.py index 2e238be7765e..28cc175b8827 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -32,6 +32,7 @@ ParamSpecType, PartialType, ProperType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -1039,6 +1040,9 @@ def meet_tuples(self, s: TupleType, t: TupleType) -> list[Type] | None: items.append(self.meet(fi, vi)) return items + def visit_tuplegetter_type(self, t: TupleGetterType) -> ProperType: + raise NotImplementedError + def visit_tuple_type(self, t: TupleType) -> ProperType: if isinstance(self.s, TupleType): items = self.meet_tuples(self.s, t) diff --git a/mypy/messages.py b/mypy/messages.py index 44ed25a19517..3d9cf098bb64 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -84,6 +84,7 @@ ParamSpecType, PartialType, ProperType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -2664,6 +2665,8 @@ def format_literal_value(typ: LiteralType) -> str: else: # TODO: better disambiguate ParamSpec name clashes. return typ.name_with_suffix() + elif isinstance(typ, TupleGetterType): + return f"TupleGetterType[{typ.typ}]" elif isinstance(typ, TupleType): # Prefer the name of the fallback class (if not tuple), as it's more informative. if typ.partial_fallback.type.fullname != "builtins.tuple": diff --git a/mypy/semanal_namedtuple.py b/mypy/semanal_namedtuple.py index b67747d16887..2555b0a0c6bc 100644 --- a/mypy/semanal_namedtuple.py +++ b/mypy/semanal_namedtuple.py @@ -59,6 +59,7 @@ AnyType, CallableType, LiteralType, + TupleGetterType, TupleType, Type, TypeOfAny, @@ -552,7 +553,7 @@ def add_field( var._fullname = f"{info.fullname}.{var.name}" info.names[var.name] = SymbolTableNode(MDEF, var) - fields = [Var(item, typ) for item, typ in zip(items, types)] + fields = [Var(item, TupleGetterType(typ)) for item, typ in zip(items, types)] for var in fields: add_field(var, is_property=True) # We can't share Vars between fields and method arguments, since they diff --git a/mypy/semanal_typeargs.py b/mypy/semanal_typeargs.py index 435abb78ca43..558e8f4e0908 100644 --- a/mypy/semanal_typeargs.py +++ b/mypy/semanal_typeargs.py @@ -25,6 +25,7 @@ Instance, Parameters, ParamSpecType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -103,6 +104,9 @@ def visit_type_alias_type(self, t: TypeAliasType) -> None: # the expansion, most likely it will result in the same kind of error. get_proper_type(t).accept(self) + def visit_tuplegetter_type(self, t: TupleGetterType) -> None: + raise NotImplementedError + def visit_tuple_type(self, t: TupleType) -> None: t.items = flatten_nested_tuples(t.items) # We could also normalize Tuple[*tuple[X, ...]] -> tuple[X, ...] like in diff --git a/mypy/server/astdiff.py b/mypy/server/astdiff.py index 16a0d882a8aa..64a0a2716e91 100644 --- a/mypy/server/astdiff.py +++ b/mypy/server/astdiff.py @@ -88,6 +88,7 @@ class level -- these are handled at attribute level (say, 'mod.Cls.method' Parameters, ParamSpecType, PartialType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -481,6 +482,9 @@ def normalize_callable_variables(self, typ: CallableType) -> CallableType: with state.strict_optional_set(True): return expand_type(typ, tvmap).copy_modified(variables=tvs) + def visit_tuplegetter_type(self, typ: TupleGetterType) -> SnapshotItem: + return ("TupleGetterType", snapshot_type(typ.typ)) + def visit_tuple_type(self, typ: TupleType) -> SnapshotItem: return ("TupleType", snapshot_types(typ.items)) diff --git a/mypy/server/astmerge.py b/mypy/server/astmerge.py index 33e2d2b799cb..446bc5ea0116 100644 --- a/mypy/server/astmerge.py +++ b/mypy/server/astmerge.py @@ -96,6 +96,7 @@ PlaceholderType, RawExpressionType, SyntheticTypeVisitor, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -470,6 +471,9 @@ def visit_deleted_type(self, typ: DeletedType) -> None: def visit_partial_type(self, typ: PartialType) -> None: raise RuntimeError("Cannot handle partial type") + def visit_tuplegetter_type(self, typ: TupleGetterType) -> None: + typ.typ.accept(self) + def visit_tuple_type(self, typ: TupleType) -> None: for item in typ.items: item.accept(self) diff --git a/mypy/server/deps.py b/mypy/server/deps.py index b994a214f67a..da40beed00d9 100644 --- a/mypy/server/deps.py +++ b/mypy/server/deps.py @@ -157,6 +157,7 @@ class 'mod.Cls'. This can also refer to an attribute inherited from a ParamSpecType, PartialType, ProperType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -1017,6 +1018,9 @@ def visit_deleted_type(self, typ: DeletedType) -> list[str]: def visit_partial_type(self, typ: PartialType) -> list[str]: assert False, "Should not see a partial type here" + def visit_tuplegetter_type(self, typ: TupleGetterType) -> list[str]: + return typ.typ.accept(self) + def visit_tuple_type(self, typ: TupleType) -> list[str]: triggers = [] for item in typ.items: diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 7da258a827f3..dbdac4c02d57 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -55,6 +55,7 @@ ParamSpecType, PartialType, ProperType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -759,6 +760,14 @@ def visit_callable_type(self, left: CallableType) -> bool: else: return False + def visit_tuplegetter_type(self, left: TupleGetterType) -> bool: + right = self.right + if isinstance(right, TupleGetterType): + return left.typ == right.typ + elif isinstance(right, Instance): + return self.is_top_type(right) + return False + def visit_tuple_type(self, left: TupleType) -> bool: right = self.right if isinstance(right, Instance): diff --git a/mypy/type_visitor.py b/mypy/type_visitor.py index ab1ec8b46fdd..8d30fbb386f0 100644 --- a/mypy/type_visitor.py +++ b/mypy/type_visitor.py @@ -35,6 +35,7 @@ PartialType, PlaceholderType, RawExpressionType, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -114,6 +115,10 @@ def visit_callable_type(self, t: CallableType, /) -> T: def visit_overloaded(self, t: Overloaded, /) -> T: pass + @abstractmethod + def visit_tuplegetter_type(self, t: TupleGetterType, /) -> T: + pass + @abstractmethod def visit_tuple_type(self, t: TupleType, /) -> T: pass @@ -260,6 +265,9 @@ def visit_callable_type(self, t: CallableType, /) -> Type: variables=self.translate_variables(t.variables), ) + def visit_tuplegetter_type(self, t: TupleGetterType, /) -> Type: + return TupleGetterType(t.typ.accept(self)) + def visit_tuple_type(self, t: TupleType, /) -> Type: return TupleType( self.translate_types(t.items), @@ -412,6 +420,9 @@ def visit_callable_type(self, t: CallableType, /) -> T: def visit_tuple_type(self, t: TupleType, /) -> T: return self.query_types([t.partial_fallback] + t.items) + def visit_tuplegetter_type(self, t: TupleGetterType, /) -> T: + return self.query_types([t.typ]) + def visit_typeddict_type(self, t: TypedDictType, /) -> T: return self.query_types(t.items.values()) @@ -549,6 +560,9 @@ def visit_callable_type(self, t: CallableType, /) -> bool: else: return args and ret + def visit_tuplegetter_type(self, t: TupleGetterType, /) -> bool: + return self.default + def visit_tuple_type(self, t: TupleType, /) -> bool: return self.query_types([t.partial_fallback] + t.items) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 204d3061c734..f12c51cad840 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -92,6 +92,7 @@ RequiredType, SyntheticTypeVisitor, TrivialSyntheticTypeTranslator, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -1261,6 +1262,9 @@ def visit_overloaded(self, t: Overloaded) -> Type: # fine to just return it as-is. return t + def visit_tuplegetter_type(self, t: TupleGetterType) -> Type: + raise NotImplementedError + def visit_tuple_type(self, t: TupleType) -> Type: # Types such as (t1, t2, ...) only allowed in assignment statements. They'll # generate errors elsewhere, and Tuple[t1, t2, ...] must be used instead. @@ -2637,6 +2641,9 @@ def visit_callable_type(self, t: CallableType) -> None: self.process_types(t.arg_types) t.ret_type.accept(self) + def visit_tuplegetter_type(self, t: TupleGetterType) -> None: + raise NotImplementedError + def visit_tuple_type(self, t: TupleType) -> None: self.process_types(t.items) diff --git a/mypy/types.py b/mypy/types.py index e9d299dbc8fc..c6f9c975212b 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -2404,6 +2404,25 @@ def deserialize(cls, data: JsonDict) -> Overloaded: return Overloaded([CallableType.deserialize(t) for t in data["items"]]) +class TupleGetterType(ProperType): + __slots__ = ("typ",) + + def __init__(self, typ: Type) -> None: + super().__init__(typ.line, typ.column) + self.typ = typ + + def serialize(self) -> JsonDict: + return {".class": "TupleGetterType", "type": self.typ.serialize()} + + @classmethod + def deserialize(cls, data: JsonDict) -> TupleGetterType: + assert data[".class"] == "TupleGetterType" + return TupleGetterType(deserialize_type(data["type"])) + + def accept(self, visitor: TypeVisitor[T]) -> T: + return visitor.visit_tuplegetter_type(self) + + class TupleType(ProperType): """The tuple type Tuple[T1, ..., Tn] (at least one type argument). @@ -3470,6 +3489,9 @@ def visit_overloaded(self, t: Overloaded, /) -> str: a.append(i.accept(self)) return f"Overload({', '.join(a)})" + def visit_tuplegetter_type(self, t: TupleGetterType, /) -> str: + return f"TupleGetterType[{t.typ.accept(self)}]" + def visit_tuple_type(self, t: TupleType, /) -> str: s = self.list_str(t.items) or "()" if t.partial_fallback and t.partial_fallback.type: diff --git a/mypy/typetraverser.py b/mypy/typetraverser.py index 047c5caf6dae..b4611f35447f 100644 --- a/mypy/typetraverser.py +++ b/mypy/typetraverser.py @@ -21,6 +21,7 @@ PlaceholderType, RawExpressionType, SyntheticTypeVisitor, + TupleGetterType, TupleType, Type, TypeAliasType, @@ -92,6 +93,9 @@ def visit_callable_type(self, t: CallableType, /) -> None: if t.type_is is not None: t.type_is.accept(self) + def visit_tuplegetter_type(self, t: TupleGetterType, /) -> None: + t.typ.accept(self) + def visit_tuple_type(self, t: TupleType, /) -> None: self.traverse_type_list(t.items) t.partial_fallback.accept(self) diff --git a/test-data/unit/check-class-namedtuple.test b/test-data/unit/check-class-namedtuple.test index fe8a1551f81b..d44280babd5c 100644 --- a/test-data/unit/check-class-namedtuple.test +++ b/test-data/unit/check-class-namedtuple.test @@ -683,3 +683,52 @@ reveal_type(y) # N: Revealed type is "builtins.int" point.y = 6 # E: Property "y" defined in "Point" is read-only [builtins fixtures/tuple.pyi] + +[case testNamedTupleClassAttributeAccess] +from typing import NamedTuple + +class A(NamedTuple): + x: str + +reveal_type(A.x) # N: Revealed type is "TupleGetterType[builtins.str]" +A.x + 3 # E: Unsupported left operand type for + ("TupleGetterType[builtins.str]") +A.y # E: "type[A]" has no attribute "y" + +[builtins fixtures/tuple.pyi] + +[case testNamedTupleTupleGetterIsCompatibleWithObject] +from typing import NamedTuple + +class A(NamedTuple): + x: str = "x" + +a: object = A.x +b: int = A.x # E: Incompatible types in assignment (expression has type "TupleGetterType[builtins.str]", variable has type "int") +[builtins fixtures/tuple.pyi] + +[case testNamedTupleTupleGetterNested] +from typing import NamedTuple + +class Inner(NamedTuple): + x: int + +class Outer(NamedTuple): + y: Inner + +reveal_type(Inner.x) # N: Revealed type is "TupleGetterType[builtins.int]" +reveal_type(Outer.y) # N: Revealed type is "TupleGetterType[tuple[builtins.int, fallback=__main__.Inner]]" +[builtins fixtures/tuple.pyi] + +[case testNamedTupleTupleGetterGeneric] +from typing import Generic +from typing import NamedTuple +from typing import TypeVar + +T = TypeVar("T") + +class GenericTuple(NamedTuple, Generic[T]): + x: T + +reveal_type(GenericTuple.x) # E: Access to generic instance variables via class is ambiguous \ + # N: Revealed type is "TupleGetterType[Any]" +[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index 503135d901f8..786549c2cf26 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -8685,7 +8685,7 @@ m.py:4: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#varia == m.py:4: error: Variable "a.A" is not valid as a type m.py:4: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -m.py:5: note: Revealed type is "Any" +m.py:5: note: Revealed type is "TupleGetterType[Any]" m.py:7: note: Revealed type is "Any" [case testAliasForwardFunctionDirect] diff --git a/test-data/unit/merge.test b/test-data/unit/merge.test index 7463571b76b4..13546b0f3d92 100644 --- a/test-data/unit/merge.test +++ b/test-data/unit/merge.test @@ -680,7 +680,7 @@ TypeInfo<2>( _make<17> _replace<18> _source<19> (builtins.str<8>) - x<20> (target.A<0>))) + x<20> (TupleGetterType[target.A<0>]))) ==> TypeInfo<0>( Name(target.A) @@ -704,8 +704,8 @@ TypeInfo<2>( _make<17> _replace<18> _source<19> (builtins.str<8>) - x<20> (target.A<0>) - y<21> (target.A<0>))) + x<20> (TupleGetterType[target.A<0>]) + y<21> (TupleGetterType[target.A<0>]))) [case testNamedTupleOldVersion_typeinfo] import target @@ -740,7 +740,7 @@ TypeInfo<2>( _make<16> _replace<17> _source<18> (builtins.str<8>) - x<19> (target.A<0>))) + x<19> (TupleGetterType[target.A<0>]))) ==> TypeInfo<0>( Name(target.A) @@ -763,8 +763,8 @@ TypeInfo<2>( _make<16> _replace<17> _source<18> (builtins.str<8>) - x<19> (target.A<0>) - y<20> (target.A<0>))) + x<19> (TupleGetterType[target.A<0>]) + y<20> (TupleGetterType[target.A<0>]))) [case testUnionType_types] import target From 84a520274a574804845e22563a35b34fdae8b8d9 Mon Sep 17 00:00:00 2001 From: Gatsik <74517072+Gatsik@users.noreply.github.com> Date: Mon, 21 Jul 2025 09:55:27 +0300 Subject: [PATCH 2/7] Remove `TupleGetterType` in favour of `api.named_type("collections._tuplegetter")` --- mypy/checkmember.py | 9 ----- mypy/constraints.py | 4 -- mypy/copytype.py | 4 -- mypy/erasetype.py | 4 -- mypy/expandtype.py | 4 -- mypy/fixup.py | 4 -- mypy/indirection.py | 3 -- mypy/join.py | 4 -- mypy/meet.py | 4 -- mypy/messages.py | 3 -- mypy/semanal_namedtuple.py | 6 ++- mypy/semanal_typeargs.py | 4 -- mypy/server/astdiff.py | 4 -- mypy/server/astmerge.py | 4 -- mypy/server/deps.py | 4 -- mypy/subtypes.py | 9 ----- mypy/test/teststubtest.py | 4 +- mypy/type_visitor.py | 14 ------- mypy/typeanal.py | 7 ---- mypy/types.py | 22 ----------- mypy/typetraverser.py | 4 -- test-data/unit/check-basic.test | 2 +- test-data/unit/check-callable.test | 2 +- test-data/unit/check-class-namedtuple.test | 43 +++++++++++----------- test-data/unit/check-classes.test | 20 +++++----- test-data/unit/check-custom-plugin.test | 2 +- test-data/unit/check-enum.test | 1 - test-data/unit/check-expressions.test | 4 +- test-data/unit/check-flags.test | 6 +-- test-data/unit/check-incremental.test | 24 ++++++------ test-data/unit/check-inference.test | 4 +- test-data/unit/check-literal.test | 6 +-- test-data/unit/check-namedtuple.test | 22 +++++------ test-data/unit/check-narrowing.test | 8 ++-- test-data/unit/check-newsemanal.test | 6 +-- test-data/unit/check-protocols.test | 6 +-- test-data/unit/check-python310.test | 2 +- test-data/unit/check-recursive-types.test | 4 +- test-data/unit/check-semanal-error.test | 2 +- test-data/unit/check-statements.test | 4 +- test-data/unit/check-type-aliases.test | 2 +- test-data/unit/check-unions.test | 4 +- test-data/unit/deps-classes.test | 3 ++ test-data/unit/deps-types.test | 1 + test-data/unit/fine-grained.test | 4 +- test-data/unit/fixtures/tuple.pyi | 39 +++++++++++++++++--- test-data/unit/lib-stub/collections.pyi | 8 +++- test-data/unit/merge.test | 12 +++--- 48 files changed, 146 insertions(+), 220 deletions(-) diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 70bb38c15eba..7ce7e69e21d8 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -61,7 +61,6 @@ ParamSpecType, PartialType, ProperType, - TupleGetterType, TupleType, Type, TypedDictType, @@ -936,20 +935,12 @@ def analyze_var( return result -def expand_tuplegetter_type_if_needed(typ: Type) -> Type: - proper = get_proper_type(typ) - if isinstance(proper, TupleGetterType): - return proper.typ - return typ - - def expand_without_binding( typ: Type, var: Var, itype: Instance, original_itype: Instance, mx: MemberContext ) -> Type: if not mx.preserve_type_var_ids: typ = freshen_all_functions_type_vars(typ) typ = expand_self_type_if_needed(typ, mx, var, original_itype) - typ = expand_tuplegetter_type_if_needed(typ) expanded = expand_type_by_instance(typ, itype) freeze_all_type_vars(expanded) return expanded diff --git a/mypy/constraints.py b/mypy/constraints.py index e5cc36bd7a41..9eeea3cb2c26 100644 --- a/mypy/constraints.py +++ b/mypy/constraints.py @@ -36,7 +36,6 @@ ParamSpecType, PartialType, ProperType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -1245,9 +1244,6 @@ def infer_against_overloaded( item = find_matching_overload_item(overloaded, template) return infer_constraints(template, item, self.direction) - def visit_tuplegetter_type(self, template: TupleGetterType) -> list[Constraint]: - raise NotImplementedError - def visit_tuple_type(self, template: TupleType) -> list[Constraint]: actual = self.actual unpack_index = find_unpack_in_list(template.items) diff --git a/mypy/copytype.py b/mypy/copytype.py index 9e4fbd1311bf..ecb1a89759b6 100644 --- a/mypy/copytype.py +++ b/mypy/copytype.py @@ -15,7 +15,6 @@ ParamSpecType, PartialType, ProperType, - TupleGetterType, TupleType, TypeAliasType, TypedDictType, @@ -104,9 +103,6 @@ def visit_partial_type(self, t: PartialType) -> ProperType: def visit_callable_type(self, t: CallableType) -> ProperType: return self.copy_common(t, t.copy_modified()) - def visit_tuplegetter_type(self, t: TupleGetterType) -> ProperType: - return self.copy_common(t, TupleGetterType(t.typ)) - def visit_tuple_type(self, t: TupleType) -> ProperType: return self.copy_common(t, TupleType(t.items, t.partial_fallback, implicit=t.implicit)) diff --git a/mypy/erasetype.py b/mypy/erasetype.py index 260daf0895a3..6c47670d6687 100644 --- a/mypy/erasetype.py +++ b/mypy/erasetype.py @@ -17,7 +17,6 @@ ParamSpecType, PartialType, ProperType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -116,9 +115,6 @@ def visit_callable_type(self, t: CallableType) -> ProperType: def visit_overloaded(self, t: Overloaded) -> ProperType: return t.fallback.accept(self) - def visit_tuplegetter_type(self, t: TupleGetterType) -> ProperType: - raise NotImplementedError - def visit_tuple_type(self, t: TupleType) -> ProperType: return t.partial_fallback.accept(self) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 36e60b6d2d34..f704df3b010e 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -23,7 +23,6 @@ PartialType, ProperType, TrivialSyntheticTypeTranslator, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -457,9 +456,6 @@ def expand_type_tuple_with_unpack(self, typs: tuple[Type, ...]) -> list[Type]: items.append(item.accept(self)) return items - def visit_tuplegetter_type(self, t: TupleGetterType) -> Type: - return TupleGetterType(t.typ.accept(self)) - def visit_tuple_type(self, t: TupleType) -> Type: items = self.expand_type_list_with_unpack(t.items) if len(items) == 1: diff --git a/mypy/fixup.py b/mypy/fixup.py index 47f32ccb9a0c..0e9c186fd42a 100644 --- a/mypy/fixup.py +++ b/mypy/fixup.py @@ -29,7 +29,6 @@ Overloaded, Parameters, ParamSpecType, - TupleGetterType, TupleType, TypeAliasType, TypedDictType, @@ -297,9 +296,6 @@ def visit_uninhabited_type(self, o: Any) -> None: def visit_partial_type(self, o: Any) -> None: raise RuntimeError("Shouldn't get here", o) - def visit_tuplegetter_type(self, tgt: TupleGetterType) -> None: - tgt.typ.accept(self) - def visit_tuple_type(self, tt: TupleType) -> None: if tt.items: for it in tt.items: diff --git a/mypy/indirection.py b/mypy/indirection.py index 948042fbd34b..06a158818fbe 100644 --- a/mypy/indirection.py +++ b/mypy/indirection.py @@ -128,9 +128,6 @@ def visit_overloaded(self, t: types.Overloaded) -> None: self._visit_type_list(list(t.items)) self._visit(t.fallback) - def visit_tuplegetter_type(self, t: types.TupleGetterType) -> None: - self._visit(t.typ) - def visit_tuple_type(self, t: types.TupleType) -> None: self._visit_type_list(t.items) self._visit(t.partial_fallback) diff --git a/mypy/join.py b/mypy/join.py index 83418c10b880..099df02680f0 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -32,7 +32,6 @@ ParamSpecType, PartialType, ProperType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -560,9 +559,6 @@ def join_tuples(self, s: TupleType, t: TupleType) -> list[Type] | None: items.append(join_types(fi, vi)) return items - def visit_tuplegetter_type(self, t: TupleGetterType) -> ProperType: - raise NotImplementedError - def visit_tuple_type(self, t: TupleType) -> ProperType: # When given two fixed-length tuples: # * If they have the same length, join their subtypes item-wise: diff --git a/mypy/meet.py b/mypy/meet.py index 28cc175b8827..2e238be7765e 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -32,7 +32,6 @@ ParamSpecType, PartialType, ProperType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -1040,9 +1039,6 @@ def meet_tuples(self, s: TupleType, t: TupleType) -> list[Type] | None: items.append(self.meet(fi, vi)) return items - def visit_tuplegetter_type(self, t: TupleGetterType) -> ProperType: - raise NotImplementedError - def visit_tuple_type(self, t: TupleType) -> ProperType: if isinstance(self.s, TupleType): items = self.meet_tuples(self.s, t) diff --git a/mypy/messages.py b/mypy/messages.py index 3d9cf098bb64..44ed25a19517 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -84,7 +84,6 @@ ParamSpecType, PartialType, ProperType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -2665,8 +2664,6 @@ def format_literal_value(typ: LiteralType) -> str: else: # TODO: better disambiguate ParamSpec name clashes. return typ.name_with_suffix() - elif isinstance(typ, TupleGetterType): - return f"TupleGetterType[{typ.typ}]" elif isinstance(typ, TupleType): # Prefer the name of the fallback class (if not tuple), as it's more informative. if typ.partial_fallback.type.fullname != "builtins.tuple": diff --git a/mypy/semanal_namedtuple.py b/mypy/semanal_namedtuple.py index 2555b0a0c6bc..48dd2b868a54 100644 --- a/mypy/semanal_namedtuple.py +++ b/mypy/semanal_namedtuple.py @@ -59,7 +59,6 @@ AnyType, CallableType, LiteralType, - TupleGetterType, TupleType, Type, TypeOfAny, @@ -553,7 +552,10 @@ def add_field( var._fullname = f"{info.fullname}.{var.name}" info.names[var.name] = SymbolTableNode(MDEF, var) - fields = [Var(item, TupleGetterType(typ)) for item, typ in zip(items, types)] + fields = [ + Var(item, self.api.named_type("collections._tuplegetter", [typ])) + for item, typ in zip(items, types) + ] for var in fields: add_field(var, is_property=True) # We can't share Vars between fields and method arguments, since they diff --git a/mypy/semanal_typeargs.py b/mypy/semanal_typeargs.py index 558e8f4e0908..435abb78ca43 100644 --- a/mypy/semanal_typeargs.py +++ b/mypy/semanal_typeargs.py @@ -25,7 +25,6 @@ Instance, Parameters, ParamSpecType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -104,9 +103,6 @@ def visit_type_alias_type(self, t: TypeAliasType) -> None: # the expansion, most likely it will result in the same kind of error. get_proper_type(t).accept(self) - def visit_tuplegetter_type(self, t: TupleGetterType) -> None: - raise NotImplementedError - def visit_tuple_type(self, t: TupleType) -> None: t.items = flatten_nested_tuples(t.items) # We could also normalize Tuple[*tuple[X, ...]] -> tuple[X, ...] like in diff --git a/mypy/server/astdiff.py b/mypy/server/astdiff.py index 64a0a2716e91..16a0d882a8aa 100644 --- a/mypy/server/astdiff.py +++ b/mypy/server/astdiff.py @@ -88,7 +88,6 @@ class level -- these are handled at attribute level (say, 'mod.Cls.method' Parameters, ParamSpecType, PartialType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -482,9 +481,6 @@ def normalize_callable_variables(self, typ: CallableType) -> CallableType: with state.strict_optional_set(True): return expand_type(typ, tvmap).copy_modified(variables=tvs) - def visit_tuplegetter_type(self, typ: TupleGetterType) -> SnapshotItem: - return ("TupleGetterType", snapshot_type(typ.typ)) - def visit_tuple_type(self, typ: TupleType) -> SnapshotItem: return ("TupleType", snapshot_types(typ.items)) diff --git a/mypy/server/astmerge.py b/mypy/server/astmerge.py index 446bc5ea0116..33e2d2b799cb 100644 --- a/mypy/server/astmerge.py +++ b/mypy/server/astmerge.py @@ -96,7 +96,6 @@ PlaceholderType, RawExpressionType, SyntheticTypeVisitor, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -471,9 +470,6 @@ def visit_deleted_type(self, typ: DeletedType) -> None: def visit_partial_type(self, typ: PartialType) -> None: raise RuntimeError("Cannot handle partial type") - def visit_tuplegetter_type(self, typ: TupleGetterType) -> None: - typ.typ.accept(self) - def visit_tuple_type(self, typ: TupleType) -> None: for item in typ.items: item.accept(self) diff --git a/mypy/server/deps.py b/mypy/server/deps.py index da40beed00d9..b994a214f67a 100644 --- a/mypy/server/deps.py +++ b/mypy/server/deps.py @@ -157,7 +157,6 @@ class 'mod.Cls'. This can also refer to an attribute inherited from a ParamSpecType, PartialType, ProperType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -1018,9 +1017,6 @@ def visit_deleted_type(self, typ: DeletedType) -> list[str]: def visit_partial_type(self, typ: PartialType) -> list[str]: assert False, "Should not see a partial type here" - def visit_tuplegetter_type(self, typ: TupleGetterType) -> list[str]: - return typ.typ.accept(self) - def visit_tuple_type(self, typ: TupleType) -> list[str]: triggers = [] for item in typ.items: diff --git a/mypy/subtypes.py b/mypy/subtypes.py index dbdac4c02d57..7da258a827f3 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -55,7 +55,6 @@ ParamSpecType, PartialType, ProperType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -760,14 +759,6 @@ def visit_callable_type(self, left: CallableType) -> bool: else: return False - def visit_tuplegetter_type(self, left: TupleGetterType) -> bool: - right = self.right - if isinstance(right, TupleGetterType): - return left.typ == right.typ - elif isinstance(right, Instance): - return self.is_top_type(right) - return False - def visit_tuple_type(self, left: TupleType) -> bool: right = self.right if isinstance(right, Instance): diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 7925f2a6bd3e..d14e3d81f7b1 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -2097,7 +2097,7 @@ class Y(TypedDict): @collect_cases def test_named_tuple(self) -> Iterator[Case]: yield Case( - stub="from typing import NamedTuple", + stub="from typing import NamedTuple; import collections", runtime="from typing import NamedTuple", error=None, ) @@ -2133,7 +2133,7 @@ class X2(NamedTuple): @collect_cases def test_named_tuple_typing_and_collections(self) -> Iterator[Case]: yield Case( - stub="from typing import NamedTuple", + stub="from typing import NamedTuple; import collections", runtime="from collections import namedtuple", error=None, ) diff --git a/mypy/type_visitor.py b/mypy/type_visitor.py index 8d30fbb386f0..ab1ec8b46fdd 100644 --- a/mypy/type_visitor.py +++ b/mypy/type_visitor.py @@ -35,7 +35,6 @@ PartialType, PlaceholderType, RawExpressionType, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -115,10 +114,6 @@ def visit_callable_type(self, t: CallableType, /) -> T: def visit_overloaded(self, t: Overloaded, /) -> T: pass - @abstractmethod - def visit_tuplegetter_type(self, t: TupleGetterType, /) -> T: - pass - @abstractmethod def visit_tuple_type(self, t: TupleType, /) -> T: pass @@ -265,9 +260,6 @@ def visit_callable_type(self, t: CallableType, /) -> Type: variables=self.translate_variables(t.variables), ) - def visit_tuplegetter_type(self, t: TupleGetterType, /) -> Type: - return TupleGetterType(t.typ.accept(self)) - def visit_tuple_type(self, t: TupleType, /) -> Type: return TupleType( self.translate_types(t.items), @@ -420,9 +412,6 @@ def visit_callable_type(self, t: CallableType, /) -> T: def visit_tuple_type(self, t: TupleType, /) -> T: return self.query_types([t.partial_fallback] + t.items) - def visit_tuplegetter_type(self, t: TupleGetterType, /) -> T: - return self.query_types([t.typ]) - def visit_typeddict_type(self, t: TypedDictType, /) -> T: return self.query_types(t.items.values()) @@ -560,9 +549,6 @@ def visit_callable_type(self, t: CallableType, /) -> bool: else: return args and ret - def visit_tuplegetter_type(self, t: TupleGetterType, /) -> bool: - return self.default - def visit_tuple_type(self, t: TupleType, /) -> bool: return self.query_types([t.partial_fallback] + t.items) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index f12c51cad840..204d3061c734 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -92,7 +92,6 @@ RequiredType, SyntheticTypeVisitor, TrivialSyntheticTypeTranslator, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -1262,9 +1261,6 @@ def visit_overloaded(self, t: Overloaded) -> Type: # fine to just return it as-is. return t - def visit_tuplegetter_type(self, t: TupleGetterType) -> Type: - raise NotImplementedError - def visit_tuple_type(self, t: TupleType) -> Type: # Types such as (t1, t2, ...) only allowed in assignment statements. They'll # generate errors elsewhere, and Tuple[t1, t2, ...] must be used instead. @@ -2641,9 +2637,6 @@ def visit_callable_type(self, t: CallableType) -> None: self.process_types(t.arg_types) t.ret_type.accept(self) - def visit_tuplegetter_type(self, t: TupleGetterType) -> None: - raise NotImplementedError - def visit_tuple_type(self, t: TupleType) -> None: self.process_types(t.items) diff --git a/mypy/types.py b/mypy/types.py index c6f9c975212b..e9d299dbc8fc 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -2404,25 +2404,6 @@ def deserialize(cls, data: JsonDict) -> Overloaded: return Overloaded([CallableType.deserialize(t) for t in data["items"]]) -class TupleGetterType(ProperType): - __slots__ = ("typ",) - - def __init__(self, typ: Type) -> None: - super().__init__(typ.line, typ.column) - self.typ = typ - - def serialize(self) -> JsonDict: - return {".class": "TupleGetterType", "type": self.typ.serialize()} - - @classmethod - def deserialize(cls, data: JsonDict) -> TupleGetterType: - assert data[".class"] == "TupleGetterType" - return TupleGetterType(deserialize_type(data["type"])) - - def accept(self, visitor: TypeVisitor[T]) -> T: - return visitor.visit_tuplegetter_type(self) - - class TupleType(ProperType): """The tuple type Tuple[T1, ..., Tn] (at least one type argument). @@ -3489,9 +3470,6 @@ def visit_overloaded(self, t: Overloaded, /) -> str: a.append(i.accept(self)) return f"Overload({', '.join(a)})" - def visit_tuplegetter_type(self, t: TupleGetterType, /) -> str: - return f"TupleGetterType[{t.typ.accept(self)}]" - def visit_tuple_type(self, t: TupleType, /) -> str: s = self.list_str(t.items) or "()" if t.partial_fallback and t.partial_fallback.type: diff --git a/mypy/typetraverser.py b/mypy/typetraverser.py index b4611f35447f..047c5caf6dae 100644 --- a/mypy/typetraverser.py +++ b/mypy/typetraverser.py @@ -21,7 +21,6 @@ PlaceholderType, RawExpressionType, SyntheticTypeVisitor, - TupleGetterType, TupleType, Type, TypeAliasType, @@ -93,9 +92,6 @@ def visit_callable_type(self, t: CallableType, /) -> None: if t.type_is is not None: t.type_is.accept(self) - def visit_tuplegetter_type(self, t: TupleGetterType, /) -> None: - t.typ.accept(self) - def visit_tuple_type(self, t: TupleType, /) -> None: self.traverse_type_list(t.items) t.partial_fallback.accept(self) diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index 07ed5fd77082..7e50447d3046 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -462,7 +462,7 @@ def typeddict() -> Sequence[D]: a = (a.A(), A()) a.x # E: "tuple[a.A, b.A]" has no attribute "x" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-full.pyi] [case testReturnAnyFromFunctionDeclaredToReturnObject] diff --git a/test-data/unit/check-callable.test b/test-data/unit/check-callable.test index 23db0bf50a4e..d71d15cd8945 100644 --- a/test-data/unit/check-callable.test +++ b/test-data/unit/check-callable.test @@ -491,7 +491,7 @@ def g(o: Thing) -> None: i + s # E: Unsupported operand types for + ("str" and "int") o(1,2,3) -[builtins fixtures/callable.pyi] +[builtins fixtures/tuple.pyi] [case testCallableNoArgs] diff --git a/test-data/unit/check-class-namedtuple.test b/test-data/unit/check-class-namedtuple.test index d44280babd5c..dda6fee2468c 100644 --- a/test-data/unit/check-class-namedtuple.test +++ b/test-data/unit/check-class-namedtuple.test @@ -214,7 +214,7 @@ i, i = l[0] # E: Need more than 1 value to unpack (2 expected) l = [A(1)] a = (1,) # E: Incompatible types in assignment (expression has type "tuple[int]", \ variable has type "A") -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleMissingClassAttribute] from typing import NamedTuple @@ -259,7 +259,7 @@ class C(B): pass B(1).b C(2).b -[builtins fixtures/property.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleAsDict] from typing import NamedTuple, Any @@ -271,7 +271,7 @@ class X(NamedTuple): x: X reveal_type(x._asdict()) # N: Revealed type is "builtins.dict[builtins.str, Any]" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleReplaceTyped] from typing import NamedTuple @@ -301,7 +301,7 @@ reveal_type(X._field_defaults) # N: Revealed type is "builtins.dict[builtins.st # but it's inferred as `Mapping[str, object]` here due to the fixture we're using reveal_type(X.__annotations__) # N: Revealed type is "typing.Mapping[builtins.str, builtins.object]" -[builtins fixtures/dict-full.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleUnit] from typing import NamedTuple @@ -326,7 +326,7 @@ class Y(NamedTuple): reveal_type([X(3, 'b'), Y(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleJoinTuple] from typing import NamedTuple @@ -338,7 +338,7 @@ class X(NamedTuple): reveal_type([(3, 'b'), X(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" reveal_type([X(1, 'a'), (3, 'b')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleWithTooManyArguments] from typing import NamedTuple @@ -358,7 +358,7 @@ class X(typing.NamedTuple): x.x: int # E: Invalid statement in NamedTuple definition; expected "field_name: field_type [= default]" z: str = 'z' aa: int # E: Non-default NamedTuple fields cannot follow default fields -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleWithoutTypesSpecified] from typing import NamedTuple @@ -377,7 +377,7 @@ class N(NamedTuple): def f(a: Type[N]): a() # E: Missing positional arguments "x", "y" in call to "N" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleWithDefaults] from typing import List, NamedTuple, Optional @@ -416,7 +416,7 @@ reveal_type(UserDefined()) # N: Revealed type is "tuple[__main__.Default, fallb reveal_type(UserDefined(Default())) # N: Revealed type is "tuple[__main__.Default, fallback=__main__.UserDefined]" UserDefined(1) # E: Argument 1 to "UserDefined" has incompatible type "int"; expected "Default" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleWithDefaultsStrictOptional] from typing import List, NamedTuple, Optional @@ -434,7 +434,7 @@ class CannotBeNone(NamedTuple): x: int y: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleWrongType] from typing import NamedTuple @@ -448,7 +448,8 @@ class X(NamedTuple): from typing import NamedTuple class X(NamedTuple): - x: int = 1 + '1' # E: Unsupported left operand type for + ("int") + x: int = 1 + '1' # E: Incompatible types in assignment (expression has type "str", variable has type "int") \ + # E: Unsupported operand types for + ("int" and "str") [builtins fixtures/tuple.pyi] [case testNewNamedTupleInheritance] @@ -607,7 +608,7 @@ class ReuseCallableNamed(NamedTuple): def z(self) -> int: # E: Name "z" already defined on line 31 return 0 -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleDocString] from typing import NamedTuple @@ -639,7 +640,7 @@ class HasClassMethod(NamedTuple): reveal_type(HasClassMethod) # N: Revealed type is "def (x: builtins.str) -> tuple[builtins.str, fallback=__main__.HasClassMethod]" return cls(x=f) -[builtins fixtures/classmethod.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleStaticMethod] from typing import NamedTuple @@ -651,7 +652,7 @@ class HasStaticMethod(NamedTuple): def new(f: str) -> 'HasStaticMethod': return HasStaticMethod(x=f) -[builtins fixtures/classmethod.pyi] +[builtins fixtures/tuple.pyi] [case testNewNamedTupleProperty] from typing import NamedTuple @@ -664,7 +665,7 @@ class HasStaticMethod(NamedTuple): reveal_type(self) # N: Revealed type is "tuple[builtins.str, fallback=__main__.HasStaticMethod]" return 4 -[builtins fixtures/property.pyi] +[builtins fixtures/tuple.pyi] [case testTypingExtensionsNamedTuple] from typing_extensions import NamedTuple @@ -690,8 +691,8 @@ from typing import NamedTuple class A(NamedTuple): x: str -reveal_type(A.x) # N: Revealed type is "TupleGetterType[builtins.str]" -A.x + 3 # E: Unsupported left operand type for + ("TupleGetterType[builtins.str]") +reveal_type(A.x) # N: Revealed type is "collections._tuplegetter[builtins.str]" +A.x + 3 # E: Unsupported left operand type for + ("_tuplegetter[str]") A.y # E: "type[A]" has no attribute "y" [builtins fixtures/tuple.pyi] @@ -703,7 +704,7 @@ class A(NamedTuple): x: str = "x" a: object = A.x -b: int = A.x # E: Incompatible types in assignment (expression has type "TupleGetterType[builtins.str]", variable has type "int") +b: int = A.x # E: Incompatible types in assignment (expression has type "_tuplegetter[str]", variable has type "int") [builtins fixtures/tuple.pyi] [case testNamedTupleTupleGetterNested] @@ -715,8 +716,8 @@ class Inner(NamedTuple): class Outer(NamedTuple): y: Inner -reveal_type(Inner.x) # N: Revealed type is "TupleGetterType[builtins.int]" -reveal_type(Outer.y) # N: Revealed type is "TupleGetterType[tuple[builtins.int, fallback=__main__.Inner]]" +reveal_type(Inner.x) # N: Revealed type is "collections._tuplegetter[builtins.int]" +reveal_type(Outer.y) # N: Revealed type is "collections._tuplegetter[tuple[builtins.int, fallback=__main__.Inner]]" [builtins fixtures/tuple.pyi] [case testNamedTupleTupleGetterGeneric] @@ -730,5 +731,5 @@ class GenericTuple(NamedTuple, Generic[T]): x: T reveal_type(GenericTuple.x) # E: Access to generic instance variables via class is ambiguous \ - # N: Revealed type is "TupleGetterType[Any]" + # N: Revealed type is "collections._tuplegetter[Any]" [builtins fixtures/tuple.pyi] diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index ae91815d1e9e..bbe43f5d6d72 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -3868,7 +3868,7 @@ from typing import Type, NamedTuple N = NamedTuple('N', [('x', int), ('y', int)]) def f(a: Type[N]): a() -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [out] main:4: error: Missing positional arguments "x", "y" in call to "N" @@ -5346,7 +5346,7 @@ class M(NamedTuple): n: N m: M lst = [n, m] -[builtins fixtures/isinstancelist.pyi] +[builtins fixtures/tuple.pyi] [case testCorrectJoinOfSelfRecursiveTypedDicts] from typing import TypedDict @@ -5377,7 +5377,7 @@ def parse_ast(name_dict: NameDict) -> None: if isinstance(name_dict[''], int): pass reveal_type(name_dict['test']) # N: Revealed type is "tuple[builtins.bool, fallback=__main__.NameInfo]" -[builtins fixtures/isinstancelist.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-medium.pyi] [case testCrashInForwardRefToTypedDictWithIsinstance] @@ -5600,7 +5600,7 @@ class B(object): return self.a.x reveal_type(x.x) # N: Revealed type is "builtins.int" -[builtins fixtures/property.pyi] +[builtins fixtures/tuple.pyi] [out] [case testCorrectIsinstanceWithForwardUnion] @@ -5613,7 +5613,7 @@ def f(x: ForwardUnion) -> None: reveal_type(x) # N: Revealed type is "Union[tuple[builtins.int, fallback=__main__.TP], builtins.int]" if isinstance(x, TP): reveal_type(x) # N: Revealed type is "tuple[builtins.int, fallback=__main__.TP]" -[builtins fixtures/isinstance.pyi] +[builtins fixtures/tuple.pyi] [out] [case testCrashInvalidArgsSyntheticClassSyntax] @@ -5626,7 +5626,7 @@ class NM(NamedTuple): # These two should never crash, reveals are in the next test TD({'x': []}) NM(x=[]) -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -5645,7 +5645,7 @@ reveal_type(x) # N: Revealed type is "TypedDict('__main__.TD', {'x': builtins.li reveal_type(x1) # N: Revealed type is "TypedDict('__main__.TD', {'x': builtins.list[Any]})" reveal_type(y) # N: Revealed type is "tuple[builtins.list[Any], fallback=__main__.NM]" reveal_type(y1) # N: Revealed type is "tuple[builtins.list[Any], fallback=__main__.NM]" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -5659,7 +5659,7 @@ NT = NewType('NT', List[int, str]) # E: "list" expects 1 type argument, but 2 gi TD({'x': []}) NM(x=[]) NT([]) -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -5677,7 +5677,7 @@ x: A1 y: A2 reveal_type(x.b) # N: Revealed type is "__main__.B" reveal_type(y['b']) # N: Revealed type is "__main__.B" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -5691,7 +5691,7 @@ x: A1 y: A2 reveal_type(x.b) # N: Revealed type is "__main__.B" reveal_type(y['b']) # N: Revealed type is "__main__.B" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [out] diff --git a/test-data/unit/check-custom-plugin.test b/test-data/unit/check-custom-plugin.test index 0c157510cb34..4f9384bbed21 100644 --- a/test-data/unit/check-custom-plugin.test +++ b/test-data/unit/check-custom-plugin.test @@ -599,7 +599,7 @@ reveal_type(FullyQualifiedTestNamedTuple('')._asdict()) # N: Revealed type is "b [file mypy.ini] \[mypy] plugins=/test-data/unit/plugins/fully_qualified_test_hook.py -[builtins fixtures/classmethod.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [case testDynamicClassPlugin] diff --git a/test-data/unit/check-enum.test b/test-data/unit/check-enum.test index d034fe1a6f5f..ca38f1770887 100644 --- a/test-data/unit/check-enum.test +++ b/test-data/unit/check-enum.test @@ -2452,7 +2452,6 @@ class Foo(Enum): # E: Incompatible types in assignment (expression has type "", variable has type "Foo") Baz: Any = Callable[[Dict[str, "Missing"]], None] # E: Enum members must be left unannotated \ # N: See https://typing.readthedocs.io/en/latest/spec/enums.html#defining-members \ - # E: Type application targets a non-generic function or class \ # E: Name "Missing" is not defined reveal_type(Foo.Bar) # N: Revealed type is "Literal[__main__.Foo.Bar]?" diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index 33271a3cc04c..6ba177571a7d 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -2159,7 +2159,7 @@ class Custom(Base): Base(int()) == int() # E: Non-overlapping equality check (left operand type: "Base", right operand type: "int") Base(int()) == tuple() Custom(int()) == int() -[builtins fixtures/bool.pyi] +[builtins fixtures/tuple.pyi] [case testCustomEqCheckStrictEqualityMeta] # flags: --strict-equality @@ -2459,7 +2459,7 @@ def f() -> int: # E: Missing return statement from typing import TypeVar T = TypeVar("T") x: int -x + T # E: Unsupported left operand type for + ("int") +x + T # E: Unsupported operand types for + ("int" and "TypeVar") T() # E: "TypeVar" not callable [builtins fixtures/tuple.pyi] [typing fixtures/typing-full.pyi] diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test index bb64bb44d282..e7113e393281 100644 --- a/test-data/unit/check-flags.test +++ b/test-data/unit/check-flags.test @@ -1024,7 +1024,7 @@ from missing import Unchecked Point = NamedTuple('Point', [('x', List[Unchecked]), ('y', Unchecked)]) -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [out] main:5: error: NamedTuple type becomes "tuple[list[Any], Any]" due to an unfollowed import @@ -1315,7 +1315,7 @@ Point = NamedTuple('Point', [('x', int), ('y', int)]) # no error def origin() -> Point: return Point(x=0, y=0) -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testDisallowAnyExprNewType] # flags: --disallow-any-expr @@ -1908,7 +1908,7 @@ z = cast(List[Any], x) # E: Explicit "Any" is not allowed [explicit-any] from typing import Any, List, NamedTuple Point = NamedTuple('Point', [('x', List[Any]), ('y', Any)]) # E: Explicit "Any" is not allowed [explicit-any] -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testDisallowAnyExplicitTypeVarConstraint] # flags: --disallow-any-explicit --show-error-codes diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 4c170ec4753f..6e12dce778d1 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -1950,7 +1950,7 @@ def f() -> None: A = TypedDict('A', {'x': X, 'y': int}) B = NamedTuple('B', [('x', X)]) -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [out1] main:1: error: Module "ntcrash" has no attribute "nope" @@ -2574,7 +2574,7 @@ class B(NamedTuple): C(1).x C(1)[0] -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [out] [case testSerializeRecursiveAliases1] @@ -3715,8 +3715,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, collections, typing] +[stale _typeshed, a, builtins, collections, typing] [builtins fixtures/tuple.pyi] [case testIncrementalPackageNameOverload] @@ -3767,8 +3767,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, collections, typing] +[rechecked _typeshed, a, b, builtins, collections, typing] [builtins fixtures/tuple.pyi] [case testIncrementalBustedFineGrainedCache2] @@ -3780,8 +3780,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, collections, typing] +[rechecked _typeshed, a, b, builtins, collections, typing] [builtins fixtures/tuple.pyi] [case testIncrementalBustedFineGrainedCache3] @@ -3796,8 +3796,8 @@ import b [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, collections, typing] +[rechecked _typeshed, a, b, builtins, collections, typing] [builtins fixtures/tuple.pyi] [case testIncrementalWorkingFineGrainedCache] @@ -4650,7 +4650,7 @@ A = NamedTuple('A', [('x', B)]) from typing import TypedDict from lib import A B = TypedDict('B', {'x': A}) -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [out] [out2] @@ -5772,7 +5772,7 @@ class C: al: Alias = Alias(c=1) n: N = N(NT1(c=1)) -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [out2] tmp/a.py:2: error: "object" has no attribute "xyz" diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 6564fb3192d0..5dfaa63ef64e 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -3442,7 +3442,7 @@ x = t and d[t] reveal_type(x) # N: Revealed type is "Union[None, builtins.bytes]" if x: reveal_type(x) # N: Revealed type is "builtins.bytes" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [case testRegression11705_NoStrict] # flags: --no-strict-optional @@ -3457,7 +3457,7 @@ x = t and d[t] reveal_type(x) # N: Revealed type is "builtins.bytes" if x: reveal_type(x) # N: Revealed type is "builtins.bytes" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [case testSuggestPep604AnnotationForPartialNone] # flags: --local-partial-types --python-version 3.10 diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index 3c9290b8dbbb..79446d9a9db3 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -1861,7 +1861,7 @@ tup2[idx5] # E: Tuple index out of range reveal_type(tup2[idx2:idx4]) # N: Revealed type is "tuple[__main__.C, __main__.D]" reveal_type(tup2[::idx2]) # N: Revealed type is "tuple[__main__.A, __main__.C, __main__.E]" tup3: Tup2Class = tup2[:] # E: Incompatible types in assignment (expression has type "tuple[A, B, C, D, E]", variable has type "Tup2Class") -[builtins fixtures/slice.pyi] +[builtins fixtures/tuple.pyi] [case testLiteralIntelligentIndexingTypedDict] from typing import Literal, TypedDict @@ -1934,7 +1934,7 @@ reveal_type(c.get(str_key_bad, u)) # N: Revealed type is "builtins.object" a[int_key_bad] # E: Tuple index out of range b[int_key_bad] # E: Tuple index out of range c[str_key_bad] # E: TypedDict "MyDict" has no key "missing" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -1964,7 +1964,7 @@ reveal_type(tup2[idx1]) # N: Revealed type is "Union[__main__.B, __main_ reveal_type(tup2[idx1:idx2]) # N: Revealed type is "Union[tuple[__main__.B, __main__.C], tuple[__main__.B, __main__.C, __main__.D], tuple[__main__.C], tuple[__main__.C, __main__.D]]" reveal_type(tup2[0::idx1]) # N: Revealed type is "Union[tuple[__main__.A, __main__.B, __main__.C, __main__.D, __main__.E], tuple[__main__.A, __main__.C, __main__.E]]" tup2[idx_bad] # E: Tuple index out of range -[builtins fixtures/slice.pyi] +[builtins fixtures/tuple.pyi] [out] [case testLiteralIntelligentIndexingTypedDictUnions] diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 45de2a9e50ae..423941a80ae7 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -334,7 +334,7 @@ if int(): if int(): a = (1,) # E: Incompatible types in assignment (expression has type "tuple[int]", \ variable has type "A") -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNamedTupleMissingClassAttribute] import collections @@ -360,7 +360,7 @@ class C(B): pass B(1).b C(2).b -[builtins fixtures/property.pyi] +[builtins fixtures/tuple.pyi] [case testNamedTupleAsDict] from collections import namedtuple @@ -418,7 +418,7 @@ X._make('a b') # E: Argument 1 to "_make" of "X" has incompatible type "str"; e -- reveal_type(x._make([5, 'a'])) # N: Revealed type is "Tuple[builtins.int, builtins.str, fallback=__main__.X]" -- x._make('a b') # E: Argument 1 to "_make" of "X" has incompatible type "str"; expected Iterable[Any] -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNamedTupleFields] from typing import NamedTuple @@ -452,7 +452,7 @@ X = NamedTuple('X', [('x', int), ('y', str)]) Y = NamedTuple('Y', [('x', int), ('y', str)]) reveal_type([X(3, 'b'), Y(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNamedTupleJoinTuple] from typing import NamedTuple, Tuple @@ -461,7 +461,7 @@ X = NamedTuple('X', [('x', int), ('y', str)]) reveal_type([(3, 'b'), X(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" reveal_type([X(1, 'a'), (3, 'b')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNamedTupleFieldTypes] from typing import NamedTuple @@ -471,7 +471,7 @@ reveal_type(X._field_types) # N: Revealed type is "builtins.dict[builtins.str, x: X reveal_type(x._field_types) # N: Revealed type is "builtins.dict[builtins.str, Any]" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [case testNamedTupleAndOtherSuperclass] from typing import NamedTuple @@ -543,7 +543,7 @@ class B(A): reveal_type(B._make([''])) # N: Revealed type is "tuple[builtins.str, fallback=__main__.B]" b = B._make(['']) # type: B -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNamedTupleIncompatibleRedefinition] from typing import NamedTuple @@ -772,7 +772,7 @@ def test() -> None: if isinstance(exp, B): reveal_type(exp.val) # N: Revealed type is "builtins.object" reveal_type(A([B(1), B(2)])) # N: Revealed type is "tuple[builtins.list[Union[Any, tuple[builtins.object, fallback=__main__.B@6]]], fallback=__main__.A@5]" -[builtins fixtures/isinstancelist.pyi] +[builtins fixtures/tuple.pyi] [out] [case testNamedTupleImportCycle] @@ -810,7 +810,7 @@ def test() -> None: hc = HelpCommand(subcommands=[]) reveal_type(hc) # N: Revealed type is "tuple[builtins.list[Any], fallback=__main__.HelpCommand@7]" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [out] [case testUnsafeOverlappingNamedTuple] @@ -871,7 +871,7 @@ class MyTuple(BaseTuple, Base): def f(o: Base) -> None: if isinstance(o, MyTuple): reveal_type(o.value) # N: Revealed type is "builtins.float" -[builtins fixtures/isinstance.pyi] +[builtins fixtures/tuple.pyi] [out] [case testNamedTupleNew] @@ -903,7 +903,7 @@ class Child(Parent): pass reveal_type(Child.class_method()) # N: Revealed type is "tuple[builtins.str, fallback=__main__.Child]" -[builtins fixtures/classmethod.pyi] +[builtins fixtures/tuple.pyi] [case testNamedTupleAsConditionalStrictOptionalDisabled] # flags: --no-strict-optional --warn-unreachable diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index 7fffd3ce94e5..adc41a508db5 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -78,7 +78,7 @@ if x5["key"] == "A": reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict1', {'key': Literal['A'], 'foo': builtins.int})" else: reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict2', {'key': Literal['B'], 'foo': builtins.str})" -[builtins fixtures/primitives.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [case testNarrowingParentWithEnumsBasic] @@ -167,7 +167,7 @@ if x5["key"] is Key.A: reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict1', {'key': Literal[__main__.Key.A], 'foo': builtins.int})" else: reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict2', {'key': Literal[__main__.Key.B], 'foo': builtins.str})" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [case testNarrowingParentWithIsInstanceBasic] @@ -232,7 +232,7 @@ if isinstance(x5["key"], int): reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict1', {'key': builtins.int})" else: reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict2', {'key': builtins.str})" -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [case testNarrowingParentMultipleKeys] @@ -1937,7 +1937,7 @@ if len(x) == 2: reveal_type(x) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.Point2D]" else: reveal_type(x) # N: Revealed type is "tuple[builtins.int, builtins.int, builtins.int, fallback=__main__.Point3D]" -[builtins fixtures/len.pyi] +[builtins fixtures/tuple.pyi] [case testNarrowingLenTupleSubclass] from typing import Tuple diff --git a/test-data/unit/check-newsemanal.test b/test-data/unit/check-newsemanal.test index 61bf08018722..c844236b1e0d 100644 --- a/test-data/unit/check-newsemanal.test +++ b/test-data/unit/check-newsemanal.test @@ -1707,7 +1707,7 @@ def g(x: int) -> int: ... def g(x: Union[C[str], int]) -> int: # E: Type argument "str" of "C" must be a subtype of "int" y: C[object] # E: Type argument "object" of "C" must be a subtype of "int" return 0 -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] [case testNewAnalyzerTypeArgBoundCheckWithStrictOptional] @@ -1961,7 +1961,7 @@ for nx in nt: t: Union[Tuple[int, int], Tuple[str, str]] for x in t: reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str]" -[builtins fixtures/for.pyi] +[builtins fixtures/tuple.pyi] [case testNewAnalyzerFallbackUpperBoundCheckAndFallbacks] from typing import TypeVar, Generic, Tuple @@ -2177,7 +2177,7 @@ def test() -> None: reveal_type(y[0]) # N: Revealed type is "builtins.int" x: A reveal_type(x) # N: Revealed type is "__main__.G@7[tuple[builtins.int, fallback=__main__.C@5]]" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testNewAnalyzerDuplicateTypeVar] from typing import TypeVar, Generic, Any diff --git a/test-data/unit/check-protocols.test b/test-data/unit/check-protocols.test index 79207c9aad56..94fe14bb8bc3 100644 --- a/test-data/unit/check-protocols.test +++ b/test-data/unit/check-protocols.test @@ -1871,7 +1871,7 @@ fun(N2(1)) # E: Argument 1 to "fun" has incompatible type "N2"; expected "P[int, reveal_type(fun3(z)) # N: Revealed type is "builtins.object" reveal_type(fun3(z3)) # N: Revealed type is "builtins.int" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testBasicCallableStructuralSubtyping] from typing import Callable, Generic, TypeVar @@ -2750,7 +2750,7 @@ class P(Protocol): def func(self) -> Callable[[], str]: ... p: P = N(lambda: 'foo') -[builtins fixtures/property.pyi] +[builtins fixtures/tuple.pyi] [case testNamedTupleWithManyArgsCallableField] from typing import Callable, NamedTuple, Protocol @@ -2763,7 +2763,7 @@ class P(Protocol): def func(self) -> Callable[[str, str, str], str]: ... p: P = N(lambda a, b, c: 'foo') -[builtins fixtures/property.pyi] +[builtins fixtures/tuple.pyi] [case testLiteralsAgainstProtocols] from typing import Final, Literal, SupportsInt, SupportsAbs, TypeVar diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index bb8f038eb1eb..75004a7a0c55 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -801,7 +801,7 @@ match m: case A(i, j): reveal_type(i) # N: Revealed type is "builtins.str" reveal_type(j) # N: Revealed type is "builtins.int" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testMatchClassPatternCaptureNamedTupleClass] from typing import NamedTuple diff --git a/test-data/unit/check-recursive-types.test b/test-data/unit/check-recursive-types.test index 7ed5ea53c27e..e3cf57305044 100644 --- a/test-data/unit/check-recursive-types.test +++ b/test-data/unit/check-recursive-types.test @@ -162,7 +162,7 @@ reveal_type(y.x) # N: Revealed type is "builtins.int" reveal_type(y[0]) # N: Revealed type is "builtins.int" x: A reveal_type(x) # N: Revealed type is "__main__.G[tuple[builtins.int, fallback=__main__.C]]" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [case testRecursiveAliasViaBaseClassImported] # flags: --disable-error-code used-before-def @@ -198,7 +198,7 @@ def my_eval(exp: Exp) -> int: return 0 my_eval(A([B(1), B(2)])) -[builtins fixtures/isinstancelist.pyi] +[builtins fixtures/tuple.pyi] [case testRecursiveAliasesSimplifiedUnion] from typing import Sequence, TypeVar, Union diff --git a/test-data/unit/check-semanal-error.test b/test-data/unit/check-semanal-error.test index 52abbf09f1e5..d52739a14c72 100644 --- a/test-data/unit/check-semanal-error.test +++ b/test-data/unit/check-semanal-error.test @@ -179,5 +179,5 @@ class C(TypedDict): class D: invalid_1: 1 + 2 # E: Invalid type comment or annotation invalid_2: Wrap[1 + 2] # E: Invalid type comment or annotation -[builtins fixtures/dict.pyi] +[builtins fixtures/tuple.pyi] [typing fixtures/typing-typeddict.pyi] diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test index 9ab68b32472d..e547ab376145 100644 --- a/test-data/unit/check-statements.test +++ b/test-data/unit/check-statements.test @@ -2165,7 +2165,7 @@ for i in lst: a: str = i[0] # E: Incompatible types in assignment (expression has type "int", variable has type "str") N = NamedTuple('N', [('x', int)]) -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [out] [case testForwardRefsInForStatement] @@ -2178,7 +2178,7 @@ for i in lst: # type: N N = NamedTuple('N', [('x', int)]) class M(N): pass -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [out] [case testForwardRefsInWithStatementImplicit] diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 5bbb503a578a..2f52a4f52d61 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -244,7 +244,7 @@ A = List[B] class B(NamedTuple): x: str reveal_type(x[0].x) # N: Revealed type is "builtins.str" -[builtins fixtures/list.pyi] +[builtins fixtures/tuple.pyi] [out] [case testJSONAliasApproximation] diff --git a/test-data/unit/check-unions.test b/test-data/unit/check-unions.test index f8c894a7957b..f9eb035e2db0 100644 --- a/test-data/unit/check-unions.test +++ b/test-data/unit/check-unions.test @@ -352,7 +352,7 @@ def foo(a: Union[A, B, C]): a.y # E: Item "B" of "Union[B, C]" has no attribute "y" \ # E: Item "C" of "Union[B, C]" has no attribute "y" b = a # type: Union[B, C] -[builtins fixtures/isinstance.pyi] +[builtins fixtures/tuple.pyi] [case testSimplifyingUnionAndTypePromotions] from typing import TypeVar, Union @@ -841,7 +841,7 @@ for nx in nt: t: Union[Tuple[int, int], Tuple[str, str]] for x in t: reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str]" -[builtins fixtures/for.pyi] +[builtins fixtures/tuple.pyi] [out] [case testUnionUnpackingInForList] diff --git a/test-data/unit/deps-classes.test b/test-data/unit/deps-classes.test index a8fc5d629491..e10923a76b96 100644 --- a/test-data/unit/deps-classes.test +++ b/test-data/unit/deps-classes.test @@ -24,6 +24,7 @@ class A: pass -> m.f -> , , m -> m + -> , , m [case testNamedTuple2] from typing import NamedTuple, Any, Tuple @@ -45,6 +46,7 @@ class B: pass -> , , m -> , , m -> m + -> , , m [case testNamedTuple3] from typing import NamedTuple @@ -62,6 +64,7 @@ y = M(x) -> , , , , m -> m -> m + -> , , , , m [case testNamedTuple4] from typing import NamedTuple, Any diff --git a/test-data/unit/deps-types.test b/test-data/unit/deps-types.test index 7642e6d7a14c..d95fa5a44386 100644 --- a/test-data/unit/deps-types.test +++ b/test-data/unit/deps-types.test @@ -812,6 +812,7 @@ class I: pass [out] -> m -> m + -> , , m -> a -> a -> , , m, a, mod.I diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index 786549c2cf26..ced43f577d77 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -8685,7 +8685,7 @@ m.py:4: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#varia == m.py:4: error: Variable "a.A" is not valid as a type m.py:4: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases -m.py:5: note: Revealed type is "TupleGetterType[Any]" +m.py:5: note: Revealed type is "collections._tuplegetter[Any]" m.py:7: note: Revealed type is "Any" [case testAliasForwardFunctionDirect] @@ -9345,7 +9345,7 @@ def bar(self): def f() -> int: pass [file b.py.2] def f() -> str: pass -[builtins fixtures/classmethod.pyi] +[builtins fixtures/tuple.pyi] [out] == diff --git a/test-data/unit/fixtures/tuple.pyi b/test-data/unit/fixtures/tuple.pyi index d01cd0034d26..51fd6a4e4097 100644 --- a/test-data/unit/fixtures/tuple.pyi +++ b/test-data/unit/fixtures/tuple.pyi @@ -1,21 +1,38 @@ # Builtins stub used in tuple-related test cases. +import collections +from typing import ( + Generic, + Iterable, + Iterator, + Mapping, + Self, + Sequence, + Tuple, + TypeVar, + overload, +) import _typeshed -from typing import Iterable, Iterator, TypeVar, Generic, Sequence, Optional, overload, Tuple, Type, Self _T = TypeVar("_T") _Tco = TypeVar('_Tco', covariant=True) +KT = TypeVar('KT') +VT = TypeVar('VT') class object: def __init__(self) -> None: pass def __new__(cls) -> Self: ... + def __eq__(self, other: object) -> bool: pass + def __ne__(self, other: object) -> bool: pass class type: + __annotations__: Mapping[str, object] def __init__(self, *a: object) -> None: pass def __call__(self, *a: object) -> object: pass class tuple(Sequence[_Tco], Generic[_Tco]): - def __new__(cls: Type[_T], iterable: Iterable[_Tco] = ...) -> _T: ... + def __new__(cls: type[_T], iterable: Iterable[_Tco] = ...) -> _T: ... def __iter__(self) -> Iterator[_Tco]: pass + def __len__(self) -> int: pass def __contains__(self, item: object) -> bool: pass @overload def __getitem__(self, x: int) -> _Tco: pass @@ -29,15 +46,23 @@ class function: __name__: str class ellipsis: pass class classmethod: pass +class staticmethod: pass +def callable(x: object) -> bool: pass + +def len(__obj: object) -> int: ... # We need int and slice for indexing tuples. class int: def __neg__(self) -> 'int': pass def __pos__(self) -> 'int': pass + def __add__(self, other: 'int') -> 'str': pass # type: ignore[override] + def __eq__(self, other: 'int') -> bool: pass # type: ignore[override] class float: pass class slice: pass class bool(int): pass -class str: pass # For convenience +class str: + def __add__(self, other: 'str') -> 'str': pass # type: ignore[override] + def __eq__(self, other: 'str') -> bool: pass # type: ignore[override] class bytes: pass class bytearray: pass @@ -48,9 +73,13 @@ class list(Sequence[_T], Generic[_T]): def __getitem__(self, s: slice) -> list[_T]: ... def __contains__(self, item: object) -> bool: ... def __iter__(self) -> Iterator[_T]: ... + def __add__(self, x: list[_T]) -> list[_T]: ... + +property = object() # Dummy definition. -def isinstance(x: object, t: type) -> bool: pass +def isinstance(x: object, t: type[object] | tuple[type[object], ...]) -> bool: pass class BaseException: pass -class dict: pass +class dict(Mapping[KT, VT]): + def __iter__(self) -> Iterator[KT]: pass diff --git a/test-data/unit/lib-stub/collections.pyi b/test-data/unit/lib-stub/collections.pyi index 7ea264f764ee..b68edf73e0f5 100644 --- a/test-data/unit/lib-stub/collections.pyi +++ b/test-data/unit/lib-stub/collections.pyi @@ -1,4 +1,4 @@ -from typing import Any, Iterable, Union, Dict, TypeVar, Optional, Callable, Generic, Sequence, MutableMapping +from typing import Any, Iterable, Union, Dict, TypeVar, Optional, Callable, Generic, Sequence, MutableMapping, Self, overload def namedtuple( typename: str, @@ -23,3 +23,9 @@ class Counter(Dict[KT, int], Generic[KT]): ... class deque(Sequence[KT], Generic[KT]): ... class ChainMap(MutableMapping[KT, VT], Generic[KT, VT]): ... + +class _tuplegetter(Generic[KT]): + @overload + def __get__(self, instance: None, owner: type[Any] | None = None) -> Self: ... + @overload + def __get__(self, instance: object, owner: type[Any] | None = None) -> KT: ... diff --git a/test-data/unit/merge.test b/test-data/unit/merge.test index 13546b0f3d92..d58ddf649c4b 100644 --- a/test-data/unit/merge.test +++ b/test-data/unit/merge.test @@ -680,7 +680,7 @@ TypeInfo<2>( _make<17> _replace<18> _source<19> (builtins.str<8>) - x<20> (TupleGetterType[target.A<0>]))) + x<20> (collections._tuplegetter[target.A<0>]<21>))) ==> TypeInfo<0>( Name(target.A) @@ -704,8 +704,8 @@ TypeInfo<2>( _make<17> _replace<18> _source<19> (builtins.str<8>) - x<20> (TupleGetterType[target.A<0>]) - y<21> (TupleGetterType[target.A<0>]))) + x<20> (collections._tuplegetter[target.A<0>]<21>) + y<22> (collections._tuplegetter[target.A<0>]<21>))) [case testNamedTupleOldVersion_typeinfo] import target @@ -740,7 +740,7 @@ TypeInfo<2>( _make<16> _replace<17> _source<18> (builtins.str<8>) - x<19> (TupleGetterType[target.A<0>]))) + x<19> (collections._tuplegetter[target.A<0>]<20>))) ==> TypeInfo<0>( Name(target.A) @@ -763,8 +763,8 @@ TypeInfo<2>( _make<16> _replace<17> _source<18> (builtins.str<8>) - x<19> (TupleGetterType[target.A<0>]) - y<20> (TupleGetterType[target.A<0>]))) + x<19> (collections._tuplegetter[target.A<0>]<20>) + y<21> (collections._tuplegetter[target.A<0>]<20>))) [case testUnionType_types] import target From 64351d597118659949d44ee66ef0cba0e404dbc9 Mon Sep 17 00:00:00 2001 From: Gatsik <74517072+Gatsik@users.noreply.github.com> Date: Mon, 21 Jul 2025 23:43:53 +0300 Subject: [PATCH 3/7] Don't set default owner for python3.9 and lower in _tuplegetter descriptor --- test-data/unit/lib-stub/collections.pyi | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/test-data/unit/lib-stub/collections.pyi b/test-data/unit/lib-stub/collections.pyi index b68edf73e0f5..f07721fd975b 100644 --- a/test-data/unit/lib-stub/collections.pyi +++ b/test-data/unit/lib-stub/collections.pyi @@ -1,4 +1,4 @@ -from typing import Any, Iterable, Union, Dict, TypeVar, Optional, Callable, Generic, Sequence, MutableMapping, Self, overload +from typing import Any, Iterable, Union, Dict, TypeVar, Optional, Callable, Generic, Sequence, MutableMapping, Self, overload, sys def namedtuple( typename: str, @@ -25,7 +25,13 @@ class deque(Sequence[KT], Generic[KT]): ... class ChainMap(MutableMapping[KT, VT], Generic[KT, VT]): ... class _tuplegetter(Generic[KT]): - @overload - def __get__(self, instance: None, owner: type[Any] | None = None) -> Self: ... - @overload - def __get__(self, instance: object, owner: type[Any] | None = None) -> KT: ... + if sys.version_info >= (3, 10): + @overload + def __get__(self, instance: None, owner: type[Any] | None = None) -> Self: ... + @overload + def __get__(self, instance: object, owner: type[Any] | None = None) -> KT: ... + else: + @overload + def __get__(self, instance: None, owner: type[Any] | None) -> Self: ... + @overload + def __get__(self, instance: object, owner: type[Any] | None) -> KT: ... From bc3e46954205210c2bac876b10200e8af3e36926 Mon Sep 17 00:00:00 2001 From: Gatsik <74517072+Gatsik@users.noreply.github.com> Date: Tue, 22 Jul 2025 20:20:24 +0300 Subject: [PATCH 4/7] Reduce diff ? --- mypy/test/teststubtest.py | 5 +-- test-data/unit/check-basic.test | 2 +- test-data/unit/check-callable.test | 2 +- test-data/unit/check-class-namedtuple.test | 31 +++++++++--------- test-data/unit/check-classes.test | 20 ++++++------ test-data/unit/check-custom-plugin.test | 2 +- test-data/unit/check-enum.test | 1 + test-data/unit/check-expressions.test | 2 +- test-data/unit/check-flags.test | 6 ++-- test-data/unit/check-inference.test | 4 +-- test-data/unit/check-literal.test | 6 ++-- test-data/unit/check-namedtuple.test | 22 ++++++------- test-data/unit/check-narrowing.test | 6 ++-- test-data/unit/check-newsemanal.test | 6 ++-- test-data/unit/check-protocols.test | 6 ++-- test-data/unit/check-python310.test | 2 +- test-data/unit/check-recursive-types.test | 4 +-- test-data/unit/check-semanal-error.test | 2 +- test-data/unit/check-statements.test | 4 +-- test-data/unit/check-type-aliases.test | 2 +- test-data/unit/check-unions.test | 4 +-- test-data/unit/fixtures/callable.pyi | 1 + test-data/unit/fixtures/classmethod.pyi | 1 + test-data/unit/fixtures/dict-full.pyi | 1 + test-data/unit/fixtures/dict.pyi | 1 + test-data/unit/fixtures/for.pyi | 1 + test-data/unit/fixtures/isinstance.pyi | 1 + test-data/unit/fixtures/isinstancelist.pyi | 1 + test-data/unit/fixtures/len.pyi | 1 + test-data/unit/fixtures/list-simple.pyi | 16 ++++++++++ test-data/unit/fixtures/list.pyi | 1 + test-data/unit/fixtures/property.pyi | 1 + test-data/unit/fixtures/slice.pyi | 1 + test-data/unit/fixtures/tuple.pyi | 37 +++------------------- test-data/unit/lib-stub/collections.pyi | 16 +++------- test-data/unit/typexport-basic.test | 22 ++++++------- 36 files changed, 118 insertions(+), 123 deletions(-) create mode 100644 test-data/unit/fixtures/list-simple.pyi diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index d14e3d81f7b1..ed5058540fdb 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -39,6 +39,7 @@ def use_tmp_dir(mod_name: str) -> Iterator[str]: stubtest_typing_stub = """ +import collections Any = object() class _SpecialForm: @@ -2097,7 +2098,7 @@ class Y(TypedDict): @collect_cases def test_named_tuple(self) -> Iterator[Case]: yield Case( - stub="from typing import NamedTuple; import collections", + stub="from typing import NamedTuple", runtime="from typing import NamedTuple", error=None, ) @@ -2133,7 +2134,7 @@ class X2(NamedTuple): @collect_cases def test_named_tuple_typing_and_collections(self) -> Iterator[Case]: yield Case( - stub="from typing import NamedTuple; import collections", + stub="from typing import NamedTuple", runtime="from collections import namedtuple", error=None, ) diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index 7e50447d3046..07ed5fd77082 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -462,7 +462,7 @@ def typeddict() -> Sequence[D]: a = (a.A(), A()) a.x # E: "tuple[a.A, b.A]" has no attribute "x" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-full.pyi] [case testReturnAnyFromFunctionDeclaredToReturnObject] diff --git a/test-data/unit/check-callable.test b/test-data/unit/check-callable.test index d71d15cd8945..23db0bf50a4e 100644 --- a/test-data/unit/check-callable.test +++ b/test-data/unit/check-callable.test @@ -491,7 +491,7 @@ def g(o: Thing) -> None: i + s # E: Unsupported operand types for + ("str" and "int") o(1,2,3) -[builtins fixtures/tuple.pyi] +[builtins fixtures/callable.pyi] [case testCallableNoArgs] diff --git a/test-data/unit/check-class-namedtuple.test b/test-data/unit/check-class-namedtuple.test index dda6fee2468c..727ebaaf3d58 100644 --- a/test-data/unit/check-class-namedtuple.test +++ b/test-data/unit/check-class-namedtuple.test @@ -214,7 +214,7 @@ i, i = l[0] # E: Need more than 1 value to unpack (2 expected) l = [A(1)] a = (1,) # E: Incompatible types in assignment (expression has type "tuple[int]", \ variable has type "A") -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNewNamedTupleMissingClassAttribute] from typing import NamedTuple @@ -259,7 +259,7 @@ class C(B): pass B(1).b C(2).b -[builtins fixtures/tuple.pyi] +[builtins fixtures/property.pyi] [case testNewNamedTupleAsDict] from typing import NamedTuple, Any @@ -271,7 +271,7 @@ class X(NamedTuple): x: X reveal_type(x._asdict()) # N: Revealed type is "builtins.dict[builtins.str, Any]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [case testNewNamedTupleReplaceTyped] from typing import NamedTuple @@ -301,7 +301,7 @@ reveal_type(X._field_defaults) # N: Revealed type is "builtins.dict[builtins.st # but it's inferred as `Mapping[str, object]` here due to the fixture we're using reveal_type(X.__annotations__) # N: Revealed type is "typing.Mapping[builtins.str, builtins.object]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict-full.pyi] [case testNewNamedTupleUnit] from typing import NamedTuple @@ -326,7 +326,7 @@ class Y(NamedTuple): reveal_type([X(3, 'b'), Y(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNewNamedTupleJoinTuple] from typing import NamedTuple @@ -338,7 +338,7 @@ class X(NamedTuple): reveal_type([(3, 'b'), X(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" reveal_type([X(1, 'a'), (3, 'b')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNewNamedTupleWithTooManyArguments] from typing import NamedTuple @@ -358,7 +358,7 @@ class X(typing.NamedTuple): x.x: int # E: Invalid statement in NamedTuple definition; expected "field_name: field_type [= default]" z: str = 'z' aa: int # E: Non-default NamedTuple fields cannot follow default fields -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNewNamedTupleWithoutTypesSpecified] from typing import NamedTuple @@ -377,7 +377,7 @@ class N(NamedTuple): def f(a: Type[N]): a() # E: Missing positional arguments "x", "y" in call to "N" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNewNamedTupleWithDefaults] from typing import List, NamedTuple, Optional @@ -416,7 +416,7 @@ reveal_type(UserDefined()) # N: Revealed type is "tuple[__main__.Default, fallb reveal_type(UserDefined(Default())) # N: Revealed type is "tuple[__main__.Default, fallback=__main__.UserDefined]" UserDefined(1) # E: Argument 1 to "UserDefined" has incompatible type "int"; expected "Default" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNewNamedTupleWithDefaultsStrictOptional] from typing import List, NamedTuple, Optional @@ -434,7 +434,7 @@ class CannotBeNone(NamedTuple): x: int y: int = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNewNamedTupleWrongType] from typing import NamedTuple @@ -448,8 +448,7 @@ class X(NamedTuple): from typing import NamedTuple class X(NamedTuple): - x: int = 1 + '1' # E: Incompatible types in assignment (expression has type "str", variable has type "int") \ - # E: Unsupported operand types for + ("int" and "str") + x: int = 1 + '1' # E: Unsupported left operand type for + ("int") [builtins fixtures/tuple.pyi] [case testNewNamedTupleInheritance] @@ -608,7 +607,7 @@ class ReuseCallableNamed(NamedTuple): def z(self) -> int: # E: Name "z" already defined on line 31 return 0 -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [case testNewNamedTupleDocString] from typing import NamedTuple @@ -640,7 +639,7 @@ class HasClassMethod(NamedTuple): reveal_type(HasClassMethod) # N: Revealed type is "def (x: builtins.str) -> tuple[builtins.str, fallback=__main__.HasClassMethod]" return cls(x=f) -[builtins fixtures/tuple.pyi] +[builtins fixtures/classmethod.pyi] [case testNewNamedTupleStaticMethod] from typing import NamedTuple @@ -652,7 +651,7 @@ class HasStaticMethod(NamedTuple): def new(f: str) -> 'HasStaticMethod': return HasStaticMethod(x=f) -[builtins fixtures/tuple.pyi] +[builtins fixtures/classmethod.pyi] [case testNewNamedTupleProperty] from typing import NamedTuple @@ -665,7 +664,7 @@ class HasStaticMethod(NamedTuple): reveal_type(self) # N: Revealed type is "tuple[builtins.str, fallback=__main__.HasStaticMethod]" return 4 -[builtins fixtures/tuple.pyi] +[builtins fixtures/property.pyi] [case testTypingExtensionsNamedTuple] from typing_extensions import NamedTuple diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index bbe43f5d6d72..ae91815d1e9e 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -3868,7 +3868,7 @@ from typing import Type, NamedTuple N = NamedTuple('N', [('x', int), ('y', int)]) def f(a: Type[N]): a() -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [out] main:4: error: Missing positional arguments "x", "y" in call to "N" @@ -5346,7 +5346,7 @@ class M(NamedTuple): n: N m: M lst = [n, m] -[builtins fixtures/tuple.pyi] +[builtins fixtures/isinstancelist.pyi] [case testCorrectJoinOfSelfRecursiveTypedDicts] from typing import TypedDict @@ -5377,7 +5377,7 @@ def parse_ast(name_dict: NameDict) -> None: if isinstance(name_dict[''], int): pass reveal_type(name_dict['test']) # N: Revealed type is "tuple[builtins.bool, fallback=__main__.NameInfo]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/isinstancelist.pyi] [typing fixtures/typing-medium.pyi] [case testCrashInForwardRefToTypedDictWithIsinstance] @@ -5600,7 +5600,7 @@ class B(object): return self.a.x reveal_type(x.x) # N: Revealed type is "builtins.int" -[builtins fixtures/tuple.pyi] +[builtins fixtures/property.pyi] [out] [case testCorrectIsinstanceWithForwardUnion] @@ -5613,7 +5613,7 @@ def f(x: ForwardUnion) -> None: reveal_type(x) # N: Revealed type is "Union[tuple[builtins.int, fallback=__main__.TP], builtins.int]" if isinstance(x, TP): reveal_type(x) # N: Revealed type is "tuple[builtins.int, fallback=__main__.TP]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/isinstance.pyi] [out] [case testCrashInvalidArgsSyntheticClassSyntax] @@ -5626,7 +5626,7 @@ class NM(NamedTuple): # These two should never crash, reveals are in the next test TD({'x': []}) NM(x=[]) -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -5645,7 +5645,7 @@ reveal_type(x) # N: Revealed type is "TypedDict('__main__.TD', {'x': builtins.li reveal_type(x1) # N: Revealed type is "TypedDict('__main__.TD', {'x': builtins.list[Any]})" reveal_type(y) # N: Revealed type is "tuple[builtins.list[Any], fallback=__main__.NM]" reveal_type(y1) # N: Revealed type is "tuple[builtins.list[Any], fallback=__main__.NM]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -5659,7 +5659,7 @@ NT = NewType('NT', List[int, str]) # E: "list" expects 1 type argument, but 2 gi TD({'x': []}) NM(x=[]) NT([]) -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -5677,7 +5677,7 @@ x: A1 y: A2 reveal_type(x.b) # N: Revealed type is "__main__.B" reveal_type(y['b']) # N: Revealed type is "__main__.B" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -5691,7 +5691,7 @@ x: A1 y: A2 reveal_type(x.b) # N: Revealed type is "__main__.B" reveal_type(y['b']) # N: Revealed type is "__main__.B" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [out] diff --git a/test-data/unit/check-custom-plugin.test b/test-data/unit/check-custom-plugin.test index 4f9384bbed21..0c157510cb34 100644 --- a/test-data/unit/check-custom-plugin.test +++ b/test-data/unit/check-custom-plugin.test @@ -599,7 +599,7 @@ reveal_type(FullyQualifiedTestNamedTuple('')._asdict()) # N: Revealed type is "b [file mypy.ini] \[mypy] plugins=/test-data/unit/plugins/fully_qualified_test_hook.py -[builtins fixtures/tuple.pyi] +[builtins fixtures/classmethod.pyi] [typing fixtures/typing-typeddict.pyi] [case testDynamicClassPlugin] diff --git a/test-data/unit/check-enum.test b/test-data/unit/check-enum.test index ca38f1770887..d034fe1a6f5f 100644 --- a/test-data/unit/check-enum.test +++ b/test-data/unit/check-enum.test @@ -2452,6 +2452,7 @@ class Foo(Enum): # E: Incompatible types in assignment (expression has type "", variable has type "Foo") Baz: Any = Callable[[Dict[str, "Missing"]], None] # E: Enum members must be left unannotated \ # N: See https://typing.readthedocs.io/en/latest/spec/enums.html#defining-members \ + # E: Type application targets a non-generic function or class \ # E: Name "Missing" is not defined reveal_type(Foo.Bar) # N: Revealed type is "Literal[__main__.Foo.Bar]?" diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index 6ba177571a7d..536133096868 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -2459,7 +2459,7 @@ def f() -> int: # E: Missing return statement from typing import TypeVar T = TypeVar("T") x: int -x + T # E: Unsupported operand types for + ("int" and "TypeVar") +x + T # E: Unsupported left operand type for + ("int") T() # E: "TypeVar" not callable [builtins fixtures/tuple.pyi] [typing fixtures/typing-full.pyi] diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test index e7113e393281..bb64bb44d282 100644 --- a/test-data/unit/check-flags.test +++ b/test-data/unit/check-flags.test @@ -1024,7 +1024,7 @@ from missing import Unchecked Point = NamedTuple('Point', [('x', List[Unchecked]), ('y', Unchecked)]) -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [out] main:5: error: NamedTuple type becomes "tuple[list[Any], Any]" due to an unfollowed import @@ -1315,7 +1315,7 @@ Point = NamedTuple('Point', [('x', int), ('y', int)]) # no error def origin() -> Point: return Point(x=0, y=0) -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testDisallowAnyExprNewType] # flags: --disallow-any-expr @@ -1908,7 +1908,7 @@ z = cast(List[Any], x) # E: Explicit "Any" is not allowed [explicit-any] from typing import Any, List, NamedTuple Point = NamedTuple('Point', [('x', List[Any]), ('y', Any)]) # E: Explicit "Any" is not allowed [explicit-any] -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testDisallowAnyExplicitTypeVarConstraint] # flags: --disallow-any-explicit --show-error-codes diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 5dfaa63ef64e..6564fb3192d0 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -3442,7 +3442,7 @@ x = t and d[t] reveal_type(x) # N: Revealed type is "Union[None, builtins.bytes]" if x: reveal_type(x) # N: Revealed type is "builtins.bytes" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [case testRegression11705_NoStrict] # flags: --no-strict-optional @@ -3457,7 +3457,7 @@ x = t and d[t] reveal_type(x) # N: Revealed type is "builtins.bytes" if x: reveal_type(x) # N: Revealed type is "builtins.bytes" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [case testSuggestPep604AnnotationForPartialNone] # flags: --local-partial-types --python-version 3.10 diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index 79446d9a9db3..3c9290b8dbbb 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -1861,7 +1861,7 @@ tup2[idx5] # E: Tuple index out of range reveal_type(tup2[idx2:idx4]) # N: Revealed type is "tuple[__main__.C, __main__.D]" reveal_type(tup2[::idx2]) # N: Revealed type is "tuple[__main__.A, __main__.C, __main__.E]" tup3: Tup2Class = tup2[:] # E: Incompatible types in assignment (expression has type "tuple[A, B, C, D, E]", variable has type "Tup2Class") -[builtins fixtures/tuple.pyi] +[builtins fixtures/slice.pyi] [case testLiteralIntelligentIndexingTypedDict] from typing import Literal, TypedDict @@ -1934,7 +1934,7 @@ reveal_type(c.get(str_key_bad, u)) # N: Revealed type is "builtins.object" a[int_key_bad] # E: Tuple index out of range b[int_key_bad] # E: Tuple index out of range c[str_key_bad] # E: TypedDict "MyDict" has no key "missing" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [out] @@ -1964,7 +1964,7 @@ reveal_type(tup2[idx1]) # N: Revealed type is "Union[__main__.B, __main_ reveal_type(tup2[idx1:idx2]) # N: Revealed type is "Union[tuple[__main__.B, __main__.C], tuple[__main__.B, __main__.C, __main__.D], tuple[__main__.C], tuple[__main__.C, __main__.D]]" reveal_type(tup2[0::idx1]) # N: Revealed type is "Union[tuple[__main__.A, __main__.B, __main__.C, __main__.D, __main__.E], tuple[__main__.A, __main__.C, __main__.E]]" tup2[idx_bad] # E: Tuple index out of range -[builtins fixtures/tuple.pyi] +[builtins fixtures/slice.pyi] [out] [case testLiteralIntelligentIndexingTypedDictUnions] diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 423941a80ae7..45de2a9e50ae 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -334,7 +334,7 @@ if int(): if int(): a = (1,) # E: Incompatible types in assignment (expression has type "tuple[int]", \ variable has type "A") -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNamedTupleMissingClassAttribute] import collections @@ -360,7 +360,7 @@ class C(B): pass B(1).b C(2).b -[builtins fixtures/tuple.pyi] +[builtins fixtures/property.pyi] [case testNamedTupleAsDict] from collections import namedtuple @@ -418,7 +418,7 @@ X._make('a b') # E: Argument 1 to "_make" of "X" has incompatible type "str"; e -- reveal_type(x._make([5, 'a'])) # N: Revealed type is "Tuple[builtins.int, builtins.str, fallback=__main__.X]" -- x._make('a b') # E: Argument 1 to "_make" of "X" has incompatible type "str"; expected Iterable[Any] -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNamedTupleFields] from typing import NamedTuple @@ -452,7 +452,7 @@ X = NamedTuple('X', [('x', int), ('y', str)]) Y = NamedTuple('Y', [('x', int), ('y', str)]) reveal_type([X(3, 'b'), Y(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNamedTupleJoinTuple] from typing import NamedTuple, Tuple @@ -461,7 +461,7 @@ X = NamedTuple('X', [('x', int), ('y', str)]) reveal_type([(3, 'b'), X(1, 'a')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" reveal_type([X(1, 'a'), (3, 'b')]) # N: Revealed type is "builtins.list[tuple[builtins.int, builtins.str]]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNamedTupleFieldTypes] from typing import NamedTuple @@ -471,7 +471,7 @@ reveal_type(X._field_types) # N: Revealed type is "builtins.dict[builtins.str, x: X reveal_type(x._field_types) # N: Revealed type is "builtins.dict[builtins.str, Any]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [case testNamedTupleAndOtherSuperclass] from typing import NamedTuple @@ -543,7 +543,7 @@ class B(A): reveal_type(B._make([''])) # N: Revealed type is "tuple[builtins.str, fallback=__main__.B]" b = B._make(['']) # type: B -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNamedTupleIncompatibleRedefinition] from typing import NamedTuple @@ -772,7 +772,7 @@ def test() -> None: if isinstance(exp, B): reveal_type(exp.val) # N: Revealed type is "builtins.object" reveal_type(A([B(1), B(2)])) # N: Revealed type is "tuple[builtins.list[Union[Any, tuple[builtins.object, fallback=__main__.B@6]]], fallback=__main__.A@5]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/isinstancelist.pyi] [out] [case testNamedTupleImportCycle] @@ -810,7 +810,7 @@ def test() -> None: hc = HelpCommand(subcommands=[]) reveal_type(hc) # N: Revealed type is "tuple[builtins.list[Any], fallback=__main__.HelpCommand@7]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [out] [case testUnsafeOverlappingNamedTuple] @@ -871,7 +871,7 @@ class MyTuple(BaseTuple, Base): def f(o: Base) -> None: if isinstance(o, MyTuple): reveal_type(o.value) # N: Revealed type is "builtins.float" -[builtins fixtures/tuple.pyi] +[builtins fixtures/isinstance.pyi] [out] [case testNamedTupleNew] @@ -903,7 +903,7 @@ class Child(Parent): pass reveal_type(Child.class_method()) # N: Revealed type is "tuple[builtins.str, fallback=__main__.Child]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/classmethod.pyi] [case testNamedTupleAsConditionalStrictOptionalDisabled] # flags: --no-strict-optional --warn-unreachable diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index adc41a508db5..1fa6de7cca02 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -167,7 +167,7 @@ if x5["key"] is Key.A: reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict1', {'key': Literal[__main__.Key.A], 'foo': builtins.int})" else: reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict2', {'key': Literal[__main__.Key.B], 'foo': builtins.str})" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [case testNarrowingParentWithIsInstanceBasic] @@ -232,7 +232,7 @@ if isinstance(x5["key"], int): reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict1', {'key': builtins.int})" else: reveal_type(x5) # N: Revealed type is "TypedDict('__main__.TypedDict2', {'key': builtins.str})" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [case testNarrowingParentMultipleKeys] @@ -1937,7 +1937,7 @@ if len(x) == 2: reveal_type(x) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.Point2D]" else: reveal_type(x) # N: Revealed type is "tuple[builtins.int, builtins.int, builtins.int, fallback=__main__.Point3D]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/len.pyi] [case testNarrowingLenTupleSubclass] from typing import Tuple diff --git a/test-data/unit/check-newsemanal.test b/test-data/unit/check-newsemanal.test index c844236b1e0d..61bf08018722 100644 --- a/test-data/unit/check-newsemanal.test +++ b/test-data/unit/check-newsemanal.test @@ -1707,7 +1707,7 @@ def g(x: int) -> int: ... def g(x: Union[C[str], int]) -> int: # E: Type argument "str" of "C" must be a subtype of "int" y: C[object] # E: Type argument "object" of "C" must be a subtype of "int" return 0 -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [case testNewAnalyzerTypeArgBoundCheckWithStrictOptional] @@ -1961,7 +1961,7 @@ for nx in nt: t: Union[Tuple[int, int], Tuple[str, str]] for x in t: reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/for.pyi] [case testNewAnalyzerFallbackUpperBoundCheckAndFallbacks] from typing import TypeVar, Generic, Tuple @@ -2177,7 +2177,7 @@ def test() -> None: reveal_type(y[0]) # N: Revealed type is "builtins.int" x: A reveal_type(x) # N: Revealed type is "__main__.G@7[tuple[builtins.int, fallback=__main__.C@5]]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testNewAnalyzerDuplicateTypeVar] from typing import TypeVar, Generic, Any diff --git a/test-data/unit/check-protocols.test b/test-data/unit/check-protocols.test index 94fe14bb8bc3..79207c9aad56 100644 --- a/test-data/unit/check-protocols.test +++ b/test-data/unit/check-protocols.test @@ -1871,7 +1871,7 @@ fun(N2(1)) # E: Argument 1 to "fun" has incompatible type "N2"; expected "P[int, reveal_type(fun3(z)) # N: Revealed type is "builtins.object" reveal_type(fun3(z3)) # N: Revealed type is "builtins.int" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testBasicCallableStructuralSubtyping] from typing import Callable, Generic, TypeVar @@ -2750,7 +2750,7 @@ class P(Protocol): def func(self) -> Callable[[], str]: ... p: P = N(lambda: 'foo') -[builtins fixtures/tuple.pyi] +[builtins fixtures/property.pyi] [case testNamedTupleWithManyArgsCallableField] from typing import Callable, NamedTuple, Protocol @@ -2763,7 +2763,7 @@ class P(Protocol): def func(self) -> Callable[[str, str, str], str]: ... p: P = N(lambda a, b, c: 'foo') -[builtins fixtures/tuple.pyi] +[builtins fixtures/property.pyi] [case testLiteralsAgainstProtocols] from typing import Final, Literal, SupportsInt, SupportsAbs, TypeVar diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 75004a7a0c55..bb8f038eb1eb 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -801,7 +801,7 @@ match m: case A(i, j): reveal_type(i) # N: Revealed type is "builtins.str" reveal_type(j) # N: Revealed type is "builtins.int" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testMatchClassPatternCaptureNamedTupleClass] from typing import NamedTuple diff --git a/test-data/unit/check-recursive-types.test b/test-data/unit/check-recursive-types.test index e3cf57305044..7ed5ea53c27e 100644 --- a/test-data/unit/check-recursive-types.test +++ b/test-data/unit/check-recursive-types.test @@ -162,7 +162,7 @@ reveal_type(y.x) # N: Revealed type is "builtins.int" reveal_type(y[0]) # N: Revealed type is "builtins.int" x: A reveal_type(x) # N: Revealed type is "__main__.G[tuple[builtins.int, fallback=__main__.C]]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [case testRecursiveAliasViaBaseClassImported] # flags: --disable-error-code used-before-def @@ -198,7 +198,7 @@ def my_eval(exp: Exp) -> int: return 0 my_eval(A([B(1), B(2)])) -[builtins fixtures/tuple.pyi] +[builtins fixtures/isinstancelist.pyi] [case testRecursiveAliasesSimplifiedUnion] from typing import Sequence, TypeVar, Union diff --git a/test-data/unit/check-semanal-error.test b/test-data/unit/check-semanal-error.test index d52739a14c72..52abbf09f1e5 100644 --- a/test-data/unit/check-semanal-error.test +++ b/test-data/unit/check-semanal-error.test @@ -179,5 +179,5 @@ class C(TypedDict): class D: invalid_1: 1 + 2 # E: Invalid type comment or annotation invalid_2: Wrap[1 + 2] # E: Invalid type comment or annotation -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test index e547ab376145..9ab68b32472d 100644 --- a/test-data/unit/check-statements.test +++ b/test-data/unit/check-statements.test @@ -2165,7 +2165,7 @@ for i in lst: a: str = i[0] # E: Incompatible types in assignment (expression has type "int", variable has type "str") N = NamedTuple('N', [('x', int)]) -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [out] [case testForwardRefsInForStatement] @@ -2178,7 +2178,7 @@ for i in lst: # type: N N = NamedTuple('N', [('x', int)]) class M(N): pass -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [out] [case testForwardRefsInWithStatementImplicit] diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 2f52a4f52d61..5bbb503a578a 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -244,7 +244,7 @@ A = List[B] class B(NamedTuple): x: str reveal_type(x[0].x) # N: Revealed type is "builtins.str" -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [out] [case testJSONAliasApproximation] diff --git a/test-data/unit/check-unions.test b/test-data/unit/check-unions.test index f9eb035e2db0..f8c894a7957b 100644 --- a/test-data/unit/check-unions.test +++ b/test-data/unit/check-unions.test @@ -352,7 +352,7 @@ def foo(a: Union[A, B, C]): a.y # E: Item "B" of "Union[B, C]" has no attribute "y" \ # E: Item "C" of "Union[B, C]" has no attribute "y" b = a # type: Union[B, C] -[builtins fixtures/tuple.pyi] +[builtins fixtures/isinstance.pyi] [case testSimplifyingUnionAndTypePromotions] from typing import TypeVar, Union @@ -841,7 +841,7 @@ for nx in nt: t: Union[Tuple[int, int], Tuple[str, str]] for x in t: reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str]" -[builtins fixtures/tuple.pyi] +[builtins fixtures/for.pyi] [out] [case testUnionUnpackingInForList] diff --git a/test-data/unit/fixtures/callable.pyi b/test-data/unit/fixtures/callable.pyi index 44abf0691ceb..63e21c3149fe 100644 --- a/test-data/unit/fixtures/callable.pyi +++ b/test-data/unit/fixtures/callable.pyi @@ -1,3 +1,4 @@ +import collections from typing import Generic, Tuple, TypeVar, Union T = TypeVar('T') diff --git a/test-data/unit/fixtures/classmethod.pyi b/test-data/unit/fixtures/classmethod.pyi index 97e018b1dc1c..7efc8fe8460f 100644 --- a/test-data/unit/fixtures/classmethod.pyi +++ b/test-data/unit/fixtures/classmethod.pyi @@ -1,3 +1,4 @@ +import collections import typing _T = typing.TypeVar('_T') diff --git a/test-data/unit/fixtures/dict-full.pyi b/test-data/unit/fixtures/dict-full.pyi index f20369ce9332..9f46d20e0c90 100644 --- a/test-data/unit/fixtures/dict-full.pyi +++ b/test-data/unit/fixtures/dict-full.pyi @@ -1,5 +1,6 @@ # Builtins stub used in dictionary-related test cases (more complete). +import collections from _typeshed import SupportsKeysAndGetItem import _typeshed from typing import ( diff --git a/test-data/unit/fixtures/dict.pyi b/test-data/unit/fixtures/dict.pyi index ed2287511161..1e66f6996f9b 100644 --- a/test-data/unit/fixtures/dict.pyi +++ b/test-data/unit/fixtures/dict.pyi @@ -3,6 +3,7 @@ # NOTE: Use dict-full.pyi if you need more builtins instead of adding here, # if feasible. +import collections from _typeshed import SupportsKeysAndGetItem import _typeshed from typing import ( diff --git a/test-data/unit/fixtures/for.pyi b/test-data/unit/fixtures/for.pyi index 80c8242c2a5e..1bcc50a24093 100644 --- a/test-data/unit/fixtures/for.pyi +++ b/test-data/unit/fixtures/for.pyi @@ -1,5 +1,6 @@ # builtins stub used in for statement test cases +import collections from typing import TypeVar, Generic, Iterable, Iterator, Generator from abc import abstractmethod, ABCMeta diff --git a/test-data/unit/fixtures/isinstance.pyi b/test-data/unit/fixtures/isinstance.pyi index 12cef2035c2b..10716040ce7b 100644 --- a/test-data/unit/fixtures/isinstance.pyi +++ b/test-data/unit/fixtures/isinstance.pyi @@ -1,3 +1,4 @@ +import collections from typing import Tuple, TypeVar, Generic, Union, cast, Any, Type T = TypeVar('T') diff --git a/test-data/unit/fixtures/isinstancelist.pyi b/test-data/unit/fixtures/isinstancelist.pyi index 0ee5258ff74b..5b90b8c9766a 100644 --- a/test-data/unit/fixtures/isinstancelist.pyi +++ b/test-data/unit/fixtures/isinstancelist.pyi @@ -1,3 +1,4 @@ +import collections from typing import ( Iterable, Iterator, TypeVar, List, Mapping, overload, Tuple, Set, Union, Generic, Sequence ) diff --git a/test-data/unit/fixtures/len.pyi b/test-data/unit/fixtures/len.pyi index ee39d952701f..28e990df820a 100644 --- a/test-data/unit/fixtures/len.pyi +++ b/test-data/unit/fixtures/len.pyi @@ -1,3 +1,4 @@ +import collections from typing import Tuple, TypeVar, Generic, Union, Type, Sequence, Mapping from typing_extensions import Protocol diff --git a/test-data/unit/fixtures/list-simple.pyi b/test-data/unit/fixtures/list-simple.pyi new file mode 100644 index 000000000000..e6da7d6d9cd1 --- /dev/null +++ b/test-data/unit/fixtures/list-simple.pyi @@ -0,0 +1,16 @@ +# Builtins stub used in list-related test cases. +# +# This is a simpler version of list.pyi + +from typing import Sequence, TypeVar + +T = TypeVar('T') + +class object: + def __init__(self) -> None: pass + +class list(Sequence[T]): pass +class type: pass +class int: pass +class str: pass +class dict: pass diff --git a/test-data/unit/fixtures/list.pyi b/test-data/unit/fixtures/list.pyi index 3dcdf18b2faa..07d72b93141c 100644 --- a/test-data/unit/fixtures/list.pyi +++ b/test-data/unit/fixtures/list.pyi @@ -1,5 +1,6 @@ # Builtins stub used in list-related test cases. +import collections from typing import TypeVar, Generic, Iterable, Iterator, Sequence, overload T = TypeVar('T') diff --git a/test-data/unit/fixtures/property.pyi b/test-data/unit/fixtures/property.pyi index 933868ac9907..3920d5a91d68 100644 --- a/test-data/unit/fixtures/property.pyi +++ b/test-data/unit/fixtures/property.pyi @@ -1,3 +1,4 @@ +import collections import typing _T = typing.TypeVar('_T') diff --git a/test-data/unit/fixtures/slice.pyi b/test-data/unit/fixtures/slice.pyi index b22a12b5213f..0c1136289f31 100644 --- a/test-data/unit/fixtures/slice.pyi +++ b/test-data/unit/fixtures/slice.pyi @@ -1,4 +1,5 @@ # Builtins stub used in slicing test cases. +import collections from typing import Generic, TypeVar T = TypeVar('T') diff --git a/test-data/unit/fixtures/tuple.pyi b/test-data/unit/fixtures/tuple.pyi index 51fd6a4e4097..09ae0309e53a 100644 --- a/test-data/unit/fixtures/tuple.pyi +++ b/test-data/unit/fixtures/tuple.pyi @@ -1,38 +1,23 @@ # Builtins stub used in tuple-related test cases. -import collections -from typing import ( - Generic, - Iterable, - Iterator, - Mapping, - Self, - Sequence, - Tuple, - TypeVar, - overload, -) +import collections import _typeshed +from typing import Iterable, Iterator, TypeVar, Generic, Sequence, Optional, overload, Tuple, Self _T = TypeVar("_T") _Tco = TypeVar('_Tco', covariant=True) -KT = TypeVar('KT') -VT = TypeVar('VT') class object: def __init__(self) -> None: pass def __new__(cls) -> Self: ... def __eq__(self, other: object) -> bool: pass - def __ne__(self, other: object) -> bool: pass class type: - __annotations__: Mapping[str, object] def __init__(self, *a: object) -> None: pass def __call__(self, *a: object) -> object: pass class tuple(Sequence[_Tco], Generic[_Tco]): def __new__(cls: type[_T], iterable: Iterable[_Tco] = ...) -> _T: ... def __iter__(self) -> Iterator[_Tco]: pass - def __len__(self) -> int: pass def __contains__(self, item: object) -> bool: pass @overload def __getitem__(self, x: int) -> _Tco: pass @@ -46,23 +31,15 @@ class function: __name__: str class ellipsis: pass class classmethod: pass -class staticmethod: pass -def callable(x: object) -> bool: pass - -def len(__obj: object) -> int: ... # We need int and slice for indexing tuples. class int: def __neg__(self) -> 'int': pass def __pos__(self) -> 'int': pass - def __add__(self, other: 'int') -> 'str': pass # type: ignore[override] - def __eq__(self, other: 'int') -> bool: pass # type: ignore[override] class float: pass class slice: pass class bool(int): pass -class str: - def __add__(self, other: 'str') -> 'str': pass # type: ignore[override] - def __eq__(self, other: 'str') -> bool: pass # type: ignore[override] +class str: pass # For convenience class bytes: pass class bytearray: pass @@ -73,13 +50,9 @@ class list(Sequence[_T], Generic[_T]): def __getitem__(self, s: slice) -> list[_T]: ... def __contains__(self, item: object) -> bool: ... def __iter__(self) -> Iterator[_T]: ... - def __add__(self, x: list[_T]) -> list[_T]: ... - -property = object() # Dummy definition. -def isinstance(x: object, t: type[object] | tuple[type[object], ...]) -> bool: pass +def isinstance(x: object, t: type) -> bool: pass class BaseException: pass -class dict(Mapping[KT, VT]): - def __iter__(self) -> Iterator[KT]: pass +class dict: pass diff --git a/test-data/unit/lib-stub/collections.pyi b/test-data/unit/lib-stub/collections.pyi index f07721fd975b..52cc5435714c 100644 --- a/test-data/unit/lib-stub/collections.pyi +++ b/test-data/unit/lib-stub/collections.pyi @@ -1,4 +1,4 @@ -from typing import Any, Iterable, Union, Dict, TypeVar, Optional, Callable, Generic, Sequence, MutableMapping, Self, overload, sys +from typing import Any, Iterable, Union, Dict, TypeVar, Optional, Callable, Generic, Sequence, MutableMapping, overload def namedtuple( typename: str, @@ -25,13 +25,7 @@ class deque(Sequence[KT], Generic[KT]): ... class ChainMap(MutableMapping[KT, VT], Generic[KT, VT]): ... class _tuplegetter(Generic[KT]): - if sys.version_info >= (3, 10): - @overload - def __get__(self, instance: None, owner: type[Any] | None = None) -> Self: ... - @overload - def __get__(self, instance: object, owner: type[Any] | None = None) -> KT: ... - else: - @overload - def __get__(self, instance: None, owner: type[Any] | None) -> Self: ... - @overload - def __get__(self, instance: object, owner: type[Any] | None) -> KT: ... + @overload + def __get__(self, instance: None, owner: type[Any]) -> _tuplegetter[KT]: ... + @overload + def __get__(self, instance: object, owner: type[Any]) -> KT: ... diff --git a/test-data/unit/typexport-basic.test b/test-data/unit/typexport-basic.test index 77e7763824d6..706d1632d396 100644 --- a/test-data/unit/typexport-basic.test +++ b/test-data/unit/typexport-basic.test @@ -684,14 +684,14 @@ NameExpr(5) : def (a: A[C]) -> B[A[C]] from typing import List a = [] # type: List[A] class A: pass -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] ListExpr(2) : builtins.list[A] [case testInferGenericTypeInTypeAnyContext] from typing import Any a = [] # type: Any -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] ListExpr(2) : builtins.list[Any] @@ -706,7 +706,7 @@ def f(a: A) -> B: pass map( f, [A()]) -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] CallExpr(8) : builtins.list[B] NameExpr(8) : def (f: def (A) -> B, a: builtins.list[A]) -> builtins.list[B] @@ -754,7 +754,7 @@ f = lambda x: [] # type: Callable[[B], List[A]] class A: pass class B: a = None # type: A -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] LambdaExpr(2) : def (x: B) -> builtins.list[A] ListExpr(2) : builtins.list[A] @@ -770,7 +770,7 @@ def f(a: A) -> B: pass l = None # type: List[A] map( lambda x: f(x), l) -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] CallExpr(9) : builtins.list[B] NameExpr(9) : def (f: def (A) -> B, a: builtins.list[A]) -> builtins.list[B] @@ -792,7 +792,7 @@ def f(a: A) -> B: pass l = None # type: List[A] map( lambda x: [f(x)], l) -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] NameExpr(10) : def (f: def (A) -> builtins.list[B], a: builtins.list[A]) -> builtins.list[B] LambdaExpr(11) : def (x: A) -> builtins.list[B] @@ -811,7 +811,7 @@ l = None # type: List[A] map( [lambda x: x], l) -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] -- TODO We probably should not silently infer 'Any' types in statically typed -- context. Perhaps just fail instead? @@ -834,7 +834,7 @@ l = None # type: List[A] map( lambda x: x.b, l) -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] CallExpr(9) : builtins.list[B] NameExpr(9) : def (f: def (A) -> B, a: builtins.list[A]) -> builtins.list[B] @@ -855,7 +855,7 @@ l = None # type: List[A] map( a=l, f=lambda x: x.b) -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] CallExpr(9) : builtins.list[B] NameExpr(9) : def (f: def (A) -> B, a: builtins.list[A]) -> builtins.list[B] @@ -877,7 +877,7 @@ a = a or [] if int(): a = [] or a class A: pass -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] ListExpr(3) : builtins.list[A] NameExpr(3) : builtins.list[A] @@ -1154,7 +1154,7 @@ def m(fun: Callable[[T], V], iter: List[T]) -> None: pass nums = [1] # type: List[int] m(fun, nums) -[builtins fixtures/list.pyi] +[builtins fixtures/list-simple.pyi] [out] IntExpr(13) : Literal[1]? ListExpr(13) : builtins.list[builtins.int] From 1ff9a0078fa13d6f7aff45eb2d4f314981a8adc3 Mon Sep 17 00:00:00 2001 From: Gatsik <74517072+Gatsik@users.noreply.github.com> Date: Tue, 22 Jul 2025 20:24:44 +0300 Subject: [PATCH 5/7] Reduce diff even more --- test-data/unit/check-incremental.test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 6e12dce778d1..92bce39a3d32 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -1950,7 +1950,7 @@ def f() -> None: A = TypedDict('A', {'x': X, 'y': int}) B = NamedTuple('B', [('x', X)]) -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [out1] main:1: error: Module "ntcrash" has no attribute "nope" @@ -2574,7 +2574,7 @@ class B(NamedTuple): C(1).x C(1)[0] -[builtins fixtures/tuple.pyi] +[builtins fixtures/list.pyi] [out] [case testSerializeRecursiveAliases1] @@ -4650,7 +4650,7 @@ A = NamedTuple('A', [('x', B)]) from typing import TypedDict from lib import A B = TypedDict('B', {'x': A}) -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [out] [out2] @@ -5772,7 +5772,7 @@ class C: al: Alias = Alias(c=1) n: N = N(NT1(c=1)) -[builtins fixtures/tuple.pyi] +[builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [out2] tmp/a.py:2: error: "object" has no attribute "xyz" From b320f2df9b1376b031fba9d02f9d473455586457 Mon Sep 17 00:00:00 2001 From: Gatsik <74517072+Gatsik@users.noreply.github.com> Date: Wed, 23 Jul 2025 01:14:27 +0300 Subject: [PATCH 6/7] Apply python/typeshed#14436 to local typeshed --- mypy/typeshed/stdlib/collections/__init__.pyi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mypy/typeshed/stdlib/collections/__init__.pyi b/mypy/typeshed/stdlib/collections/__init__.pyi index bc33d91caa1d..28f1a208c766 100644 --- a/mypy/typeshed/stdlib/collections/__init__.pyi +++ b/mypy/typeshed/stdlib/collections/__init__.pyi @@ -32,6 +32,22 @@ _VT = TypeVar("_VT") _KT_co = TypeVar("_KT_co", covariant=True) _VT_co = TypeVar("_VT_co", covariant=True) +# at runtime this class is implemented in _collections, but it considers itself to live in collections since Python 3.12 +@final +class _tuplegetter(Generic[_T]): # undocumented + def __init__(self, index: SupportsIndex, doc: str, /) -> None: ... + def __reduce__(self) -> tuple[type[Self], tuple[int, str]]: ... + if sys.version_info >= (3, 10): + @overload + def __get__(self, instance: None, owner: type[Any] | None = None, /) -> Self: ... + @overload + def __get__(self, instance: object, owner: type[Any] | None = None, /) -> _T: ... + else: + @overload + def __get__(self, instance: None, owner: type[Any] | None, /) -> Self: ... + @overload + def __get__(self, instance: object, owner: type[Any] | None, /) -> _T: ... + # namedtuple is special-cased in the type checker; the initializer is ignored. def namedtuple( typename: str, From fc2e371212273ea8a24d42463b166f9d6452dc3d Mon Sep 17 00:00:00 2001 From: Gatsik <74517072+Gatsik@users.noreply.github.com> Date: Wed, 23 Jul 2025 02:13:47 +0300 Subject: [PATCH 7/7] Fix mypyc tests --- mypyc/test-data/annotate-basic.test | 1 + mypyc/test-data/fixtures/typing-full.pyi | 3 +++ mypyc/test-data/irbuild-basic.test | 1 + mypyc/test-data/irbuild-tuple.test | 1 + mypyc/test-data/run-misc.test | 1 + mypyc/test-data/run-tuples.test | 2 ++ 6 files changed, 9 insertions(+) diff --git a/mypyc/test-data/annotate-basic.test b/mypyc/test-data/annotate-basic.test index c9e1c4b64a32..b4c89caaa920 100644 --- a/mypyc/test-data/annotate-basic.test +++ b/mypyc/test-data/annotate-basic.test @@ -389,6 +389,7 @@ def good1() -> int: [file nonnative.py] class C: def foo(self) -> None: pass +[typing fixtures/typing-full.pyi] [case testAnnotateGetAttrAndSetAttrBuiltins] def f1(x, s: str): diff --git a/mypyc/test-data/fixtures/typing-full.pyi b/mypyc/test-data/fixtures/typing-full.pyi index d37129bc2e0b..f5ba188e168f 100644 --- a/mypyc/test-data/fixtures/typing-full.pyi +++ b/mypyc/test-data/fixtures/typing-full.pyi @@ -6,6 +6,7 @@ # Many of the definitions have special handling in the type checker, so they # can just be initialized to anything. +import collections from abc import abstractmethod, ABCMeta class GenericMeta(type): pass @@ -175,3 +176,5 @@ class _TypedDict(Mapping[str, object]): class TypeAliasType: pass + +def final(f: T) -> T: pass diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index 4a7d315ec836..69525f6bc92b 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -2315,6 +2315,7 @@ L2: r73 = CPyDict_SetItem(r71, r72, r66) r74 = r73 >= 0 :: signed return 1 +[typing fixtures/typing-full.pyi] [case testChainedConditional] def g(x: int) -> int: diff --git a/mypyc/test-data/irbuild-tuple.test b/mypyc/test-data/irbuild-tuple.test index 5c5ec27b1882..7da3761390d6 100644 --- a/mypyc/test-data/irbuild-tuple.test +++ b/mypyc/test-data/irbuild-tuple.test @@ -176,6 +176,7 @@ L2: r2 = CPySequenceTuple_GetItem(nt, 2) r3 = unbox(int, r2) return r3 +[typing fixtures/typing-full.pyi] [case testTupleOperatorIn] diff --git a/mypyc/test-data/run-misc.test b/mypyc/test-data/run-misc.test index 129946a4c330..7b138d1e277d 100644 --- a/mypyc/test-data/run-misc.test +++ b/mypyc/test-data/run-misc.test @@ -728,6 +728,7 @@ def test_named_tuple() -> None: assert type(t) is NT assert isinstance(t, tuple) assert not isinstance(tuple([1]), NT) +[typing fixtures/typing-full.pyi] [case testUnion] from typing import Union diff --git a/mypyc/test-data/run-tuples.test b/mypyc/test-data/run-tuples.test index ea0a1cb8d852..ce1d1a04785d 100644 --- a/mypyc/test-data/run-tuples.test +++ b/mypyc/test-data/run-tuples.test @@ -94,6 +94,7 @@ assert f(NT(3, 2)) == 3 class Sub(NT): pass assert f(Sub(3, 2)) == 3 +[typing fixtures/typing-full.pyi] -- Ref: https://github.com/mypyc/mypyc/issues/924 [case testNamedTupleClassSyntax] @@ -152,6 +153,7 @@ assert Record.__annotations__ == { 'ordering': type, 'extra_int_constants': list, }, Record.__annotations__ +[typing fixtures/typing-full.pyi] [case testTupleOps] from typing import Tuple, Final, List, Any, Optional, cast