Skip to content

Commit 882ccc1

Browse files
author
hauntsaninja
committed
types: change type of CallableType.variables
Creates a number of TODOs that I shall get to.
1 parent 8cb584f commit 882ccc1

File tree

12 files changed

+86
-59
lines changed

12 files changed

+86
-59
lines changed

mypy/checker.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,15 +1389,14 @@ def expand_typevars(self, defn: FuncItem,
13891389
typ: CallableType) -> List[Tuple[FuncItem, CallableType]]:
13901390
# TODO use generator
13911391
subst = [] # type: List[List[Tuple[TypeVarId, Type]]]
1392-
tvars = typ.variables or []
1393-
tvars = tvars[:]
1392+
tvars = list(typ.variables) or []
13941393
if defn.info:
13951394
# Class type variables
13961395
tvars += defn.info.defn.type_vars or []
1396+
# TODO(shantanu): audit for paramspec
13971397
for tvar in tvars:
1398-
if tvar.values:
1399-
subst.append([(tvar.id, value)
1400-
for value in tvar.values])
1398+
if isinstance(tvar, TypeVarDef) and tvar.values:
1399+
subst.append([(tvar.id, value) for value in tvar.values])
14011400
# Make a copy of the function to check for each combination of
14021401
# value restricted type variables. (Except when running mypyc,
14031402
# where we need one canonical version of the function.)

mypy/checkexpr.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4311,6 +4311,8 @@ def merge_typevars_in_callables_by_name(
43114311
for tvdef in target.variables:
43124312
name = tvdef.fullname
43134313
if name not in unique_typevars:
4314+
# TODO(shantanu): fix for ParamSpecDef
4315+
assert isinstance(tvdef, TypeVarDef)
43144316
unique_typevars[name] = TypeVarType(tvdef)
43154317
variables.append(tvdef)
43164318
rename[tvdef.id] = unique_typevars[name]

mypy/checkmember.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"""Type checking of attribute access"""
22

3-
from typing import cast, Callable, Optional, Union, List
3+
from typing import cast, Callable, Optional, Union, List, Sequence
44
from typing_extensions import TYPE_CHECKING
55

66
from mypy.types import (
77
Type, Instance, AnyType, TupleType, TypedDictType, CallableType, FunctionLike, TypeVarDef,
8-
Overloaded, TypeVarType, UnionType, PartialType, TypeOfAny, LiteralType,
8+
TypeVarLikeDef, Overloaded, TypeVarType, UnionType, PartialType, TypeOfAny, LiteralType,
99
DeletedType, NoneType, TypeType, has_type_vars, get_proper_type, ProperType
1010
)
1111
from mypy.nodes import (
@@ -676,7 +676,7 @@ def analyze_class_attribute_access(itype: Instance,
676676
name: str,
677677
mx: MemberContext,
678678
override_info: Optional[TypeInfo] = None,
679-
original_vars: Optional[List[TypeVarDef]] = None
679+
original_vars: Optional[Sequence[TypeVarLikeDef]] = None
680680
) -> Optional[Type]:
681681
"""Analyze access to an attribute on a class object.
682682
@@ -839,7 +839,7 @@ def analyze_enum_class_attribute_access(itype: Instance,
839839
def add_class_tvars(t: ProperType, isuper: Optional[Instance],
840840
is_classmethod: bool,
841841
original_type: Type,
842-
original_vars: Optional[List[TypeVarDef]] = None) -> Type:
842+
original_vars: Optional[Sequence[TypeVarLikeDef]] = None) -> Type:
843843
"""Instantiate type variables during analyze_class_attribute_access,
844844
e.g T and Q in the following:
845845
@@ -883,7 +883,7 @@ class B(A[str]): pass
883883
assert isuper is not None
884884
t = cast(CallableType, expand_type_by_instance(t, isuper))
885885
freeze_type_vars(t)
886-
return t.copy_modified(variables=tvars + t.variables)
886+
return t.copy_modified(variables=list(tvars) + list(t.variables))
887887
elif isinstance(t, Overloaded):
888888
return Overloaded([cast(CallableType, add_class_tvars(item, isuper,
889889
is_classmethod, original_type,

mypy/expandtype.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ def freshen_function_type_vars(callee: F) -> F:
4040
tvdefs = []
4141
tvmap = {} # type: Dict[TypeVarId, Type]
4242
for v in callee.variables:
43+
# TODO(shantanu): fix for ParamSpecDef
44+
assert isinstance(v, TypeVarDef)
4345
tvdef = TypeVarDef.new_unification_variable(v)
4446
tvdefs.append(tvdef)
4547
tvmap[v.id] = TypeVarType(tvdef)

mypy/fixup.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
from mypy.types import (
1212
CallableType, Instance, Overloaded, TupleType, TypedDictType,
1313
TypeVarType, UnboundType, UnionType, TypeVisitor, LiteralType,
14-
TypeType, NOT_READY, TypeAliasType, AnyType, TypeOfAny)
14+
TypeType, NOT_READY, TypeAliasType, AnyType, TypeOfAny, TypeVarDef
15+
)
1516
from mypy.visitor import NodeVisitor
1617
from mypy.lookup import lookup_fully_qualified
1718

@@ -183,10 +184,11 @@ def visit_callable_type(self, ct: CallableType) -> None:
183184
if ct.ret_type is not None:
184185
ct.ret_type.accept(self)
185186
for v in ct.variables:
186-
if v.values:
187-
for val in v.values:
188-
val.accept(self)
189-
v.upper_bound.accept(self)
187+
if isinstance(v, TypeVarDef):
188+
if v.values:
189+
for val in v.values:
190+
val.accept(self)
191+
v.upper_bound.accept(self)
190192
for arg in ct.bound_args:
191193
if arg:
192194
arg.accept(self)

mypy/messages.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from mypy.errors import Errors
2222
from mypy.types import (
2323
Type, CallableType, Instance, TypeVarType, TupleType, TypedDictType, LiteralType,
24-
UnionType, NoneType, AnyType, Overloaded, FunctionLike, DeletedType, TypeType,
24+
UnionType, NoneType, AnyType, Overloaded, FunctionLike, DeletedType, TypeType, TypeVarDef,
2525
UninhabitedType, TypeOfAny, UnboundType, PartialType, get_proper_type, ProperType,
2626
get_proper_types
2727
)
@@ -1862,16 +1862,20 @@ def [T <: int] f(self, x: int, y: T) -> None
18621862
if tp.variables:
18631863
tvars = []
18641864
for tvar in tp.variables:
1865-
upper_bound = get_proper_type(tvar.upper_bound)
1866-
if (isinstance(upper_bound, Instance) and
1867-
upper_bound.type.fullname != 'builtins.object'):
1868-
tvars.append('{} <: {}'.format(tvar.name, format_type_bare(upper_bound)))
1869-
elif tvar.values:
1870-
tvars.append('{} in ({})'
1871-
.format(tvar.name, ', '.join([format_type_bare(tp)
1872-
for tp in tvar.values])))
1865+
if isinstance(tvar, TypeVarDef):
1866+
upper_bound = get_proper_type(tvar.upper_bound)
1867+
if (isinstance(upper_bound, Instance) and
1868+
upper_bound.type.fullname != 'builtins.object'):
1869+
tvars.append('{} <: {}'.format(tvar.name, format_type_bare(upper_bound)))
1870+
elif tvar.values:
1871+
tvars.append('{} in ({})'
1872+
.format(tvar.name, ', '.join([format_type_bare(tp)
1873+
for tp in tvar.values])))
1874+
else:
1875+
tvars.append(tvar.name)
18731876
else:
1874-
tvars.append(tvar.name)
1877+
# For other TypeVarLikeDefs, just use the repr
1878+
tvars.append(repr(tvar))
18751879
s = '[{}] {}'.format(', '.join(tvars), s)
18761880
return 'def {}'.format(s)
18771881

mypy/plugins/default.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from mypy.plugins.common import try_getting_str_literals
1111
from mypy.types import (
1212
Type, Instance, AnyType, TypeOfAny, CallableType, NoneType, TypedDictType,
13-
TypeVarType, TPDICT_FB_NAMES, get_proper_type, LiteralType
13+
TypeVarDef, TypeVarType, TPDICT_FB_NAMES, get_proper_type, LiteralType
1414
)
1515
from mypy.subtypes import is_subtype
1616
from mypy.typeops import make_simplified_union
@@ -204,6 +204,7 @@ def typed_dict_get_signature_callback(ctx: MethodSigContext) -> CallableType:
204204
# Tweak the signature to include the value type as context. It's
205205
# only needed for type inference since there's a union with a type
206206
# variable that accepts everything.
207+
assert isinstance(signature.variables[0], TypeVarDef)
207208
tv = TypeVarType(signature.variables[0])
208209
return signature.copy_modified(
209210
arg_types=[signature.arg_types[0],
@@ -269,6 +270,7 @@ def typed_dict_pop_signature_callback(ctx: MethodSigContext) -> CallableType:
269270
# Tweak the signature to include the value type as context. It's
270271
# only needed for type inference since there's a union with a type
271272
# variable that accepts everything.
273+
assert isinstance(signature.variables[0], TypeVarDef)
272274
tv = TypeVarType(signature.variables[0])
273275
typ = make_simplified_union([value_type, tv])
274276
return signature.copy_modified(

mypy/server/astmerge.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,10 @@ def visit_callable_type(self, typ: CallableType) -> None:
370370
if typ.fallback is not None:
371371
typ.fallback.accept(self)
372372
for tv in typ.variables:
373-
tv.upper_bound.accept(self)
374-
for value in tv.values:
375-
value.accept(self)
373+
if isinstance(tv, TypeVarDef):
374+
tv.upper_bound.accept(self)
375+
for value in tv.values:
376+
value.accept(self)
376377

377378
def visit_overloaded(self, t: Overloaded) -> None:
378379
for item in t.items():

mypy/type_visitor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313

1414
from abc import abstractmethod
1515
from mypy.ordered_dict import OrderedDict
16-
from typing import Generic, TypeVar, cast, Any, List, Callable, Iterable, Optional, Set
16+
from typing import Generic, TypeVar, cast, Any, List, Callable, Iterable, Optional, Set, Sequence
1717
from mypy_extensions import trait
1818

1919
T = TypeVar('T')
2020

2121
from mypy.types import (
2222
Type, AnyType, CallableType, Overloaded, TupleType, TypedDictType, LiteralType,
2323
RawExpressionType, Instance, NoneType, TypeType,
24-
UnionType, TypeVarType, PartialType, DeletedType, UninhabitedType, TypeVarDef,
24+
UnionType, TypeVarType, PartialType, DeletedType, UninhabitedType, TypeVarDef, TypeVarLikeDef,
2525
UnboundType, ErasedType, StarType, EllipsisType, TypeList, CallableArgument,
2626
PlaceholderType, TypeAliasType, get_proper_type
2727
)
@@ -218,7 +218,7 @@ def translate_types(self, types: Iterable[Type]) -> List[Type]:
218218
return [t.accept(self) for t in types]
219219

220220
def translate_variables(self,
221-
variables: List[TypeVarDef]) -> List[TypeVarDef]:
221+
variables: Sequence[TypeVarLikeDef]) -> Sequence[TypeVarLikeDef]:
222222
return variables
223223

224224
def visit_overloaded(self, t: Overloaded) -> Type:

mypy/typeanal.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
CallableType, NoneType, ErasedType, DeletedType, TypeList, TypeVarDef, SyntheticTypeVisitor,
1717
StarType, PartialType, EllipsisType, UninhabitedType, TypeType,
1818
CallableArgument, TypeQuery, union_items, TypeOfAny, LiteralType, RawExpressionType,
19-
PlaceholderType, Overloaded, get_proper_type, TypeAliasType
19+
PlaceholderType, Overloaded, get_proper_type, TypeAliasType, TypeVarLikeDef
2020
)
2121

2222
from mypy.nodes import (
@@ -205,6 +205,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
205205
' to define generic alias'.format(t.name), t)
206206
return AnyType(TypeOfAny.from_error)
207207
if isinstance(sym.node, TypeVarExpr) and tvar_def is not None:
208+
assert isinstance(tvar_def, TypeVarDef)
208209
if len(t.args) > 0:
209210
self.fail('Type variable "{}" used with arguments'.format(t.name), t)
210211
return TypeVarType(tvar_def, t.line)
@@ -813,8 +814,9 @@ def infer_type_variables(self,
813814
tvars.append(tvar_expr)
814815
return list(zip(names, tvars))
815816

816-
def bind_function_type_variables(self,
817-
fun_type: CallableType, defn: Context) -> List[TypeVarDef]:
817+
def bind_function_type_variables(
818+
self, fun_type: CallableType, defn: Context
819+
) -> Sequence[TypeVarLikeDef]:
818820
"""Find the type variables of the function type and bind them in our tvar_scope"""
819821
if fun_type.variables:
820822
for var in fun_type.variables:
@@ -828,7 +830,7 @@ def bind_function_type_variables(self,
828830
# Do not define a new type variable if already defined in scope.
829831
typevars = [(name, tvar) for name, tvar in typevars
830832
if not self.is_defined_type_var(name, defn)]
831-
defs = [] # type: List[TypeVarDef]
833+
defs = [] # type: List[TypeVarLikeDef]
832834
for name, tvar in typevars:
833835
if not self.tvar_scope.allow_binding(tvar.fullname):
834836
self.fail("Type variable '{}' is bound by an outer class".format(name), defn)
@@ -860,17 +862,22 @@ def anal_type(self, t: Type, nested: bool = True) -> Type:
860862
if nested:
861863
self.nesting_level -= 1
862864

863-
def anal_var_defs(self, var_defs: List[TypeVarDef]) -> List[TypeVarDef]:
864-
a = [] # type: List[TypeVarDef]
865-
for vd in var_defs:
866-
a.append(TypeVarDef(vd.name,
867-
vd.fullname,
868-
vd.id.raw_id,
869-
self.anal_array(vd.values),
870-
vd.upper_bound.accept(self),
871-
vd.variance,
872-
vd.line))
873-
return a
865+
def anal_var_def(self, var_def: TypeVarLikeDef) -> TypeVarLikeDef:
866+
if isinstance(var_def, TypeVarDef):
867+
return TypeVarDef(
868+
var_def.name,
869+
var_def.fullname,
870+
var_def.id.raw_id,
871+
self.anal_array(var_def.values),
872+
var_def.upper_bound.accept(self),
873+
var_def.variance,
874+
var_def.line
875+
)
876+
else:
877+
return var_def
878+
879+
def anal_var_defs(self, var_defs: Sequence[TypeVarLikeDef]) -> List[TypeVarLikeDef]:
880+
return [self.anal_var_def(vd) for vd in var_defs]
874881

875882
def named_type_with_normalized_str(self, fully_qualified_name: str) -> Instance:
876883
"""Does almost the same thing as `named_type`, except that we immediately

0 commit comments

Comments
 (0)