From a72c71bbe43641545f2b64c09991f80070a71f43 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Tue, 4 Apr 2017 01:17:11 -0700 Subject: [PATCH 01/16] Update builtins stub to make test fail when production code fails --- test-data/unit/fixtures/list.pyi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test-data/unit/fixtures/list.pyi b/test-data/unit/fixtures/list.pyi index ce9978a38c4c..ea82738b1ba3 100644 --- a/test-data/unit/fixtures/list.pyi +++ b/test-data/unit/fixtures/list.pyi @@ -1,6 +1,6 @@ # Builtins stub used in list-related test cases. -from typing import TypeVar, Generic, builtinclass, Iterable, Iterator, overload +from typing import TypeVar, Generic, builtinclass, Iterable, Iterator, overload, Sequence T = TypeVar('T') @@ -23,7 +23,8 @@ class list(Iterable[T], Generic[T]): def append(self, x: T) -> None: pass def extend(self, x: Iterable[T]) -> None: pass -class tuple: pass +_T_co = TypeVar('_T_co', covariant=True) +class tuple(Sequence[_T_co], Generic[_T_co]): pass class function: pass class int: pass class str: pass From 2e90e9fef22508f479bd3202500cf8c26b5d0d42 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Tue, 4 Apr 2017 01:20:54 -0700 Subject: [PATCH 02/16] Fix join of Tuple and NamedTuple --- mypy/subtypes.py | 9 +++++++-- mypy/types.py | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 11fb92fcb155..ab2f472234fe 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -143,10 +143,15 @@ def visit_instance(self, left: Instance) -> bool: rname = right.type.fullname() if not left.type.has_base(rname) and rname != 'builtins.object': return False - # Map left type to corresponding right instances. t = map_instance_to_supertype(left, right.type) - + # Check that one of the types does not have type args or + # the number of type args is the same and + # each left type arg is acceptable in place of the matching right one + if not t.args or not right.args: + return True + if len(t.args) != len(right.args): + return False return all(self.check_type_parameter(lefta, righta, tvar.variance) for lefta, righta, tvar in zip(t.args, right.args, right.type.defn.type_vars)) diff --git a/mypy/types.py b/mypy/types.py index e182806a4f39..52e58e885b7f 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -1428,7 +1428,7 @@ def visit_tuple_type(self, t: TupleType) -> str: s = self.list_str(t.items) if t.fallback and t.fallback.type: fallback_name = t.fallback.type.fullname() - if fallback_name != 'builtins.tuple': + if fallback_name not in ('builtins.tuple', 'builtins.object'): return 'Tuple[{}, fallback={}]'.format(s, t.fallback.accept(self)) return 'Tuple[{}]'.format(s) From 936bbe6fba82f76a2e89d81c142999f730a8c0a0 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Wed, 5 Apr 2017 14:39:34 -0700 Subject: [PATCH 03/16] Fix Tuple behavior --- mypy/checker.py | 4 +- mypy/checkexpr.py | 2 +- mypy/expandtype.py | 7 ++- mypy/join.py | 5 +- mypy/messages.py | 5 +- mypy/semanal.py | 2 +- mypy/subtypes.py | 8 +-- mypy/typeanal.py | 70 ++++++++++++---------- mypy/types.py | 17 +++++- test-data/unit/check-functions.test | 2 +- test-data/unit/check-inference.test | 2 + test-data/unit/check-tuples.test | 5 +- test-data/unit/check-typeddict.test | 2 +- test-data/unit/fixtures/isinstancelist.pyi | 8 ++- typeshed | 2 +- 15 files changed, 82 insertions(+), 59 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 431d2d38aabe..7c4f6a68d7f8 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1511,7 +1511,7 @@ def append_types_for_inference(lvs: List[Expression], rv_types: List[Type]) -> N append_types_for_inference(right_lvs, right_rv_types) - return TupleType(type_parameters, self.named_type('builtins.tuple')) + return TupleType(type_parameters, self.named_generic_type('builtins.tuple', [AnyType()])) def split_around_star(self, items: List[T], star_index: int, length: int) -> Tuple[List[T], List[T], List[T]]: @@ -1574,7 +1574,7 @@ def check_lvalue(self, lvalue: Lvalue) -> Tuple[Type, IndexExpr, Var]: self.store_type(lvalue, lvalue_type) elif isinstance(lvalue, TupleExpr) or isinstance(lvalue, ListExpr): types = [self.check_lvalue(sub_expr)[0] for sub_expr in lvalue.items] - lvalue_type = TupleType(types, self.named_type('builtins.tuple')) + lvalue_type = TupleType(types, self.named_generic_type('builtins.tuple', [AnyType()])) else: lvalue_type = self.expr_checker.accept(lvalue) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index fbe980eb165e..d8255a67f444 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1740,7 +1740,7 @@ def visit_dict_expr(self, e: DictExpr) -> Type: # # def (*v: Tuple[kt, vt]) -> Dict[kt, vt]: ... constructor = CallableType( - [TupleType([kt, vt], self.named_type('builtins.tuple'))], + [TupleType([kt, vt], self.chk.named_generic_type('builtins.tuple', [AnyType()]))], [nodes.ARG_STAR], [None], self.chk.named_generic_type('builtins.dict', [kt, vt]), diff --git a/mypy/expandtype.py b/mypy/expandtype.py index a526ddd2e020..42cd75690992 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -7,6 +7,8 @@ FunctionLike, TypeVarDef ) +import mypy + def expand_type(typ: Type, env: Mapping[TypeVarId, Type]) -> Type: """Substitute any type variable references in a type given by a type @@ -109,7 +111,10 @@ def visit_overloaded(self, t: Overloaded) -> Type: return Overloaded(items) def visit_tuple_type(self, t: TupleType) -> Type: - return t.copy_modified(items=self.expand_types(t.items)) + new_items = self.expand_types(t.items) + new_fallback_arg = mypy.join.join_type_list(new_items) + new_fallback = t.fallback.copy_modified(args=[new_fallback_arg]) + return t.copy_modified(items=new_items, fallback=new_fallback) def visit_typeddict_type(self, t: TypedDictType) -> Type: return t.copy_modified(item_types=self.expand_types(t.items.values())) diff --git a/mypy/join.py b/mypy/join.py index 7746e4d32d1f..2ece8768fcad 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -386,7 +386,4 @@ def join_type_list(types: List[Type]) -> Type: # This is a little arbitrary but reasonable. Any empty tuple should be compatible # with all variable length tuples, and this makes it possible. return UninhabitedType() - joined = types[0] - for t in types[1:]: - joined = join_types(joined, t) - return joined + return UnionType.make_simplified_union(types) diff --git a/mypy/messages.py b/mypy/messages.py index 9348003371ac..e0379c00ce87 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -260,7 +260,10 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: return '"{}"'.format(base_str) elif itype.type.fullname() == 'builtins.tuple': item_type_str = strip_quotes(self.format(itype.args[0])) - return 'Tuple[{}, ...]'.format(item_type_str) + if isinstance(itype.args[0], AnyType): + return 'tuple' + else: + return 'Tuple[{}, ...]'.format(item_type_str) elif itype.type.fullname() in reverse_type_aliases: alias = reverse_type_aliases[itype.type.fullname()] alias = alias.split('.')[-1] diff --git a/mypy/semanal.py b/mypy/semanal.py index 8f285c135242..4c235fe5b572 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2107,7 +2107,7 @@ def build_namedtuple_typeinfo(self, name: str, items: List[str], types: List[Typ # Actual signature should return OrderedDict[str, Union[types]] ordereddictype = (self.named_type_or_none('builtins.dict', [strtype, AnyType()]) or self.object_type()) - fallback = self.named_type('__builtins__.tuple', types) + fallback = self.named_type('__builtins__.tuple', [join.join_type_list(types)]) # Note: actual signature should accept an invariant version of Iterable[UnionType[types]]. # but it can't be expressed. 'new' and 'len' should be callable types. iterable_type = self.named_type_or_none('typing.Iterable', [AnyType()]) diff --git a/mypy/subtypes.py b/mypy/subtypes.py index ab2f472234fe..3dde1350d7be 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -145,13 +145,7 @@ def visit_instance(self, left: Instance) -> bool: return False # Map left type to corresponding right instances. t = map_instance_to_supertype(left, right.type) - # Check that one of the types does not have type args or - # the number of type args is the same and - # each left type arg is acceptable in place of the matching right one - if not t.args or not right.args: - return True - if len(t.args) != len(right.args): - return False + # TODO: assert len(t.args) == len(right.args) return all(self.check_type_parameter(lefta, righta, tvar.variance) for lefta, righta, tvar in zip(t.args, right.args, right.type.defn.type_vars)) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index e89a17a1a998..d82ade0ef855 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -18,6 +18,7 @@ from mypy.exprtotype import expr_to_unanalyzed_type, TypeTranslationError from mypy.subtypes import is_subtype from mypy import nodes +from mypy import join from mypy import experiments @@ -137,7 +138,7 @@ def visit_unbound_type(self, t: UnboundType) -> Type: elif fullname == 'typing.Tuple': if len(t.args) == 0 and not t.empty_tuple_index: # Bare 'Tuple' is same as 'tuple' - return self.builtin_type('builtins.tuple') + return self.builtin_type('builtins.tuple', [AnyType()]) if len(t.args) == 2 and isinstance(t.args[1], EllipsisType): # Tuple[T, ...] (uniform, variable-length tuple) instance = self.builtin_type('builtins.tuple', [self.anal_type(t.args[0])]) @@ -211,37 +212,35 @@ def visit_unbound_type(self, t: UnboundType) -> Type: self.fail('Invalid type "{}"'.format(name), t) return t info = sym.node # type: TypeInfo - if len(t.args) > 0 and info.fullname() == 'builtins.tuple': - return TupleType(self.anal_array(t.args), - Instance(info, [AnyType()], t.line), - t.line) - else: - # Analyze arguments and construct Instance type. The - # number of type arguments and their values are - # checked only later, since we do not always know the - # valid count at this point. Thus we may construct an - # Instance with an invalid number of type arguments. - instance = Instance(info, self.anal_array(t.args), t.line, t.column) - tup = info.tuple_type - if tup is not None: - # The class has a Tuple[...] base class so it will be - # represented as a tuple type. - if t.args: - self.fail('Generic tuple types not supported', t) - return AnyType() - return tup.copy_modified(items=self.anal_array(tup.items), - fallback=instance) - td = info.typeddict_type - if td is not None: - # The class has a TypedDict[...] base class so it will be - # represented as a typeddict type. - if t.args: - self.fail('Generic TypedDict types not supported', t) - return AnyType() - # Create a named TypedDictType - return td.copy_modified(item_types=self.anal_array(list(td.items.values())), - fallback=instance) - return instance + if info.fullname() == 'builtins.tuple': + assert not t.args + t.args = [AnyType()] + # Analyze arguments and construct Instance type. The + # number of type arguments and their values are + # checked only later, since we do not always know the + # valid count at this point. Thus we may construct an + # Instance with an invalid number of type arguments. + instance = Instance(info, self.anal_array(t.args), t.line, t.column) + tup = info.tuple_type + if tup is not None: + # The class has a Tuple[...] base class so it will be + # represented as a tuple type. + if t.args: + self.fail('Generic tuple types not supported', t) + return AnyType() + return tup.copy_modified(items=self.anal_array(tup.items), + fallback=instance) + td = info.typeddict_type + if td is not None: + # The class has a TypedDict[...] base class so it will be + # represented as a typeddict type. + if t.args: + self.fail('Generic TypedDict types not supported', t) + return AnyType() + # Create a named TypedDictType + return td.copy_modified(item_types=self.anal_array(list(td.items.values())), + fallback=instance) + return instance else: return AnyType() @@ -332,7 +331,7 @@ def visit_tuple_type(self, t: TupleType) -> Type: self.fail('At most one star type allowed in a tuple', t) if t.implicit: return TupleType([AnyType() for _ in t.items], - self.builtin_type('builtins.tuple'), + self.builtin_type('builtins.tuple', [AnyType()]), t.line) else: return AnyType() @@ -520,6 +519,11 @@ def visit_callable_type(self, t: CallableType) -> None: def visit_tuple_type(self, t: TupleType) -> None: for item in t.items: item.accept(self) + # if it's not builtins.tuple, then its bases should have tuple[Any] + # TODO: put assert here if it's not too slow + if type(t.fallback) == Instance and t.fallback.type.fullname() == 'builtins.tuple': + fallback_item = join.join_type_list(t.items) + t.fallback.args = [fallback_item] def visit_typeddict_type(self, t: TypedDictType) -> None: for item_type in t.items.values(): diff --git a/mypy/types.py b/mypy/types.py index 52e58e885b7f..4cc4787390f3 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -15,6 +15,11 @@ ) from mypy.sharedparse import argument_elide_name +import mypy + +MYPY = False +if MYPY: + from mypy import join T = TypeVar('T') @@ -378,6 +383,7 @@ class Instance(Type): def __init__(self, typ: Optional[mypy.nodes.TypeInfo], args: List[Type], line: int = -1, column: int = -1, erased: bool = False) -> None: assert(typ is None or typ.fullname() not in ["builtins.Any", "typing.Any"]) + # TODO: assert(typ is None or typ.fullname() != 'builtins.tuple' or len(args) == 1) self.type = typ self.args = args self.erased = erased @@ -833,6 +839,8 @@ def __init__(self, items: List[Type], fallback: Instance, line: int = -1, column: int = -1, implicit: bool = False) -> None: self.items = items self.fallback = fallback + # TODO: assert not (isinstance(fallback, Instance) and fallback.type and + # fallback.type.fullname() == 'builtins.tuple' and not fallback.args) self.implicit = implicit self.can_be_true = len(self.items) > 0 self.can_be_false = len(self.items) == 0 @@ -867,7 +875,10 @@ def copy_modified(self, *, fallback: Instance = None, return TupleType(items, fallback, self.line, self.column) def slice(self, begin: int, stride: int, end: int) -> 'TupleType': - return TupleType(self.items[begin:end:stride], self.fallback, + new_items = self.items[begin:end:stride] + fallback_args = [mypy.join.join_type_list(new_items)] + new_fallback = self.fallback.copy_modified(args=fallback_args) + return TupleType(new_items, new_fallback, self.line, self.column, self.implicit) @@ -1707,7 +1718,9 @@ def set_typ_args(tp: Type, new_args: List[Type], line: int = -1, column: int = - if isinstance(tp, Instance): return Instance(tp.type, new_args, line, column) if isinstance(tp, TupleType): - return tp.copy_modified(items=new_args) + fallback_args = [mypy.join.join_type_list(new_args)] + fallback = tp.fallback.copy_modified(args=fallback_args) + return tp.copy_modified(items=new_args, fallback=fallback) if isinstance(tp, UnionType): return UnionType.make_simplified_union(new_args, line, column) if isinstance(tp, CallableType): diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 0099d501b9f6..8995a102a298 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -1486,7 +1486,7 @@ f(1, thing_in_kwargs=["hey"]) from typing import Tuple, Any def f(x, *args): # type: (...) -> None success_tuple_type = args # type: Tuple[Any, ...] - fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type Tuple[Any, ...], variable has type None) + fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type tuple, variable has type None) f(1, "hello") [builtins fixtures/tuple.pyi] [out] diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 0457e49127d8..4e53da80d75e 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -1775,6 +1775,8 @@ def g(x: Union[int, str]): pass c = a if f() else b g(c) # E: Argument 1 to "g" has incompatible type "Union[int, str, tuple]"; expected "Union[int, str]" +[builtins fixtures/list.pyi] + [case testUnificationMultipleInheritance] class A: pass class B: diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test index c836fe8cd41e..13e0deab0755 100644 --- a/test-data/unit/check-tuples.test +++ b/test-data/unit/check-tuples.test @@ -91,7 +91,7 @@ from typing import Tuple t1 = None # type: Tuple[A, A] t2 = None # type: tuple -t1 = t2 # E: Incompatible types in assignment (expression has type Tuple[Any, ...], variable has type "Tuple[A, A]") +t1 = t2 # E: Incompatible types in assignment (expression has type tuple, variable has type "Tuple[A, A]") t2 = t1 class A: pass @@ -702,6 +702,7 @@ B()[100] [case testValidTupleBaseClass] from typing import Tuple class A(tuple): pass +[builtins fixtures/tuple.pyi] [out] [case testTupleBaseClass2-skip] @@ -913,7 +914,7 @@ def f(a: Tuple) -> None: pass f(()) f((1,)) f(('', '')) -f(0) # E: Argument 1 to "f" has incompatible type "int"; expected Tuple[Any, ...] +f(0) # E: Argument 1 to "f" has incompatible type "int"; expected tuple [builtins fixtures/tuple.pyi] [case testTupleSingleton] diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index c971f427a08b..98a8c13ec44c 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -367,7 +367,7 @@ Point3D = TypedDict('Point3D', {'x': int, 'y': int, 'z': int}) p1 = TaggedPoint(type='2d', x=0, y=0) p2 = Point3D(x=1, y=1, z=1) joined_points = [p1, p2] -reveal_type(p1) # E: Revealed type is 'TypedDict(type=builtins.str, x=builtins.int, y=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.object])' +reveal_type(p1) # E: Revealed type is 'TypedDict(type=builtins.str, x=builtins.int, y=builtins.int, _fallback=typing.Mapping[builtins.str, Union[builtins.str, builtins.int]])' reveal_type(p2) # E: Revealed type is 'TypedDict(x=builtins.int, y=builtins.int, z=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.int])' reveal_type(joined_points) # E: Revealed type is 'builtins.list[TypedDict(x=builtins.int, y=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.int])]' [builtins fixtures/dict.pyi] diff --git a/test-data/unit/fixtures/isinstancelist.pyi b/test-data/unit/fixtures/isinstancelist.pyi index 9096961b06ab..020f70c7c601 100644 --- a/test-data/unit/fixtures/isinstancelist.pyi +++ b/test-data/unit/fixtures/isinstancelist.pyi @@ -1,4 +1,4 @@ -from typing import builtinclass, Iterable, Iterator, TypeVar, List, Mapping, overload, Tuple, Set, Union +from typing import builtinclass, Iterable, Iterator, TypeVar, List, Mapping, overload, Tuple, Set, Union, Sequence, Generic @builtinclass class object: @@ -8,7 +8,11 @@ class object: class type: def __init__(self, x) -> None: pass -class tuple: pass +Tco = TypeVar('Tco', covariant=True) +class tuple(Sequence[Tco], Generic[Tco]): + def __iter__(self) -> Iterator[Tco]: pass + def __getitem__(self, x: int) -> Tco: pass + class function: pass def isinstance(x: object, t: Union[type, Tuple]) -> bool: pass diff --git a/typeshed b/typeshed index 1ea3d2de5794..7027c3e4e8f5 160000 --- a/typeshed +++ b/typeshed @@ -1 +1 @@ -Subproject commit 1ea3d2de5794c2224a1bc086aa471d0097699bf1 +Subproject commit 7027c3e4e8f5d00d5269fc11ccaf768012725abd From 5810f55acf1fdb1376ea18a057f4af2755909159 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Thu, 6 Apr 2017 04:33:39 -0700 Subject: [PATCH 04/16] CR fixes --- mypy/checkexpr.py | 2 +- mypy/expandtype.py | 6 ++---- mypy/join.py | 5 ++++- mypy/semanal.py | 2 +- mypy/typeanal.py | 5 ++--- mypy/types.py | 9 ++------- test-data/unit/check-typeddict.test | 2 +- 7 files changed, 13 insertions(+), 18 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index d8255a67f444..cc4321f5ae1e 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1701,7 +1701,7 @@ def visit_tuple_expr(self, e: TupleExpr) -> Type: tt = self.accept(item, type_context_items[j]) j += 1 items.append(tt) - fallback_item = join.join_type_list(items) + fallback_item = UnionType.make_simplified_union(items) return TupleType(items, self.chk.named_generic_type('builtins.tuple', [fallback_item])) def visit_dict_expr(self, e: DictExpr) -> Type: diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 42cd75690992..15f0e8ceaffa 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -111,10 +111,8 @@ def visit_overloaded(self, t: Overloaded) -> Type: return Overloaded(items) def visit_tuple_type(self, t: TupleType) -> Type: - new_items = self.expand_types(t.items) - new_fallback_arg = mypy.join.join_type_list(new_items) - new_fallback = t.fallback.copy_modified(args=[new_fallback_arg]) - return t.copy_modified(items=new_items, fallback=new_fallback) + new_fallback = expand_type(t.fallback, self.variables) + return t.copy_modified(items=self.expand_types(t.items), fallback=new_fallback) def visit_typeddict_type(self, t: TypedDictType) -> Type: return t.copy_modified(item_types=self.expand_types(t.items.values())) diff --git a/mypy/join.py b/mypy/join.py index 2ece8768fcad..7746e4d32d1f 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -386,4 +386,7 @@ def join_type_list(types: List[Type]) -> Type: # This is a little arbitrary but reasonable. Any empty tuple should be compatible # with all variable length tuples, and this makes it possible. return UninhabitedType() - return UnionType.make_simplified_union(types) + joined = types[0] + for t in types[1:]: + joined = join_types(joined, t) + return joined diff --git a/mypy/semanal.py b/mypy/semanal.py index 4c235fe5b572..43e0d3a601c8 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2107,7 +2107,7 @@ def build_namedtuple_typeinfo(self, name: str, items: List[str], types: List[Typ # Actual signature should return OrderedDict[str, Union[types]] ordereddictype = (self.named_type_or_none('builtins.dict', [strtype, AnyType()]) or self.object_type()) - fallback = self.named_type('__builtins__.tuple', [join.join_type_list(types)]) + fallback = self.named_type('__builtins__.tuple', [UnionType.make_simplified_union(types)]) # Note: actual signature should accept an invariant version of Iterable[UnionType[types]]. # but it can't be expressed. 'new' and 'len' should be callable types. iterable_type = self.named_type_or_none('typing.Iterable', [AnyType()]) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index d82ade0ef855..b729350b25db 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -18,7 +18,6 @@ from mypy.exprtotype import expr_to_unanalyzed_type, TypeTranslationError from mypy.subtypes import is_subtype from mypy import nodes -from mypy import join from mypy import experiments @@ -521,8 +520,8 @@ def visit_tuple_type(self, t: TupleType) -> None: item.accept(self) # if it's not builtins.tuple, then its bases should have tuple[Any] # TODO: put assert here if it's not too slow - if type(t.fallback) == Instance and t.fallback.type.fullname() == 'builtins.tuple': - fallback_item = join.join_type_list(t.items) + if isinstance(t.fallback, Instance) and t.fallback.type.fullname() == 'builtins.tuple': + fallback_item = UnionType.make_simplified_union(t.items) t.fallback.args = [fallback_item] def visit_typeddict_type(self, t: TypedDictType) -> None: diff --git a/mypy/types.py b/mypy/types.py index 4cc4787390f3..78b0420a6fa0 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -15,11 +15,6 @@ ) from mypy.sharedparse import argument_elide_name -import mypy - -MYPY = False -if MYPY: - from mypy import join T = TypeVar('T') @@ -876,7 +871,7 @@ def copy_modified(self, *, fallback: Instance = None, def slice(self, begin: int, stride: int, end: int) -> 'TupleType': new_items = self.items[begin:end:stride] - fallback_args = [mypy.join.join_type_list(new_items)] + fallback_args = [UnionType.make_simplified_union(new_items)] new_fallback = self.fallback.copy_modified(args=fallback_args) return TupleType(new_items, new_fallback, self.line, self.column, self.implicit) @@ -1718,7 +1713,7 @@ def set_typ_args(tp: Type, new_args: List[Type], line: int = -1, column: int = - if isinstance(tp, Instance): return Instance(tp.type, new_args, line, column) if isinstance(tp, TupleType): - fallback_args = [mypy.join.join_type_list(new_args)] + fallback_args = [UnionType.make_simplified_union(new_args)] fallback = tp.fallback.copy_modified(args=fallback_args) return tp.copy_modified(items=new_args, fallback=fallback) if isinstance(tp, UnionType): diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 98a8c13ec44c..c971f427a08b 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -367,7 +367,7 @@ Point3D = TypedDict('Point3D', {'x': int, 'y': int, 'z': int}) p1 = TaggedPoint(type='2d', x=0, y=0) p2 = Point3D(x=1, y=1, z=1) joined_points = [p1, p2] -reveal_type(p1) # E: Revealed type is 'TypedDict(type=builtins.str, x=builtins.int, y=builtins.int, _fallback=typing.Mapping[builtins.str, Union[builtins.str, builtins.int]])' +reveal_type(p1) # E: Revealed type is 'TypedDict(type=builtins.str, x=builtins.int, y=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.object])' reveal_type(p2) # E: Revealed type is 'TypedDict(x=builtins.int, y=builtins.int, z=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.int])' reveal_type(joined_points) # E: Revealed type is 'builtins.list[TypedDict(x=builtins.int, y=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.int])]' [builtins fixtures/dict.pyi] From 865ec244ee5b56ed8f3b93c14b2c586c9f7e08b3 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Thu, 6 Apr 2017 04:46:59 -0700 Subject: [PATCH 05/16] Type check fix --- mypy/expandtype.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 15f0e8ceaffa..eac7cca22663 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -112,6 +112,7 @@ def visit_overloaded(self, t: Overloaded) -> Type: def visit_tuple_type(self, t: TupleType) -> Type: new_fallback = expand_type(t.fallback, self.variables) + assert isinstance(new_fallback, Instance) return t.copy_modified(items=self.expand_types(t.items), fallback=new_fallback) def visit_typeddict_type(self, t: TypedDictType) -> Type: From a27613aee66b33e97ad9117a0417a36492711f95 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Mon, 1 May 2017 07:25:20 -0700 Subject: [PATCH 06/16] CR fixes --- mypy/checkexpr.py | 5 +- mypy/messages.py | 2 +- mypy/typeanal.py | 55 +++++++++++---------- test-data/unit/check-async-await.test | 2 +- test-data/unit/check-functions.test | 2 +- test-data/unit/check-generic-subtyping.test | 8 +-- test-data/unit/check-namedtuple.test | 4 +- test-data/unit/check-tuples.test | 4 +- test-data/unit/check-type-checks.test | 2 +- test-data/unit/pythoneval.test | 2 +- 10 files changed, 44 insertions(+), 42 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 0dcc98063ae6..d393d006f0eb 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2149,8 +2149,9 @@ def check_awaitable_expr(self, t: Type, ctx: Context, msg: str) -> Type: Also used by `async for` and `async with`. """ - if not self.chk.check_subtype(t, self.named_type('typing.Awaitable'), ctx, - msg, 'actual type', 'expected type'): + if not self.chk.check_subtype( + t, self.chk.named_generic_type('typing.Awaitable', [AnyType()]), ctx, msg, + 'actual type', 'expected type'): return AnyType() else: method = self.analyze_external_member_access('__await__', t, ctx) diff --git a/mypy/messages.py b/mypy/messages.py index 8f5bdd8290c7..acaa56a27a7b 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -253,7 +253,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: base_str = itype.type.fullname() else: base_str = itype.type.name() - if itype.args == []: + if itype.args == [] or len(itype.args) == 1 and type(itype.args[0]) == AnyType: # No type arguments. Place the type name in quotes to avoid # potential for confusion: otherwise, the type name could be # interpreted as a normal word. diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 78f302fd9316..c8cc4837851d 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -230,33 +230,34 @@ def visit_unbound_type(self, t: UnboundType) -> Type: info = sym.node # type: TypeInfo if info.fullname() == 'builtins.tuple': assert not t.args - t.args = [AnyType()] - # Analyze arguments and construct Instance type. The - # number of type arguments and their values are - # checked only later, since we do not always know the - # valid count at this point. Thus we may construct an - # Instance with an invalid number of type arguments. - instance = Instance(info, self.anal_array(t.args), t.line, t.column) - tup = info.tuple_type - if tup is not None: - # The class has a Tuple[...] base class so it will be - # represented as a tuple type. - if t.args: - self.fail('Generic tuple types not supported', t) - return AnyType() - return tup.copy_modified(items=self.anal_array(tup.items), - fallback=instance) - td = info.typeddict_type - if td is not None: - # The class has a TypedDict[...] base class so it will be - # represented as a typeddict type. - if t.args: - self.fail('Generic TypedDict types not supported', t) - return AnyType() - # Create a named TypedDictType - return td.copy_modified(item_types=self.anal_array(list(td.items.values())), - fallback=instance) - return instance + return Instance(info, self.anal_array([AnyType()]), t.line, t.column) + else: + # Analyze arguments and construct Instance type. The + # number of type arguments and their values are + # checked only later, since we do not always know the + # valid count at this point. Thus we may construct an + # Instance with an invalid number of type arguments. + instance = Instance(info, self.anal_array(t.args), t.line, t.column) + tup = info.tuple_type + if tup is not None: + # The class has a Tuple[...] base class so it will be + # represented as a tuple type. + if t.args: + self.fail('Generic tuple types not supported', t) + return AnyType() + return tup.copy_modified(items=self.anal_array(tup.items), + fallback=instance) + td = info.typeddict_type + if td is not None: + # The class has a TypedDict[...] base class so it will be + # represented as a typeddict type. + if t.args: + self.fail('Generic TypedDict types not supported', t) + return AnyType() + # Create a named TypedDictType + return td.copy_modified(item_types=self.anal_array(list(td.items.values())), + fallback=instance) + return instance else: return AnyType() diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 3c2f4c6b84ba..d363e67e8f1f 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -95,7 +95,7 @@ async def f() -> int: x = await g() return x [out] -main:6: error: Incompatible types in await (actual type Iterator[Any], expected type "Awaitable") +main:6: error: Incompatible types in await (actual type "Iterator", expected type "Awaitable") [case testAwaitArgumentError] diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 2341d27a7879..7ac4ce92f074 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -1486,7 +1486,7 @@ f(1, thing_in_kwargs=["hey"]) from typing import Tuple, Any def f(x, *args): # type: (...) -> None success_tuple_type = args # type: Tuple[Any, ...] - fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type tuple, variable has type None) + fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type "tuple", variable has type None) f(1, "hello") [builtins fixtures/tuple.pyi] [out] diff --git a/test-data/unit/check-generic-subtyping.test b/test-data/unit/check-generic-subtyping.test index 6ffa20565781..11e48cbed5b7 100644 --- a/test-data/unit/check-generic-subtyping.test +++ b/test-data/unit/check-generic-subtyping.test @@ -305,8 +305,8 @@ a = None # type: A c = None # type: C bc = None # type: B[C] -a.x = c # E: Incompatible types in assignment (expression has type "C", variable has type B[Any]) -a.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected B[Any] +a.x = c # E: Incompatible types in assignment (expression has type "C", variable has type "B") +a.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected "B" a.x = bc a.f(bc) [out] @@ -325,8 +325,8 @@ class B(Generic[T]): class A(B): def g(self) -> None: - self.x = c # E: Incompatible types in assignment (expression has type "C", variable has type B[Any]) - self.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected B[Any] + self.x = c # E: Incompatible types in assignment (expression has type "C", variable has type "B") + self.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected "B" self.x = bc self.f(bc) diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 51260733064a..ffb7452be572 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -286,12 +286,12 @@ from typing import NamedTuple X = NamedTuple('X', [('x', int), ('y', str)]) reveal_type(X._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' -X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any] +X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected "Iterable" -- # FIX: not a proper class method -- x = None # type: X -- reveal_type(x._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' --- x._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any] +-- x._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected "Iterable" [builtins fixtures/list.pyi] diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test index 799932d77c1a..4ad9a8360c76 100644 --- a/test-data/unit/check-tuples.test +++ b/test-data/unit/check-tuples.test @@ -91,7 +91,7 @@ from typing import Tuple t1 = None # type: Tuple[A, A] t2 = None # type: tuple -t1 = t2 # E: Incompatible types in assignment (expression has type tuple, variable has type "Tuple[A, A]") +t1 = t2 # E: Incompatible types in assignment (expression has type "tuple", variable has type "Tuple[A, A]") t2 = t1 class A: pass @@ -914,7 +914,7 @@ def f(a: Tuple) -> None: pass f(()) f((1,)) f(('', '')) -f(0) # E: Argument 1 to "f" has incompatible type "int"; expected tuple +f(0) # E: Argument 1 to "f" has incompatible type "int"; expected "tuple" [builtins fixtures/tuple.pyi] [case testTupleSingleton] diff --git a/test-data/unit/check-type-checks.test b/test-data/unit/check-type-checks.test index c4905a75ef78..da4c5dfa272e 100644 --- a/test-data/unit/check-type-checks.test +++ b/test-data/unit/check-type-checks.test @@ -107,7 +107,7 @@ def f(x: object) -> None: if isinstance(x, C): x.f(1) x.f('') - x.g() # E: C[Any] has no attribute "g" + x.g() # E: "C" has no attribute "g" x.g() # E: "object" has no attribute "g" [builtins fixtures/isinstance.pyi] [out] diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index c7e24e05bfd3..666cd0d236fe 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -399,7 +399,7 @@ f.write('x') f.write(b'x') f.foobar() [out] -_program.py:4: error: IO[Any] has no attribute "foobar" +_program.py:4: error: "IO" has no attribute "foobar" [case testGenericPatterns] from typing import Pattern From ea2b1b499230a912e31874ab0eda47f7cd455c2c Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Mon, 5 Jun 2017 02:26:26 -0700 Subject: [PATCH 07/16] Fix *[Any] -> * in expected error messages --- test-data/unit/check-async-await.test | 16 ++++++++-------- test-data/unit/check-functions.test | 2 +- test-data/unit/check-generics.test | 2 +- test-data/unit/pythoneval.test | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 68e561e9b980..8969adc03b0f 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -93,7 +93,7 @@ async def f() -> int: return x [typing fixtures/typing-full.pyi] [out] -main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type Awaitable[Any]) +main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type "Awaitable") [case testAwaitIteratorError] @@ -117,7 +117,7 @@ async def f() -> int: [builtins fixtures/async_await.pyi] [typing fixtures/typing-full.pyi] [out] -main:5: error: Incompatible types in await (actual type "int", expected type Awaitable[Any]) +main:5: error: Incompatible types in await (actual type "int", expected type "Awaitable") [case testAwaitResultError] @@ -290,7 +290,7 @@ class C: def __aenter__(self) -> int: pass async def __aexit__(self, x, y, z) -> None: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type Awaitable[Any]) + async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type "Awaitable") pass [builtins fixtures/async_await.pyi] [typing fixtures/typing-full.pyi] @@ -312,7 +312,7 @@ class C: async def __aenter__(self) -> int: pass def __aexit__(self, x, y, z) -> int: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type Awaitable[Any]) + async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type "Awaitable") pass [builtins fixtures/async_await.pyi] [typing fixtures/typing-full.pyi] @@ -644,11 +644,11 @@ def plain_host_generator() -> Generator[str, None, None]: async def plain_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) + x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type "Awaitable") x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable") x = await other_coroutine() @coroutine @@ -665,11 +665,11 @@ def decorated_host_generator() -> Generator[str, None, None]: @coroutine async def decorated_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) + x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type "Awaitable") x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable") x = await other_coroutine() [builtins fixtures/async_await.pyi] diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 0bdcebc2301f..1dea8730e89b 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -1480,7 +1480,7 @@ L = Callable[[Arg(name='x', type=int)], int] # ok # I have commented out the following test because I don't know how to expect the "defined here" note part of the error. # M = Callable[[Arg(gnome='x', type=int)], int] E: Invalid type alias E: Unexpected keyword argument "gnome" for "Arg" N = Callable[[Arg(name=None, type=int)], int] # ok -O = Callable[[List[Arg(int)]], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: Type expected within [...] # E: The type Type[List[Any]] is not generic and not indexable +O = Callable[[List[Arg(int)]], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: Type expected within [...] # E: The type Type[list] is not generic and not indexable P = Callable[[mypy_extensions.VarArg(int)], int] # ok Q = Callable[[Arg(int, type=int)], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "type" R = Callable[[Arg(int, 'x', name='y')], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "name" diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index 33106feca98d..46a4e14b7561 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -1504,7 +1504,7 @@ T = TypeVar('T') class C(Generic[T]): def __init__(self) -> None: pass x = C # type: Callable[[], C[int]] -y = C # type: Callable[[], int] # E: Incompatible types in assignment (expression has type Type[C[Any]], variable has type Callable[[], int]) +y = C # type: Callable[[], int] # E: Incompatible types in assignment (expression has type Type[C], variable has type Callable[[], int]) -- Special cases diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index c9ee1f322a28..21b016102d9b 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1122,7 +1122,7 @@ class MyDDict(t.DefaultDict[int,T], t.Generic[T]): MyDDict(dict)['0'] MyDDict(dict)[0] [out] -_program.py:6: error: Argument 1 to "defaultdict" has incompatible type Type[List[Any]]; expected Callable[[], str] +_program.py:6: error: Argument 1 to "defaultdict" has incompatible type Type[list]; expected Callable[[], str] _program.py:9: error: Invalid index type "str" for defaultdict[int, str]; expected type "int" _program.py:9: error: Incompatible types in assignment (expression has type "int", target has type "str") _program.py:19: error: Dict entry 0 has incompatible type "str": List[] From a230dd952e2cadd4c359a84569a13fafd4094f42 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Sat, 24 Jun 2017 11:11:06 -0700 Subject: [PATCH 08/16] CR fixes (partial) --- mypy/expandtype.py | 2 -- mypy/typeanal.py | 7 ++----- mypy/types.py | 6 ++---- test-data/unit/check-tuples.test | 4 ++-- test-data/unit/fixtures/callable.pyi | 4 ++-- test-data/unit/fixtures/f_string.pyi | 4 +++- test-data/unit/fixtures/isinstance.pyi | 4 ++-- test-data/unit/fixtures/list.pyi | 2 +- 8 files changed, 14 insertions(+), 19 deletions(-) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 18ae39c57c2f..027c94267cb7 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -7,8 +7,6 @@ FunctionLike, TypeVarDef ) -import mypy - def expand_type(typ: Type, env: Mapping[TypeVarId, Type]) -> Type: """Substitute any type variable references in a type given by a type diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 47c580d709b7..af1270c3a3df 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -240,6 +240,8 @@ def visit_unbound_type(self, t: UnboundType) -> Type: return t info = sym.node # type: TypeInfo if info.fullname() == 'builtins.tuple': + # tuple[int] or tuple[int, ...] are invalid + # The naked tuple should use canonical representation with type argument Any assert not t.args return Instance(info, self.anal_array([AnyType()]), t.line, t.column) else: @@ -633,11 +635,6 @@ def visit_callable_type(self, t: CallableType) -> None: def visit_tuple_type(self, t: TupleType) -> None: for item in t.items: item.accept(self) - # if it's not builtins.tuple, then its bases should have tuple[Any] - # TODO: put assert here if it's not too slow - if isinstance(t.fallback, Instance) and t.fallback.type.fullname() == 'builtins.tuple': - fallback_item = UnionType.make_simplified_union(t.items) - t.fallback.args = [fallback_item] def visit_typeddict_type(self, t: TypedDictType) -> None: for item_type in t.items.values(): diff --git a/mypy/types.py b/mypy/types.py index ad32bff2f83c..7eafca5af0dc 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -1496,7 +1496,7 @@ def visit_tuple_type(self, t: TupleType) -> str: s = self.list_str(t.items) if t.fallback and t.fallback.type: fallback_name = t.fallback.type.fullname() - if fallback_name not in ('builtins.tuple', 'builtins.object'): + if fallback_name != 'builtins.tuple': return 'Tuple[{}, fallback={}]'.format(s, t.fallback.accept(self)) return 'Tuple[{}]'.format(s) @@ -1747,9 +1747,7 @@ def set_typ_args(tp: Type, new_args: List[Type], line: int = -1, column: int = - if isinstance(tp, Instance): return Instance(tp.type, new_args, line, column) if isinstance(tp, TupleType): - fallback_args = [UnionType.make_simplified_union(new_args)] - fallback = tp.fallback.copy_modified(args=fallback_args) - return tp.copy_modified(items=new_args, fallback=fallback) + return tp.copy_modified(items=new_args) if isinstance(tp, UnionType): return UnionType(new_args, line, column) if isinstance(tp, CallableType): diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test index 4ad9a8360c76..47cf97e3f3e2 100644 --- a/test-data/unit/check-tuples.test +++ b/test-data/unit/check-tuples.test @@ -604,10 +604,10 @@ b = s in t [file builtins.py] from typing import TypeVar, Generic -_T = TypeVar('_T') +_T_co = TypeVar('_T_co', covariant=True) class object: def __init__(self) -> None: pass -class tuple(Generic[_T]): +class tuple(Generic[_T_co]): def __len__(self) -> int: pass def __str__(self) -> str: pass def __contains__(self, o: object) -> bool: pass diff --git a/test-data/unit/fixtures/callable.pyi b/test-data/unit/fixtures/callable.pyi index ae58648fac1e..190fd9686822 100644 --- a/test-data/unit/fixtures/callable.pyi +++ b/test-data/unit/fixtures/callable.pyi @@ -1,6 +1,6 @@ from typing import Generic, Tuple, TypeVar, Union -T = TypeVar('T') +T_co = TypeVar('T_co', covariant=True) class object: def __init__(self) -> None: pass @@ -8,7 +8,7 @@ class object: class type: def __init__(self, x) -> None: pass -class tuple(Generic[T]): pass +class tuple(Generic[T_co]): pass class function: pass diff --git a/test-data/unit/fixtures/f_string.pyi b/test-data/unit/fixtures/f_string.pyi index 78d39aee85b8..c8aaa0a9e606 100644 --- a/test-data/unit/fixtures/f_string.pyi +++ b/test-data/unit/fixtures/f_string.pyi @@ -5,6 +5,8 @@ from typing import TypeVar, Generic, Iterable, Iterator, List, overload T = TypeVar('T') +T_co = TypeVar('T_co', covariant=True) + class object: def __init__(self): pass @@ -20,7 +22,7 @@ class list(Iterable[T], Generic[T]): def __init__(self, x: Iterable[T]) -> None: pass def append(self, x: T) -> None: pass -class tuple(Generic[T]): pass +class tuple(Generic[T_co]): pass class function: pass class int: diff --git a/test-data/unit/fixtures/isinstance.pyi b/test-data/unit/fixtures/isinstance.pyi index ded946ce73fe..8ee7dfbaea83 100644 --- a/test-data/unit/fixtures/isinstance.pyi +++ b/test-data/unit/fixtures/isinstance.pyi @@ -1,6 +1,6 @@ from typing import Tuple, TypeVar, Generic, Union -T = TypeVar('T') +T_co = TypeVar('T_co', covariant=True) class object: def __init__(self) -> None: pass @@ -8,7 +8,7 @@ class object: class type: def __init__(self, x) -> None: pass -class tuple(Generic[T]): pass +class tuple(Generic[T_co]): pass class function: pass diff --git a/test-data/unit/fixtures/list.pyi b/test-data/unit/fixtures/list.pyi index dfacb3baedd9..d78317b75b0c 100644 --- a/test-data/unit/fixtures/list.pyi +++ b/test-data/unit/fixtures/list.pyi @@ -23,7 +23,7 @@ class list(Iterable[T], Generic[T]): def extend(self, x: Iterable[T]) -> None: pass _T_co = TypeVar('_T_co', covariant=True) -class tuple(Sequence[_T_co], Generic[_T_co]): pass +class tuple(Generic[_T_co]): pass class function: pass class int: pass class float: pass From a993ba637e1df061d155cdbd6a77900339fa73f9 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Sat, 24 Jun 2017 12:44:42 -0700 Subject: [PATCH 09/16] Update error messages --- mypy/messages.py | 2 +- test-data/unit/check-async-await.test | 18 +++++++++--------- test-data/unit/check-functions.test | 4 ++-- test-data/unit/check-generic-subtyping.test | 8 ++++---- test-data/unit/check-generics.test | 2 +- test-data/unit/check-namedtuple.test | 4 ++-- test-data/unit/check-tuples.test | 4 ++-- test-data/unit/check-type-checks.test | 2 +- test-data/unit/pythoneval.test | 6 +++--- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index 1f6af762968b..f5113daee745 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -253,7 +253,7 @@ def format_simple(self, typ: Type, verbosity: int = 0) -> str: base_str = itype.type.fullname() else: base_str = itype.type.name() - if itype.args == [] or len(itype.args) == 1 and type(itype.args[0]) == AnyType: + if itype.args == []: # No type arguments. Place the type name in quotes to avoid # potential for confusion: otherwise, the type name could be # interpreted as a normal word. diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 8969adc03b0f..f8ac01d8c830 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -93,7 +93,7 @@ async def f() -> int: return x [typing fixtures/typing-full.pyi] [out] -main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type "Awaitable") +main:7: error: Incompatible types in await (actual type Generator[int, None, str], expected type Awaitable[Any]) [case testAwaitIteratorError] @@ -105,7 +105,7 @@ async def f() -> int: return x [typing fixtures/typing-full.pyi] [out] -main:6: error: Incompatible types in await (actual type "Iterator", expected type "Awaitable") +main:6: error: Incompatible types in await (actual type Iterator[Any], expected type Awaitable[Any]) [case testAwaitArgumentError] @@ -117,7 +117,7 @@ async def f() -> int: [builtins fixtures/async_await.pyi] [typing fixtures/typing-full.pyi] [out] -main:5: error: Incompatible types in await (actual type "int", expected type "Awaitable") +main:5: error: Incompatible types in await (actual type "int", expected type Awaitable[Any]) [case testAwaitResultError] @@ -290,7 +290,7 @@ class C: def __aenter__(self) -> int: pass async def __aexit__(self, x, y, z) -> None: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type "Awaitable") + async with C() as x: # E: Incompatible types in "async with" for __aenter__ (actual type "int", expected type Awaitable[Any]) pass [builtins fixtures/async_await.pyi] [typing fixtures/typing-full.pyi] @@ -312,7 +312,7 @@ class C: async def __aenter__(self) -> int: pass def __aexit__(self, x, y, z) -> int: pass async def f() -> None: - async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type "Awaitable") + async with C() as x: # E: Incompatible types in "async with" for __aexit__ (actual type "int", expected type Awaitable[Any]) pass [builtins fixtures/async_await.pyi] [typing fixtures/typing-full.pyi] @@ -644,11 +644,11 @@ def plain_host_generator() -> Generator[str, None, None]: async def plain_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type "Awaitable") + x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable") + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) x = await other_coroutine() @coroutine @@ -665,11 +665,11 @@ def decorated_host_generator() -> Generator[str, None, None]: @coroutine async def decorated_host_coroutine() -> None: x = 0 - x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type "Awaitable") + x = await plain_generator() # E: Incompatible types in await (actual type Generator[str, None, int], expected type Awaitable[Any]) x = await plain_coroutine() x = await decorated_generator() x = await decorated_coroutine() - x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type "Awaitable") + x = await other_iterator() # E: Incompatible types in await (actual type "It", expected type Awaitable[Any]) x = await other_coroutine() [builtins fixtures/async_await.pyi] diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 3bffea2745c4..52fb94f99119 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -1480,7 +1480,7 @@ L = Callable[[Arg(name='x', type=int)], int] # ok # I have commented out the following test because I don't know how to expect the "defined here" note part of the error. # M = Callable[[Arg(gnome='x', type=int)], int] E: Invalid type alias E: Unexpected keyword argument "gnome" for "Arg" N = Callable[[Arg(name=None, type=int)], int] # ok -O = Callable[[List[Arg(int)]], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: Type expected within [...] # E: The type Type[list] is not generic and not indexable +O = Callable[[List[Arg(int)]], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: Type expected within [...] # E: The type Type[List[Any]] is not generic and not indexable P = Callable[[mypy_extensions.VarArg(int)], int] # ok Q = Callable[[Arg(int, type=int)], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "type" R = Callable[[Arg(int, 'x', name='y')], int] # E: Invalid type alias # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "name" @@ -1745,7 +1745,7 @@ f(1, thing_in_kwargs=["hey"]) from typing import Tuple, Any def f(x, *args): # type: (...) -> None success_tuple_type = args # type: Tuple[Any, ...] - fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type "tuple", variable has type None) + fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type tuple, variable has type None) f(1, "hello") [builtins fixtures/tuple.pyi] [out] diff --git a/test-data/unit/check-generic-subtyping.test b/test-data/unit/check-generic-subtyping.test index babd0cdbb0d0..6cae196bbe80 100644 --- a/test-data/unit/check-generic-subtyping.test +++ b/test-data/unit/check-generic-subtyping.test @@ -305,8 +305,8 @@ a = None # type: A c = None # type: C bc = None # type: B[C] -a.x = c # E: Incompatible types in assignment (expression has type "C", variable has type "B") -a.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected "B" +a.x = c # E: Incompatible types in assignment (expression has type "C", variable has type B[Any]) +a.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected B[Any] a.x = bc a.f(bc) [out] @@ -325,8 +325,8 @@ class B(Generic[T]): class A(B): def g(self) -> None: - self.x = c # E: Incompatible types in assignment (expression has type "C", variable has type "B") - self.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected "B" + self.x = c # E: Incompatible types in assignment (expression has type "C", variable has type B[Any]) + self.f(c) # E: Argument 1 to "f" of "B" has incompatible type "C"; expected B[Any] self.x = bc self.f(bc) diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index 46a4e14b7561..33106feca98d 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -1504,7 +1504,7 @@ T = TypeVar('T') class C(Generic[T]): def __init__(self) -> None: pass x = C # type: Callable[[], C[int]] -y = C # type: Callable[[], int] # E: Incompatible types in assignment (expression has type Type[C], variable has type Callable[[], int]) +y = C # type: Callable[[], int] # E: Incompatible types in assignment (expression has type Type[C[Any]], variable has type Callable[[], int]) -- Special cases diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 13eed90cdf1f..81aa3f6957e6 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -286,12 +286,12 @@ from typing import NamedTuple X = NamedTuple('X', [('x', int), ('y', str)]) reveal_type(X._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' -X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected "Iterable" +X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any] -- # FIX: not a proper class method -- x = None # type: X -- reveal_type(x._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' --- x._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected "Iterable" +-- x._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any] [builtins fixtures/list.pyi] diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test index 0ea506ecc620..7632390d8560 100644 --- a/test-data/unit/check-tuples.test +++ b/test-data/unit/check-tuples.test @@ -91,7 +91,7 @@ from typing import Tuple t1 = None # type: Tuple[A, A] t2 = None # type: tuple -t1 = t2 # E: Incompatible types in assignment (expression has type "tuple", variable has type "Tuple[A, A]") +t1 = t2 # E: Incompatible types in assignment (expression has type tuple, variable has type "Tuple[A, A]") t2 = t1 class A: pass @@ -914,7 +914,7 @@ def f(a: Tuple) -> None: pass f(()) f((1,)) f(('', '')) -f(0) # E: Argument 1 to "f" has incompatible type "int"; expected "tuple" +f(0) # E: Argument 1 to "f" has incompatible type "int"; expected tuple [builtins fixtures/tuple.pyi] [case testTupleSingleton] diff --git a/test-data/unit/check-type-checks.test b/test-data/unit/check-type-checks.test index da4c5dfa272e..c4905a75ef78 100644 --- a/test-data/unit/check-type-checks.test +++ b/test-data/unit/check-type-checks.test @@ -107,7 +107,7 @@ def f(x: object) -> None: if isinstance(x, C): x.f(1) x.f('') - x.g() # E: "C" has no attribute "g" + x.g() # E: C[Any] has no attribute "g" x.g() # E: "object" has no attribute "g" [builtins fixtures/isinstance.pyi] [out] diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 45ba1e8490d2..7c8584921cf8 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1122,7 +1122,7 @@ class MyDDict(t.DefaultDict[int,T], t.Generic[T]): MyDDict(dict)['0'] MyDDict(dict)[0] [out] -_program.py:6: error: Argument 1 to "defaultdict" has incompatible type Type[list]; expected Callable[[], str] +_program.py:6: error: Argument 1 to "defaultdict" has incompatible type Type[List[Any]]; expected Callable[[], str] _program.py:9: error: Invalid index type "str" for defaultdict[int, str]; expected type "int" _program.py:9: error: Incompatible types in assignment (expression has type "int", target has type "str") _program.py:19: error: Dict entry 0 has incompatible type "str": List[] @@ -1332,8 +1332,8 @@ reveal_type(g) with f('') as s: reveal_type(s) [out] -_program.py:13: error: Revealed type is 'def (x: builtins.int) -> contextlib.GeneratorContextManager[builtins.str*]' -_program.py:14: error: Revealed type is 'def (*x: builtins.str) -> contextlib.GeneratorContextManager[builtins.int*]' +_program.py:13: error: Revealed type is 'def (x: builtins.int) -> contextlib.ContextManager[builtins.str*]' +_program.py:14: error: Revealed type is 'def (*x: builtins.str) -> contextlib.ContextManager[builtins.int*]' _program.py:16: error: Argument 1 to "f" has incompatible type "str"; expected "int" _program.py:17: error: Revealed type is 'builtins.str*' From fb4ce354cd11246b71274c3d9fc233f5532dbea2 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Sat, 24 Jun 2017 13:14:31 -0700 Subject: [PATCH 10/16] Updated typeshed to recent master --- typeshed | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typeshed b/typeshed index 1ea3d2de5794..6fe68fd12072 160000 --- a/typeshed +++ b/typeshed @@ -1 +1 @@ -Subproject commit 1ea3d2de5794c2224a1bc086aa471d0097699bf1 +Subproject commit 6fe68fd12072f5019d9e460c6418f512cf9006a1 From f292ea4ec665442685e74bf6d74f3f20b54a0fbb Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Sun, 25 Jun 2017 01:45:52 -0700 Subject: [PATCH 11/16] Revert weird change to test output --- test-data/unit/pythoneval.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 7c8584921cf8..56f0f3de092f 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1332,8 +1332,8 @@ reveal_type(g) with f('') as s: reveal_type(s) [out] -_program.py:13: error: Revealed type is 'def (x: builtins.int) -> contextlib.ContextManager[builtins.str*]' -_program.py:14: error: Revealed type is 'def (*x: builtins.str) -> contextlib.ContextManager[builtins.int*]' +_program.py:13: error: Revealed type is 'def (x: builtins.int) -> contextlib.GeneratorContextManager[builtins.str*]' +_program.py:14: error: Revealed type is 'def (*x: builtins.str) -> contextlib.GeneratorContextManager[builtins.int*]' _program.py:16: error: Argument 1 to "f" has incompatible type "str"; expected "int" _program.py:17: error: Revealed type is 'builtins.str*' From 52b0c0fcb630579a5f1c040e1847b1f1abd5980b Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Sun, 25 Jun 2017 03:36:11 -0700 Subject: [PATCH 12/16] Empty commit to test Travis From f991a2b2a30755ecc8c94ec81c85f861c280811c Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Mon, 24 Jul 2017 22:49:40 -0700 Subject: [PATCH 13/16] Fix error message in test --- test-data/unit/check-namedtuple.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 7d313da71452..1f9eab890cae 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -415,7 +415,7 @@ b = B._make(['']) # type: B [case testNamedTupleIncompatibleRedefinition] from typing import NamedTuple class Crash(NamedTuple): - count: int # E: Incompatible types in assignment (expression has type "int", base class "tuple" defined the type as Callable[[Tuple[Any, ...], Any], int]) + count: int # E: Incompatible types in assignment (expression has type "int", base class "tuple" defined the type as Callable[[tuple, Any], int]) [builtins fixtures/tuple.pyi] [case testNamedTupleInClassNamespace] From c1304ba94548ab407d17ef985b4b2f591edd6849 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Tue, 25 Jul 2017 01:01:39 -0700 Subject: [PATCH 14/16] Revert tuple normalization --- mypy/typeanal.py | 60 ++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index f544408569ab..1d66834d4a7a 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -260,39 +260,33 @@ def visit_unbound_type(self, t: UnboundType) -> Type: self.fail('Invalid type "{}"'.format(name), t) return t info = sym.node # type: TypeInfo - if info.fullname() == 'builtins.tuple': - # tuple[int] or tuple[int, ...] are invalid - # The naked tuple should use canonical representation with type argument Any - assert not t.args - return Instance(info, self.anal_array([AnyType()]), t.line, t.column) - else: - # Analyze arguments and construct Instance type. The - # number of type arguments and their values are - # checked only later, since we do not always know the - # valid count at this point. Thus we may construct an - # Instance with an invalid number of type arguments. - instance = Instance(info, self.anal_array(t.args), t.line, t.column) - instance.from_generic_builtin = sym.normalized - tup = info.tuple_type - if tup is not None: - # The class has a Tuple[...] base class so it will be - # represented as a tuple type. - if t.args: - self.fail('Generic tuple types not supported', t) - return AnyType() - return tup.copy_modified(items=self.anal_array(tup.items), - fallback=instance) - td = info.typeddict_type - if td is not None: - # The class has a TypedDict[...] base class so it will be - # represented as a typeddict type. - if t.args: - self.fail('Generic TypedDict types not supported', t) - return AnyType() - # Create a named TypedDictType - return td.copy_modified(item_types=self.anal_array(list(td.items.values())), - fallback=instance) - return instance + # Analyze arguments and construct Instance type. The + # number of type arguments and their values are + # checked only later, since we do not always know the + # valid count at this point. Thus we may construct an + # Instance with an invalid number of type arguments. + instance = Instance(info, self.anal_array(t.args), t.line, t.column) + instance.from_generic_builtin = sym.normalized + tup = info.tuple_type + if tup is not None: + # The class has a Tuple[...] base class so it will be + # represented as a tuple type. + if t.args: + self.fail('Generic tuple types not supported', t) + return AnyType() + return tup.copy_modified(items=self.anal_array(tup.items), + fallback=instance) + td = info.typeddict_type + if td is not None: + # The class has a TypedDict[...] base class so it will be + # represented as a typeddict type. + if t.args: + self.fail('Generic TypedDict types not supported', t) + return AnyType() + # Create a named TypedDictType + return td.copy_modified(item_types=self.anal_array(list(td.items.values())), + fallback=instance) + return instance else: return AnyType() From 959e6c998684481429e5b3840657b7d5fee5bb65 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Tue, 25 Jul 2017 01:15:24 -0700 Subject: [PATCH 15/16] Revert changes to pyi --- test-data/unit/fixtures/callable.pyi | 4 ++-- test-data/unit/fixtures/f_string.pyi | 4 +--- test-data/unit/fixtures/isinstance.pyi | 4 ++-- test-data/unit/fixtures/isinstancelist.pyi | 9 ++++----- test-data/unit/fixtures/list.pyi | 6 +++--- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/test-data/unit/fixtures/callable.pyi b/test-data/unit/fixtures/callable.pyi index 190fd9686822..ae58648fac1e 100644 --- a/test-data/unit/fixtures/callable.pyi +++ b/test-data/unit/fixtures/callable.pyi @@ -1,6 +1,6 @@ from typing import Generic, Tuple, TypeVar, Union -T_co = TypeVar('T_co', covariant=True) +T = TypeVar('T') class object: def __init__(self) -> None: pass @@ -8,7 +8,7 @@ class object: class type: def __init__(self, x) -> None: pass -class tuple(Generic[T_co]): pass +class tuple(Generic[T]): pass class function: pass diff --git a/test-data/unit/fixtures/f_string.pyi b/test-data/unit/fixtures/f_string.pyi index c8aaa0a9e606..78d39aee85b8 100644 --- a/test-data/unit/fixtures/f_string.pyi +++ b/test-data/unit/fixtures/f_string.pyi @@ -5,8 +5,6 @@ from typing import TypeVar, Generic, Iterable, Iterator, List, overload T = TypeVar('T') -T_co = TypeVar('T_co', covariant=True) - class object: def __init__(self): pass @@ -22,7 +20,7 @@ class list(Iterable[T], Generic[T]): def __init__(self, x: Iterable[T]) -> None: pass def append(self, x: T) -> None: pass -class tuple(Generic[T_co]): pass +class tuple(Generic[T]): pass class function: pass class int: diff --git a/test-data/unit/fixtures/isinstance.pyi b/test-data/unit/fixtures/isinstance.pyi index 8ee7dfbaea83..ded946ce73fe 100644 --- a/test-data/unit/fixtures/isinstance.pyi +++ b/test-data/unit/fixtures/isinstance.pyi @@ -1,6 +1,6 @@ from typing import Tuple, TypeVar, Generic, Union -T_co = TypeVar('T_co', covariant=True) +T = TypeVar('T') class object: def __init__(self) -> None: pass @@ -8,7 +8,7 @@ class object: class type: def __init__(self, x) -> None: pass -class tuple(Generic[T_co]): pass +class tuple(Generic[T]): pass class function: pass diff --git a/test-data/unit/fixtures/isinstancelist.pyi b/test-data/unit/fixtures/isinstancelist.pyi index 7a812dcc3349..dd1d90f9e547 100644 --- a/test-data/unit/fixtures/isinstancelist.pyi +++ b/test-data/unit/fixtures/isinstancelist.pyi @@ -6,11 +6,6 @@ class object: class type: def __init__(self, x) -> None: pass -Tco = TypeVar('Tco', covariant=True) -class tuple(Sequence[Tco], Generic[Tco]): - def __iter__(self) -> Iterator[Tco]: pass - def __getitem__(self, x: int) -> Tco: pass - class function: pass class ellipsis: pass @@ -28,6 +23,10 @@ T = TypeVar('T') KT = TypeVar('KT') VT = TypeVar('VT') +class tuple(Sequence[T], Generic[T]): + def __iter__(self) -> Iterator[T]: pass + def __getitem__(self, x: int) -> T: pass + class list(Iterable[T]): def __iter__(self) -> Iterator[T]: pass def __mul__(self, x: int) -> list[T]: pass diff --git a/test-data/unit/fixtures/list.pyi b/test-data/unit/fixtures/list.pyi index d78317b75b0c..c949a7644ea7 100644 --- a/test-data/unit/fixtures/list.pyi +++ b/test-data/unit/fixtures/list.pyi @@ -1,6 +1,6 @@ # Builtins stub used in list-related test cases. -from typing import TypeVar, Generic, Iterable, Iterator, overload, Sequence +from typing import TypeVar, Generic, Iterable, Iterator, overload T = TypeVar('T') @@ -22,8 +22,8 @@ class list(Iterable[T], Generic[T]): def append(self, x: T) -> None: pass def extend(self, x: Iterable[T]) -> None: pass -_T_co = TypeVar('_T_co', covariant=True) -class tuple(Generic[_T_co]): pass +class tuple(Generic[T]): pass + class function: pass class int: pass class float: pass From 8edde235fac24c6b81e8b8046a6a348961f68a66 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Tue, 25 Jul 2017 01:26:41 -0700 Subject: [PATCH 16/16] Make tuple generic in most stubs --- test-data/unit/fixtures/async_await.pyi | 4 ++-- test-data/unit/fixtures/bool.pyi | 4 +++- test-data/unit/fixtures/dict.pyi | 2 +- test-data/unit/fixtures/exception.pyi | 4 +++- test-data/unit/fixtures/fine_grained.pyi | 7 +++++-- test-data/unit/fixtures/float.pyi | 5 ++++- test-data/unit/fixtures/floatdict.pyi | 2 +- test-data/unit/fixtures/for.pyi | 2 +- test-data/unit/fixtures/module.pyi | 2 +- test-data/unit/fixtures/module_all.pyi | 2 +- test-data/unit/fixtures/module_all_python2.pyi | 2 +- test-data/unit/fixtures/primitives.pyi | 4 +++- test-data/unit/fixtures/set.pyi | 2 +- test-data/unit/fixtures/slice.pyi | 4 +++- test-data/unit/fixtures/type.pyi | 2 +- test-data/unit/fixtures/union.pyi | 7 +++---- 16 files changed, 34 insertions(+), 21 deletions(-) diff --git a/test-data/unit/fixtures/async_await.pyi b/test-data/unit/fixtures/async_await.pyi index 42c1b53eb4bd..763e9fbc2f7e 100644 --- a/test-data/unit/fixtures/async_await.pyi +++ b/test-data/unit/fixtures/async_await.pyi @@ -1,7 +1,7 @@ import typing T = typing.TypeVar('T') -class list(typing.Generic[T], typing.Sequence[T]): pass +class list(typing.Sequence[T]): pass class object: def __init__(self): pass @@ -11,7 +11,7 @@ class int: pass class str: pass class dict: pass class set: pass -class tuple: pass +class tuple(typing.Generic[T]): pass class BaseException: pass class StopIteration(BaseException): pass class StopAsyncIteration(BaseException): pass diff --git a/test-data/unit/fixtures/bool.pyi b/test-data/unit/fixtures/bool.pyi index c4b4f3080f15..a1d1b9c1fdf5 100644 --- a/test-data/unit/fixtures/bool.pyi +++ b/test-data/unit/fixtures/bool.pyi @@ -1,10 +1,12 @@ # builtins stub used in boolean-related test cases. +from typing import Generic, TypeVar +T = TypeVar('T') class object: def __init__(self) -> None: pass class type: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class bool: pass class int: pass diff --git a/test-data/unit/fixtures/dict.pyi b/test-data/unit/fixtures/dict.pyi index 4182afb0eecd..a271315e4dde 100644 --- a/test-data/unit/fixtures/dict.pyi +++ b/test-data/unit/fixtures/dict.pyi @@ -35,7 +35,7 @@ class list(Iterable[T], Generic[T]): # needed by some test cases def __iter__(self) -> Iterator[T]: pass def __mul__(self, x: int) -> list[T]: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class float: pass class bool: pass diff --git a/test-data/unit/fixtures/exception.pyi b/test-data/unit/fixtures/exception.pyi index 5a2482dc1f87..999a73739364 100644 --- a/test-data/unit/fixtures/exception.pyi +++ b/test-data/unit/fixtures/exception.pyi @@ -1,9 +1,11 @@ +from typing import Generic, TypeVar +T = TypeVar('T') class object: def __init__(self): pass class type: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class int: pass class str: pass diff --git a/test-data/unit/fixtures/fine_grained.pyi b/test-data/unit/fixtures/fine_grained.pyi index 83429cd38314..b2e104ccfceb 100644 --- a/test-data/unit/fixtures/fine_grained.pyi +++ b/test-data/unit/fixtures/fine_grained.pyi @@ -4,6 +4,9 @@ # enough to handle them. import types +from typing import TypeVar, Generic + +T = TypeVar('T') class Any: pass @@ -20,7 +23,7 @@ class str: class float: pass class bytes: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class ellipsis: pass -class list: pass +class list(Generic[T]): pass diff --git a/test-data/unit/fixtures/float.pyi b/test-data/unit/fixtures/float.pyi index 38bdc08a03c5..1126d6158c6a 100644 --- a/test-data/unit/fixtures/float.pyi +++ b/test-data/unit/fixtures/float.pyi @@ -1,3 +1,6 @@ +from typing import Generic, TypeVar +T = TypeVar('T') + Any = 0 class object: @@ -12,7 +15,7 @@ class str: class bytes: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class ellipsis: pass diff --git a/test-data/unit/fixtures/floatdict.pyi b/test-data/unit/fixtures/floatdict.pyi index 9a34f8d369a0..54850d7f6e27 100644 --- a/test-data/unit/fixtures/floatdict.pyi +++ b/test-data/unit/fixtures/floatdict.pyi @@ -18,7 +18,7 @@ class str: class bytes: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class ellipsis: pass diff --git a/test-data/unit/fixtures/for.pyi b/test-data/unit/fixtures/for.pyi index 47628062f118..8b8ce1c3a500 100644 --- a/test-data/unit/fixtures/for.pyi +++ b/test-data/unit/fixtures/for.pyi @@ -9,7 +9,7 @@ class object: def __init__(self) -> None: pass class type: pass -class tuple: pass +class tuple(Generic[t]): pass class function: pass class bool: pass class int: pass # for convenience diff --git a/test-data/unit/fixtures/module.pyi b/test-data/unit/fixtures/module.pyi index 44a4dfe0c277..ac1d3688ed12 100644 --- a/test-data/unit/fixtures/module.pyi +++ b/test-data/unit/fixtures/module.pyi @@ -13,7 +13,7 @@ class function: pass class int: pass class str: pass class bool: pass -class tuple: pass +class tuple(Generic[T]): pass class dict(Generic[T, S]): pass class ellipsis: pass diff --git a/test-data/unit/fixtures/module_all.pyi b/test-data/unit/fixtures/module_all.pyi index 2ab6bc66f6f0..87959fefbff5 100644 --- a/test-data/unit/fixtures/module_all.pyi +++ b/test-data/unit/fixtures/module_all.pyi @@ -14,5 +14,5 @@ class list(Generic[_T], Sequence[_T]): def append(self, x: _T): pass def extend(self, x: Sequence[_T]): pass def __add__(self, rhs: Sequence[_T]) -> list[_T]: pass -class tuple: pass +class tuple(Generic[_T]): pass class ellipsis: pass diff --git a/test-data/unit/fixtures/module_all_python2.pyi b/test-data/unit/fixtures/module_all_python2.pyi index 5a48e60c512d..989333c5f41a 100644 --- a/test-data/unit/fixtures/module_all_python2.pyi +++ b/test-data/unit/fixtures/module_all_python2.pyi @@ -12,4 +12,4 @@ class list(Generic[_T], Sequence[_T]): def append(self, x: _T): pass def extend(self, x: Sequence[_T]): pass def __add__(self, rhs: Sequence[_T]) -> list[_T]: pass -class tuple: pass +class tuple(Generic[_T]): pass diff --git a/test-data/unit/fixtures/primitives.pyi b/test-data/unit/fixtures/primitives.pyi index 4b5611b0bace..6cedba37c6c1 100644 --- a/test-data/unit/fixtures/primitives.pyi +++ b/test-data/unit/fixtures/primitives.pyi @@ -1,4 +1,6 @@ # builtins stub with non-generic primitive types +from typing import Generic, TypeVar +T = TypeVar('T') class object: def __init__(self) -> None: pass @@ -17,5 +19,5 @@ class str: def format(self, *args) -> str: pass class bytes: pass class bytearray: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass diff --git a/test-data/unit/fixtures/set.pyi b/test-data/unit/fixtures/set.pyi index cb8bbcf841e7..79d53e832291 100644 --- a/test-data/unit/fixtures/set.pyi +++ b/test-data/unit/fixtures/set.pyi @@ -8,7 +8,7 @@ class object: def __init__(self) -> None: pass class type: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class int: pass diff --git a/test-data/unit/fixtures/slice.pyi b/test-data/unit/fixtures/slice.pyi index c01ffbb1ca4c..47c1999aecb7 100644 --- a/test-data/unit/fixtures/slice.pyi +++ b/test-data/unit/fixtures/slice.pyi @@ -1,10 +1,12 @@ # Builtins stub used in slicing test cases. +from typing import Generic, TypeVar +T = TypeVar('T') class object: def __init__(self): pass class type: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class int: pass diff --git a/test-data/unit/fixtures/type.pyi b/test-data/unit/fixtures/type.pyi index 7600021a30ea..4a2dcac1ab4b 100644 --- a/test-data/unit/fixtures/type.pyi +++ b/test-data/unit/fixtures/type.pyi @@ -13,7 +13,7 @@ class list(Generic[T]): pass class type: def mro(self) -> List['type']: pass -class tuple: pass +class tuple(Generic[T]): pass class function: pass class bool: pass class int: pass diff --git a/test-data/unit/fixtures/union.pyi b/test-data/unit/fixtures/union.pyi index 78a41f9272e6..489e3ddb6ef9 100644 --- a/test-data/unit/fixtures/union.pyi +++ b/test-data/unit/fixtures/union.pyi @@ -1,7 +1,8 @@ # Builtins stub used in tuple-related test cases. from isinstance import isinstance -from typing import Iterable, TypeVar +from typing import Iterable, TypeVar, Generic +T = TypeVar('T') class object: def __init__(self): pass @@ -9,9 +10,7 @@ class object: class type: pass class function: pass -# Current tuple types get special treatment in the type checker, thus there -# is no need for type arguments here. -class tuple: pass +class tuple(Generic[T]): pass # We need int for indexing tuples. class int: pass