Skip to content

Commit 2736edb

Browse files
authored
Merge TypeVarDef and TypeVarType (#9951)
In the spirit of #4814 (comment) I'm not sure what the distinction between TypeVarDef and TypeVarType was (note that there's also TypeVarExpr, whose purpose is clear to me). In practice, it seems it boiled down to: a) TypeVarDef has a different __repr__, that's not user facing but was used in tests, b) in two places, we used the construction of a TypeVarType from a TypeVarDef as an opportunity to change the line number. I ran into this because: a) I was considering whether to create a corresponding ParamSpecDef and ParamSpecType b) I was trying to fix an issue with applytype sometimes swallowing generics, which to fix I needed TypeVarType to have access to its TypeVarDef. I was unable to find a reason for TypeVarType to not just be the TypeVarDef and here we are. Co-authored-by: hauntsaninja <>
1 parent 3e5b9b1 commit 2736edb

27 files changed

+216
-269
lines changed

mypy/applytype.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@
55
from mypy.expandtype import expand_type
66
from mypy.types import (
77
Type, TypeVarId, TypeVarType, CallableType, AnyType, PartialType, get_proper_types,
8-
TypeVarDef, TypeVarLikeDef, ProperType, ParamSpecDef
8+
TypeVarLikeType, ProperType, ParamSpecType
99
)
1010
from mypy.nodes import Context
1111

1212

1313
def get_target_type(
14-
tvar: TypeVarLikeDef,
14+
tvar: TypeVarLikeType,
1515
type: ProperType,
1616
callable: CallableType,
1717
report_incompatible_typevar_value: Callable[[CallableType, Type, str, Context], None],
1818
context: Context,
1919
skip_unsatisfied: bool
2020
) -> Optional[Type]:
21-
# TODO(shantanu): fix for ParamSpecDef
22-
if isinstance(tvar, ParamSpecDef):
21+
# TODO(shantanu): fix for ParamSpecType
22+
if isinstance(tvar, ParamSpecType):
2323
return None
24-
assert isinstance(tvar, TypeVarDef)
24+
assert isinstance(tvar, TypeVarType)
2525
values = get_proper_types(tvar.values)
2626
if values:
2727
if isinstance(type, AnyType):

mypy/checker.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from mypy.types import (
3434
Type, AnyType, CallableType, FunctionLike, Overloaded, TupleType, TypedDictType,
3535
Instance, NoneType, strip_type, TypeType, TypeOfAny,
36-
UnionType, TypeVarId, TypeVarType, PartialType, DeletedType, UninhabitedType, TypeVarDef,
36+
UnionType, TypeVarId, TypeVarType, PartialType, DeletedType, UninhabitedType,
3737
is_named_instance, union_items, TypeQuery, LiteralType,
3838
is_optional, remove_optional, TypeTranslator, StarType, get_proper_type, ProperType,
3939
get_proper_types, is_literal_type, TypeAliasType, TypeGuardType)
@@ -1403,7 +1403,7 @@ def expand_typevars(self, defn: FuncItem,
14031403
tvars += defn.info.defn.type_vars or []
14041404
# TODO(shantanu): audit for paramspec
14051405
for tvar in tvars:
1406-
if isinstance(tvar, TypeVarDef) and tvar.values:
1406+
if isinstance(tvar, TypeVarType) and tvar.values:
14071407
subst.append([(tvar.id, value) for value in tvar.values])
14081408
# Make a copy of the function to check for each combination of
14091409
# value restricted type variables. (Except when running mypyc,
@@ -5504,7 +5504,7 @@ def detach_callable(typ: CallableType) -> CallableType:
55045504
for var in set(all_type_vars):
55055505
if var.fullname not in used_type_var_names:
55065506
continue
5507-
new_variables.append(TypeVarDef(
5507+
new_variables.append(TypeVarType(
55085508
name=var.name,
55095509
fullname=var.fullname,
55105510
id=var.id,

mypy/checkexpr.py

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
make_optional_type,
1616
)
1717
from mypy.types import (
18-
Type, AnyType, CallableType, Overloaded, NoneType, TypeGuardType, TypeVarDef,
19-
TupleType, TypedDictType, Instance, TypeVarType, ErasedType, UnionType,
18+
Type, AnyType, CallableType, Overloaded, NoneType, TypeVarType, TypeGuardType,
19+
TupleType, TypedDictType, Instance, ErasedType, UnionType,
2020
PartialType, DeletedType, UninhabitedType, TypeType, TypeOfAny, LiteralType, LiteralValue,
21-
is_named_instance, FunctionLike, ParamSpecDef,
21+
is_named_instance, FunctionLike, ParamSpecType,
2222
StarType, is_optional, remove_optional, is_generic_instance, get_proper_type, ProperType,
2323
get_proper_types, flatten_nested_unions
2424
)
@@ -1904,8 +1904,8 @@ def combine_function_signatures(self, types: Sequence[Type]) -> Union[AnyType, C
19041904
# same thing.
19051905
#
19061906
# This function will make sure that all instances of that TypeVar 'T'
1907-
# refer to the same underlying TypeVarType and TypeVarDef objects to
1908-
# simplify the union-ing logic below.
1907+
# refer to the same underlying TypeVarType objects to simplify the union-ing
1908+
# logic below.
19091909
#
19101910
# (If the user did *not* mean for 'T' to be consistently bound to the
19111911
# same type in their overloads, well, their code is probably too
@@ -3277,16 +3277,15 @@ def check_lst_expr(self, items: List[Expression], fullname: str,
32773277
# Used for list and set expressions, as well as for tuples
32783278
# containing star expressions that don't refer to a
32793279
# Tuple. (Note: "lst" stands for list-set-tuple. :-)
3280-
tvdef = TypeVarDef('T', 'T', -1, [], self.object_type())
3281-
tv = TypeVarType(tvdef)
3280+
tv = TypeVarType('T', 'T', -1, [], self.object_type())
32823281
constructor = CallableType(
32833282
[tv],
32843283
[nodes.ARG_STAR],
32853284
[None],
32863285
self.chk.named_generic_type(fullname, [tv]),
32873286
self.named_type('builtins.function'),
32883287
name=tag,
3289-
variables=[tvdef])
3288+
variables=[tv])
32903289
out = self.check_call(constructor,
32913290
[(i.expr if isinstance(i, StarExpr) else i)
32923291
for i in items],
@@ -3435,10 +3434,8 @@ def visit_dict_expr(self, e: DictExpr) -> Type:
34353434
tup.column = value.column
34363435
args.append(tup)
34373436
# Define type variables (used in constructors below).
3438-
ktdef = TypeVarDef('KT', 'KT', -1, [], self.object_type())
3439-
vtdef = TypeVarDef('VT', 'VT', -2, [], self.object_type())
3440-
kt = TypeVarType(ktdef)
3441-
vt = TypeVarType(vtdef)
3437+
kt = TypeVarType('KT', 'KT', -1, [], self.object_type())
3438+
vt = TypeVarType('VT', 'VT', -2, [], self.object_type())
34423439
rv = None
34433440
# Call dict(*args), unless it's empty and stargs is not.
34443441
if args or not stargs:
@@ -3452,7 +3449,7 @@ def visit_dict_expr(self, e: DictExpr) -> Type:
34523449
self.chk.named_generic_type('builtins.dict', [kt, vt]),
34533450
self.named_type('builtins.function'),
34543451
name='<dict>',
3455-
variables=[ktdef, vtdef])
3452+
variables=[kt, vt])
34563453
rv = self.check_call(constructor, args, [nodes.ARG_POS] * len(args), e)[0]
34573454
else:
34583455
# dict(...) will be called below.
@@ -3469,7 +3466,7 @@ def visit_dict_expr(self, e: DictExpr) -> Type:
34693466
self.chk.named_generic_type('builtins.dict', [kt, vt]),
34703467
self.named_type('builtins.function'),
34713468
name='<list>',
3472-
variables=[ktdef, vtdef])
3469+
variables=[kt, vt])
34733470
rv = self.check_call(constructor, [arg], [nodes.ARG_POS], arg)[0]
34743471
else:
34753472
self.check_method_call_by_name('update', rv, [arg], [nodes.ARG_POS], arg)
@@ -3759,16 +3756,16 @@ def check_generator_or_comprehension(self, gen: GeneratorExpr,
37593756

37603757
# Infer the type of the list comprehension by using a synthetic generic
37613758
# callable type.
3762-
tvdef = TypeVarDef('T', 'T', -1, [], self.object_type())
3763-
tv_list: List[Type] = [TypeVarType(tvdef)]
3759+
tv = TypeVarType('T', 'T', -1, [], self.object_type())
3760+
tv_list: List[Type] = [tv]
37643761
constructor = CallableType(
37653762
tv_list,
37663763
[nodes.ARG_POS],
37673764
[None],
37683765
self.chk.named_generic_type(type_name, tv_list + additional_args),
37693766
self.chk.named_type('builtins.function'),
37703767
name=id_for_messages,
3771-
variables=[tvdef])
3768+
variables=[tv])
37723769
return self.check_call(constructor,
37733770
[gen.left_expr], [nodes.ARG_POS], gen)[0]
37743771

@@ -3779,15 +3776,13 @@ def visit_dictionary_comprehension(self, e: DictionaryComprehension) -> Type:
37793776

37803777
# Infer the type of the list comprehension by using a synthetic generic
37813778
# callable type.
3782-
ktdef = TypeVarDef('KT', 'KT', -1, [], self.object_type())
3783-
vtdef = TypeVarDef('VT', 'VT', -2, [], self.object_type())
3784-
kt = TypeVarType(ktdef)
3785-
vt = TypeVarType(vtdef)
3779+
ktdef = TypeVarType('KT', 'KT', -1, [], self.object_type())
3780+
vtdef = TypeVarType('VT', 'VT', -2, [], self.object_type())
37863781
constructor = CallableType(
3787-
[kt, vt],
3782+
[ktdef, vtdef],
37883783
[nodes.ARG_POS, nodes.ARG_POS],
37893784
[None, None],
3790-
self.chk.named_generic_type('builtins.dict', [kt, vt]),
3785+
self.chk.named_generic_type('builtins.dict', [ktdef, vtdef]),
37913786
self.chk.named_type('builtins.function'),
37923787
name='<dictionary-comprehension>',
37933788
variables=[ktdef, vtdef])
@@ -4450,7 +4445,7 @@ def all_same_types(types: List[Type]) -> bool:
44504445

44514446

44524447
def merge_typevars_in_callables_by_name(
4453-
callables: Sequence[CallableType]) -> Tuple[List[CallableType], List[TypeVarDef]]:
4448+
callables: Sequence[CallableType]) -> Tuple[List[CallableType], List[TypeVarType]]:
44544449
"""Takes all the typevars present in the callables and 'combines' the ones with the same name.
44554450
44564451
For example, suppose we have two callables with signatures "f(x: T, y: S) -> T" and
@@ -4459,34 +4454,33 @@ def merge_typevars_in_callables_by_name(
44594454
distinct ids.)
44604455
44614456
If we pass in both callables into this function, it returns a a list containing two
4462-
new callables that are identical in signature, but use the same underlying TypeVarDef
4463-
and TypeVarType objects for T and S.
4457+
new callables that are identical in signature, but use the same underlying TypeVarType
4458+
for T and S.
44644459
44654460
This is useful if we want to take the output lists and "merge" them into one callable
44664461
in some way -- for example, when unioning together overloads.
44674462
4468-
Returns both the new list of callables and a list of all distinct TypeVarDef objects used.
4463+
Returns both the new list of callables and a list of all distinct TypeVarType objects used.
44694464
"""
4470-
44714465
output: List[CallableType] = []
44724466
unique_typevars: Dict[str, TypeVarType] = {}
4473-
variables: List[TypeVarDef] = []
4467+
variables: List[TypeVarType] = []
44744468

44754469
for target in callables:
44764470
if target.is_generic():
44774471
target = freshen_function_type_vars(target)
44784472

44794473
rename = {} # Dict[TypeVarId, TypeVar]
4480-
for tvdef in target.variables:
4481-
name = tvdef.fullname
4474+
for tv in target.variables:
4475+
name = tv.fullname
44824476
if name not in unique_typevars:
4483-
# TODO(shantanu): fix for ParamSpecDef
4484-
if isinstance(tvdef, ParamSpecDef):
4477+
# TODO(shantanu): fix for ParamSpecType
4478+
if isinstance(tv, ParamSpecType):
44854479
continue
4486-
assert isinstance(tvdef, TypeVarDef)
4487-
unique_typevars[name] = TypeVarType(tvdef)
4488-
variables.append(tvdef)
4489-
rename[tvdef.id] = unique_typevars[name]
4480+
assert isinstance(tv, TypeVarType)
4481+
unique_typevars[name] = tv
4482+
variables.append(tv)
4483+
rename[tv.id] = unique_typevars[name]
44904484

44914485
target = cast(CallableType, expand_type(target, rename))
44924486
output.append(target)

mypy/checkmember.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from mypy.types import (
77
Type, Instance, AnyType, TupleType, TypedDictType, CallableType, FunctionLike,
8-
TypeVarLikeDef, Overloaded, TypeVarType, UnionType, PartialType, TypeOfAny, LiteralType,
8+
TypeVarLikeType, Overloaded, TypeVarType, UnionType, PartialType, TypeOfAny, LiteralType,
99
DeletedType, NoneType, TypeType, has_type_vars, get_proper_type, ProperType
1010
)
1111
from mypy.nodes import (
@@ -695,7 +695,7 @@ def analyze_class_attribute_access(itype: Instance,
695695
name: str,
696696
mx: MemberContext,
697697
override_info: Optional[TypeInfo] = None,
698-
original_vars: Optional[Sequence[TypeVarLikeDef]] = None
698+
original_vars: Optional[Sequence[TypeVarLikeType]] = None
699699
) -> Optional[Type]:
700700
"""Analyze access to an attribute on a class object.
701701
@@ -858,7 +858,7 @@ def analyze_enum_class_attribute_access(itype: Instance,
858858
def add_class_tvars(t: ProperType, isuper: Optional[Instance],
859859
is_classmethod: bool,
860860
original_type: Type,
861-
original_vars: Optional[Sequence[TypeVarLikeDef]] = None) -> Type:
861+
original_vars: Optional[Sequence[TypeVarLikeType]] = None) -> Type:
862862
"""Instantiate type variables during analyze_class_attribute_access,
863863
e.g T and Q in the following:
864864

mypy/expandtype.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
Type, Instance, CallableType, TypeGuardType, TypeVisitor, UnboundType, AnyType,
55
NoneType, TypeVarType, Overloaded, TupleType, TypedDictType, UnionType,
66
ErasedType, PartialType, DeletedType, UninhabitedType, TypeType, TypeVarId,
7-
FunctionLike, TypeVarDef, LiteralType, get_proper_type, ProperType,
8-
TypeAliasType, ParamSpecDef
7+
FunctionLike, TypeVarType, LiteralType, get_proper_type, ProperType,
8+
TypeAliasType, ParamSpecType
99
)
1010

1111

@@ -38,17 +38,17 @@ def freshen_function_type_vars(callee: F) -> F:
3838
if isinstance(callee, CallableType):
3939
if not callee.is_generic():
4040
return cast(F, callee)
41-
tvdefs = []
41+
tvs = []
4242
tvmap: Dict[TypeVarId, Type] = {}
4343
for v in callee.variables:
44-
# TODO(shantanu): fix for ParamSpecDef
45-
if isinstance(v, ParamSpecDef):
44+
# TODO(shantanu): fix for ParamSpecType
45+
if isinstance(v, ParamSpecType):
4646
continue
47-
assert isinstance(v, TypeVarDef)
48-
tvdef = TypeVarDef.new_unification_variable(v)
49-
tvdefs.append(tvdef)
50-
tvmap[v.id] = TypeVarType(tvdef)
51-
fresh = cast(CallableType, expand_type(callee, tvmap)).copy_modified(variables=tvdefs)
47+
assert isinstance(v, TypeVarType)
48+
tv = TypeVarType.new_unification_variable(v)
49+
tvs.append(tv)
50+
tvmap[v.id] = tv
51+
fresh = cast(CallableType, expand_type(callee, tvmap)).copy_modified(variables=tvs)
5252
return cast(F, fresh)
5353
else:
5454
assert isinstance(callee, Overloaded)

mypy/fixup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from mypy.types import (
1212
CallableType, Instance, Overloaded, TupleType, TypeGuardType, TypedDictType,
1313
TypeVarType, UnboundType, UnionType, TypeVisitor, LiteralType,
14-
TypeType, NOT_READY, TypeAliasType, AnyType, TypeOfAny, TypeVarDef
14+
TypeType, NOT_READY, TypeAliasType, AnyType, TypeOfAny
1515
)
1616
from mypy.visitor import NodeVisitor
1717
from mypy.lookup import lookup_fully_qualified
@@ -184,7 +184,7 @@ def visit_callable_type(self, ct: CallableType) -> None:
184184
if ct.ret_type is not None:
185185
ct.ret_type.accept(self)
186186
for v in ct.variables:
187-
if isinstance(v, TypeVarDef):
187+
if isinstance(v, TypeVarType):
188188
if v.values:
189189
for val in v.values:
190190
val.accept(self)

mypy/messages.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from mypy.errors import Errors
2323
from mypy.types import (
2424
Type, CallableType, Instance, TypeVarType, TupleType, TypedDictType, LiteralType,
25-
UnionType, NoneType, AnyType, Overloaded, FunctionLike, DeletedType, TypeType, TypeVarDef,
25+
UnionType, NoneType, AnyType, Overloaded, FunctionLike, DeletedType, TypeType, TypeVarType,
2626
UninhabitedType, TypeOfAny, UnboundType, PartialType, get_proper_type, ProperType,
2727
get_proper_types
2828
)
@@ -1971,7 +1971,7 @@ def [T <: int] f(self, x: int, y: T) -> None
19711971
if tp.variables:
19721972
tvars = []
19731973
for tvar in tp.variables:
1974-
if isinstance(tvar, TypeVarDef):
1974+
if isinstance(tvar, TypeVarType):
19751975
upper_bound = get_proper_type(tvar.upper_bound)
19761976
if (isinstance(upper_bound, Instance) and
19771977
upper_bound.type.fullname != 'builtins.object'):
@@ -1983,7 +1983,7 @@ def [T <: int] f(self, x: int, y: T) -> None
19831983
else:
19841984
tvars.append(tvar.name)
19851985
else:
1986-
# For other TypeVarLikeDefs, just use the repr
1986+
# For other TypeVarLikeTypes, just use the repr
19871987
tvars.append(repr(tvar))
19881988
s = '[{}] {}'.format(', '.join(tvars), s)
19891989
return 'def {}'.format(s)

mypy/nodes.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -921,11 +921,10 @@ def deserialize(cls, data: JsonDict) -> 'Var':
921921

922922
class ClassDef(Statement):
923923
"""Class definition"""
924-
925924
name: str # Name of the class without module prefix
926925
fullname: Bogus[str] = None # type: ignore # Fully qualified name of the class
927926
defs: "Block"
928-
type_vars: List["mypy.types.TypeVarDef"]
927+
type_vars: List["mypy.types.TypeVarType"]
929928
# Base class expressions (not semantically analyzed -- can be arbitrary expressions)
930929
base_type_exprs: List[Expression]
931930
# Special base classes like Generic[...] get moved here during semantic analysis
@@ -940,7 +939,7 @@ class ClassDef(Statement):
940939
def __init__(self,
941940
name: str,
942941
defs: 'Block',
943-
type_vars: Optional[List['mypy.types.TypeVarDef']] = None,
942+
type_vars: Optional[List['mypy.types.TypeVarType']] = None,
944943
base_type_exprs: Optional[List[Expression]] = None,
945944
metaclass: Optional[Expression] = None,
946945
keywords: Optional[List[Tuple[str, Expression]]] = None) -> None:
@@ -975,7 +974,7 @@ def deserialize(self, data: JsonDict) -> 'ClassDef':
975974
assert data['.class'] == 'ClassDef'
976975
res = ClassDef(data['name'],
977976
Block([]),
978-
[mypy.types.TypeVarDef.deserialize(v) for v in data['type_vars']],
977+
[mypy.types.TypeVarType.deserialize(v) for v in data['type_vars']],
979978
)
980979
res.fullname = data['fullname']
981980
return res

0 commit comments

Comments
 (0)