Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge TypeVarDef and TypeVarType #9951

Merged
merged 13 commits into from
Aug 4, 2021
Merged
8 changes: 4 additions & 4 deletions mypy/applytype.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
from mypy.expandtype import expand_type
from mypy.types import (
Type, TypeVarId, TypeVarType, CallableType, AnyType, PartialType, get_proper_types,
TypeVarDef, TypeVarLikeDef, ProperType
TypeVarLikeType, ProperType
)
from mypy.nodes import Context


def get_target_type(
tvar: TypeVarLikeDef,
tvar: TypeVarLikeType,
type: ProperType,
callable: CallableType,
report_incompatible_typevar_value: Callable[[CallableType, Type, str, Context], None],
context: Context,
skip_unsatisfied: bool
) -> Optional[Type]:
# TODO(shantanu): fix for ParamSpecDef
assert isinstance(tvar, TypeVarDef)
# TODO(shantanu): fix for ParamSpecType
assert isinstance(tvar, TypeVarType)
values = get_proper_types(tvar.values)
if values:
if isinstance(type, AnyType):
Expand Down
6 changes: 3 additions & 3 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from mypy.types import (
Type, AnyType, CallableType, FunctionLike, Overloaded, TupleType, TypedDictType,
Instance, NoneType, strip_type, TypeType, TypeOfAny,
UnionType, TypeVarId, TypeVarType, PartialType, DeletedType, UninhabitedType, TypeVarDef,
UnionType, TypeVarId, TypeVarType, PartialType, DeletedType, UninhabitedType,
is_named_instance, union_items, TypeQuery, LiteralType,
is_optional, remove_optional, TypeTranslator, StarType, get_proper_type, ProperType,
get_proper_types, is_literal_type, TypeAliasType, TypeGuardType)
Expand Down Expand Up @@ -1396,7 +1396,7 @@ def expand_typevars(self, defn: FuncItem,
tvars += defn.info.defn.type_vars or []
# TODO(shantanu): audit for paramspec
for tvar in tvars:
if isinstance(tvar, TypeVarDef) and tvar.values:
if isinstance(tvar, TypeVarType) and tvar.values:
subst.append([(tvar.id, value) for value in tvar.values])
# Make a copy of the function to check for each combination of
# value restricted type variables. (Except when running mypyc,
Expand Down Expand Up @@ -5497,7 +5497,7 @@ def detach_callable(typ: CallableType) -> CallableType:
for var in set(all_type_vars):
if var.fullname not in used_type_var_names:
continue
new_variables.append(TypeVarDef(
new_variables.append(TypeVarType(
name=var.name,
fullname=var.fullname,
id=var.id,
Expand Down
60 changes: 27 additions & 33 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
make_optional_type,
)
from mypy.types import (
Type, AnyType, CallableType, Overloaded, NoneType, TypeGuardType, TypeVarDef,
TupleType, TypedDictType, Instance, TypeVarType, ErasedType, UnionType,
Type, AnyType, CallableType, Overloaded, NoneType, TypeVarType, TypeGuardType,
TupleType, TypedDictType, Instance, ErasedType, UnionType,
PartialType, DeletedType, UninhabitedType, TypeType, TypeOfAny, LiteralType, LiteralValue,
is_named_instance, FunctionLike,
StarType, is_optional, remove_optional, is_generic_instance, get_proper_type, ProperType,
Expand Down Expand Up @@ -1904,8 +1904,8 @@ def combine_function_signatures(self, types: Sequence[Type]) -> Union[AnyType, C
# same thing.
#
# This function will make sure that all instances of that TypeVar 'T'
# refer to the same underlying TypeVarType and TypeVarDef objects to
# simplify the union-ing logic below.
# refer to the same underlying TypeVarType objects to simplify the union-ing
# logic below.
#
# (If the user did *not* mean for 'T' to be consistently bound to the
# same type in their overloads, well, their code is probably too
Expand Down Expand Up @@ -3277,13 +3277,12 @@ def check_lst_expr(self, items: List[Expression], fullname: str,
# Used for list and set expressions, as well as for tuples
# containing star expressions that don't refer to a
# Tuple. (Note: "lst" stands for list-set-tuple. :-)
tvdef = TypeVarDef('T', 'T', -1, [], self.object_type())
tv = TypeVarType(tvdef)
tvdef = TypeVarType('T', 'T', -1, [], self.object_type())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe keep the tv names (and similar below) instead of the tvdef ones?

constructor = CallableType(
[tv],
[tvdef],
[nodes.ARG_STAR],
[None],
self.chk.named_generic_type(fullname, [tv]),
self.chk.named_generic_type(fullname, [tvdef]),
self.named_type('builtins.function'),
name=tag,
variables=[tvdef])
Expand Down Expand Up @@ -3435,21 +3434,19 @@ def visit_dict_expr(self, e: DictExpr) -> Type:
tup.column = value.column
args.append(tup)
# Define type variables (used in constructors below).
ktdef = TypeVarDef('KT', 'KT', -1, [], self.object_type())
vtdef = TypeVarDef('VT', 'VT', -2, [], self.object_type())
kt = TypeVarType(ktdef)
vt = TypeVarType(vtdef)
ktdef = TypeVarType('KT', 'KT', -1, [], self.object_type())
vtdef = TypeVarType('VT', 'VT', -2, [], self.object_type())
rv = None
# Call dict(*args), unless it's empty and stargs is not.
if args or not stargs:
# The callable type represents a function like this:
#
# def <unnamed>(*v: Tuple[kt, vt]) -> Dict[kt, vt]: ...
constructor = CallableType(
[TupleType([kt, vt], self.named_type('builtins.tuple'))],
[TupleType([ktdef, vtdef], self.named_type('builtins.tuple'))],
[nodes.ARG_STAR],
[None],
self.chk.named_generic_type('builtins.dict', [kt, vt]),
self.chk.named_generic_type('builtins.dict', [ktdef, vtdef]),
self.named_type('builtins.function'),
name='<dict>',
variables=[ktdef, vtdef])
Expand All @@ -3463,10 +3460,10 @@ def visit_dict_expr(self, e: DictExpr) -> Type:
for arg in stargs:
if rv is None:
constructor = CallableType(
[self.chk.named_generic_type('typing.Mapping', [kt, vt])],
[self.chk.named_generic_type('typing.Mapping', [ktdef, vtdef])],
[nodes.ARG_POS],
[None],
self.chk.named_generic_type('builtins.dict', [kt, vt]),
self.chk.named_generic_type('builtins.dict', [ktdef, vtdef]),
self.named_type('builtins.function'),
name='<list>',
variables=[ktdef, vtdef])
Expand Down Expand Up @@ -3759,8 +3756,8 @@ def check_generator_or_comprehension(self, gen: GeneratorExpr,

# Infer the type of the list comprehension by using a synthetic generic
# callable type.
tvdef = TypeVarDef('T', 'T', -1, [], self.object_type())
tv_list: List[Type] = [TypeVarType(tvdef)]
tvdef = TypeVarType('T', 'T', -1, [], self.object_type())
tv_list: List[Type] = [tvdef]
constructor = CallableType(
tv_list,
[nodes.ARG_POS],
Expand All @@ -3779,15 +3776,13 @@ def visit_dictionary_comprehension(self, e: DictionaryComprehension) -> Type:

# Infer the type of the list comprehension by using a synthetic generic
# callable type.
ktdef = TypeVarDef('KT', 'KT', -1, [], self.object_type())
vtdef = TypeVarDef('VT', 'VT', -2, [], self.object_type())
kt = TypeVarType(ktdef)
vt = TypeVarType(vtdef)
ktdef = TypeVarType('KT', 'KT', -1, [], self.object_type())
vtdef = TypeVarType('VT', 'VT', -2, [], self.object_type())
constructor = CallableType(
[kt, vt],
[ktdef, vtdef],
[nodes.ARG_POS, nodes.ARG_POS],
[None, None],
self.chk.named_generic_type('builtins.dict', [kt, vt]),
self.chk.named_generic_type('builtins.dict', [ktdef, vtdef]),
self.chk.named_type('builtins.function'),
name='<dictionary-comprehension>',
variables=[ktdef, vtdef])
Expand Down Expand Up @@ -4450,7 +4445,7 @@ def all_same_types(types: List[Type]) -> bool:


def merge_typevars_in_callables_by_name(
callables: Sequence[CallableType]) -> Tuple[List[CallableType], List[TypeVarDef]]:
callables: Sequence[CallableType]) -> Tuple[List[CallableType], List[TypeVarType]]:
"""Takes all the typevars present in the callables and 'combines' the ones with the same name.

For example, suppose we have two callables with signatures "f(x: T, y: S) -> T" and
Expand All @@ -4459,18 +4454,17 @@ def merge_typevars_in_callables_by_name(
distinct ids.)

If we pass in both callables into this function, it returns a a list containing two
new callables that are identical in signature, but use the same underlying TypeVarDef
and TypeVarType objects for T and S.
new callables that are identical in signature, but use the same underlying TypeVarType
for T and S.

This is useful if we want to take the output lists and "merge" them into one callable
in some way -- for example, when unioning together overloads.

Returns both the new list of callables and a list of all distinct TypeVarDef objects used.
Returns both the new list of callables and a list of all distinct TypeVarType objects used.
"""

output: List[CallableType] = []
unique_typevars: Dict[str, TypeVarType] = {}
variables: List[TypeVarDef] = []
variables: List[TypeVarType] = []

for target in callables:
if target.is_generic():
Expand All @@ -4480,9 +4474,9 @@ def merge_typevars_in_callables_by_name(
for tvdef in target.variables:
name = tvdef.fullname
if name not in unique_typevars:
# TODO(shantanu): fix for ParamSpecDef
assert isinstance(tvdef, TypeVarDef)
unique_typevars[name] = TypeVarType(tvdef)
# TODO(shantanu): fix for ParamSpecType
assert isinstance(tvdef, TypeVarType)
unique_typevars[name] = tvdef
variables.append(tvdef)
rename[tvdef.id] = unique_typevars[name]

Expand Down
6 changes: 3 additions & 3 deletions mypy/checkmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from mypy.types import (
Type, Instance, AnyType, TupleType, TypedDictType, CallableType, FunctionLike,
TypeVarLikeDef, Overloaded, TypeVarType, UnionType, PartialType, TypeOfAny, LiteralType,
TypeVarLikeType, Overloaded, TypeVarType, UnionType, PartialType, TypeOfAny, LiteralType,
DeletedType, NoneType, TypeType, has_type_vars, get_proper_type, ProperType
)
from mypy.nodes import (
Expand Down Expand Up @@ -695,7 +695,7 @@ def analyze_class_attribute_access(itype: Instance,
name: str,
mx: MemberContext,
override_info: Optional[TypeInfo] = None,
original_vars: Optional[Sequence[TypeVarLikeDef]] = None
original_vars: Optional[Sequence[TypeVarLikeType]] = None
) -> Optional[Type]:
"""Analyze access to an attribute on a class object.

Expand Down Expand Up @@ -858,7 +858,7 @@ def analyze_enum_class_attribute_access(itype: Instance,
def add_class_tvars(t: ProperType, isuper: Optional[Instance],
is_classmethod: bool,
original_type: Type,
original_vars: Optional[Sequence[TypeVarLikeDef]] = None) -> Type:
original_vars: Optional[Sequence[TypeVarLikeType]] = None) -> Type:
"""Instantiate type variables during analyze_class_attribute_access,
e.g T and Q in the following:

Expand Down
10 changes: 5 additions & 5 deletions mypy/expandtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Type, Instance, CallableType, TypeGuardType, TypeVisitor, UnboundType, AnyType,
NoneType, TypeVarType, Overloaded, TupleType, TypedDictType, UnionType,
ErasedType, PartialType, DeletedType, UninhabitedType, TypeType, TypeVarId,
FunctionLike, TypeVarDef, LiteralType, get_proper_type, ProperType,
FunctionLike, TypeVarType, LiteralType, get_proper_type, ProperType,
TypeAliasType)


Expand Down Expand Up @@ -40,11 +40,11 @@ def freshen_function_type_vars(callee: F) -> F:
tvdefs = []
tvmap: Dict[TypeVarId, Type] = {}
for v in callee.variables:
# TODO(shantanu): fix for ParamSpecDef
assert isinstance(v, TypeVarDef)
tvdef = TypeVarDef.new_unification_variable(v)
# TODO(shantanu): fix for ParamSpecType
assert isinstance(v, TypeVarType)
tvdef = TypeVarType.new_unification_variable(v)
tvdefs.append(tvdef)
tvmap[v.id] = TypeVarType(tvdef)
tvmap[v.id] = tvdef
fresh = cast(CallableType, expand_type(callee, tvmap)).copy_modified(variables=tvdefs)
return cast(F, fresh)
else:
Expand Down
4 changes: 2 additions & 2 deletions mypy/fixup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from mypy.types import (
CallableType, Instance, Overloaded, TupleType, TypeGuardType, TypedDictType,
TypeVarType, UnboundType, UnionType, TypeVisitor, LiteralType,
TypeType, NOT_READY, TypeAliasType, AnyType, TypeOfAny, TypeVarDef
TypeType, NOT_READY, TypeAliasType, AnyType, TypeOfAny
)
from mypy.visitor import NodeVisitor
from mypy.lookup import lookup_fully_qualified
Expand Down Expand Up @@ -184,7 +184,7 @@ def visit_callable_type(self, ct: CallableType) -> None:
if ct.ret_type is not None:
ct.ret_type.accept(self)
for v in ct.variables:
if isinstance(v, TypeVarDef):
if isinstance(v, TypeVarType):
if v.values:
for val in v.values:
val.accept(self)
Expand Down
6 changes: 3 additions & 3 deletions mypy/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from mypy.errors import Errors
from mypy.types import (
Type, CallableType, Instance, TypeVarType, TupleType, TypedDictType, LiteralType,
UnionType, NoneType, AnyType, Overloaded, FunctionLike, DeletedType, TypeType, TypeVarDef,
UnionType, NoneType, AnyType, Overloaded, FunctionLike, DeletedType, TypeType, TypeVarType,
UninhabitedType, TypeOfAny, UnboundType, PartialType, get_proper_type, ProperType,
get_proper_types
)
Expand Down Expand Up @@ -1971,7 +1971,7 @@ def [T <: int] f(self, x: int, y: T) -> None
if tp.variables:
tvars = []
for tvar in tp.variables:
if isinstance(tvar, TypeVarDef):
if isinstance(tvar, TypeVarType):
upper_bound = get_proper_type(tvar.upper_bound)
if (isinstance(upper_bound, Instance) and
upper_bound.type.fullname != 'builtins.object'):
Expand All @@ -1983,7 +1983,7 @@ def [T <: int] f(self, x: int, y: T) -> None
else:
tvars.append(tvar.name)
else:
# For other TypeVarLikeDefs, just use the repr
# For other TypeVarLikeTypes, just use the repr
tvars.append(repr(tvar))
s = '[{}] {}'.format(', '.join(tvars), s)
return 'def {}'.format(s)
Expand Down
7 changes: 3 additions & 4 deletions mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,11 +921,10 @@ def deserialize(cls, data: JsonDict) -> 'Var':

class ClassDef(Statement):
"""Class definition"""

name: str # Name of the class without module prefix
fullname: Bogus[str] = None # type: ignore # Fully qualified name of the class
defs: "Block"
type_vars: List["mypy.types.TypeVarDef"]
type_vars: List["mypy.types.TypeVarType"]
# Base class expressions (not semantically analyzed -- can be arbitrary expressions)
base_type_exprs: List[Expression]
# Special base classes like Generic[...] get moved here during semantic analysis
Expand All @@ -940,7 +939,7 @@ class ClassDef(Statement):
def __init__(self,
name: str,
defs: 'Block',
type_vars: Optional[List['mypy.types.TypeVarDef']] = None,
type_vars: Optional[List['mypy.types.TypeVarType']] = None,
base_type_exprs: Optional[List[Expression]] = None,
metaclass: Optional[Expression] = None,
keywords: Optional[List[Tuple[str, Expression]]] = None) -> None:
Expand Down Expand Up @@ -975,7 +974,7 @@ def deserialize(self, data: JsonDict) -> 'ClassDef':
assert data['.class'] == 'ClassDef'
res = ClassDef(data['name'],
Block([]),
[mypy.types.TypeVarDef.deserialize(v) for v in data['type_vars']],
[mypy.types.TypeVarType.deserialize(v) for v in data['type_vars']],
)
res.fullname = data['fullname']
return res
Expand Down
11 changes: 5 additions & 6 deletions mypy/plugins/attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
deserialize_and_fixup_type
)
from mypy.types import (
Type, AnyType, TypeOfAny, CallableType, NoneType, TypeVarDef, TypeVarType,
Type, AnyType, TypeOfAny, CallableType, NoneType, TypeVarType,
Overloaded, UnionType, FunctionLike, get_proper_type
)
from mypy.typeops import make_simplified_union, map_type_from_supertype
Expand Down Expand Up @@ -643,16 +643,15 @@ def _add_order(ctx: 'mypy.plugin.ClassDefContext', adder: 'MethodAdder') -> None
# AT = TypeVar('AT')
# def __lt__(self: AT, other: AT) -> bool
# This way comparisons with subclasses will work correctly.
tvd = TypeVarDef(SELF_TVAR_NAME, ctx.cls.info.fullname + '.' + SELF_TVAR_NAME,
tvd = TypeVarType(SELF_TVAR_NAME, ctx.cls.info.fullname + '.' + SELF_TVAR_NAME,
-1, [], object_type)
tvd_type = TypeVarType(tvd)
self_tvar_expr = TypeVarExpr(SELF_TVAR_NAME, ctx.cls.info.fullname + '.' + SELF_TVAR_NAME,
[], object_type)
ctx.cls.info.names[SELF_TVAR_NAME] = SymbolTableNode(MDEF, self_tvar_expr)

args = [Argument(Var('other', tvd_type), tvd_type, None, ARG_POS)]
args = [Argument(Var('other', tvd), tvd, None, ARG_POS)]
for method in ['__lt__', '__le__', '__gt__', '__ge__']:
adder.add_method(method, args, bool_type, self_type=tvd_type, tvd=tvd)
adder.add_method(method, args, bool_type, self_type=tvd, tvd=tvd)


def _make_frozen(ctx: 'mypy.plugin.ClassDefContext', attributes: List[Attribute]) -> None:
Expand Down Expand Up @@ -719,7 +718,7 @@ def __init__(self, ctx: 'mypy.plugin.ClassDefContext') -> None:
def add_method(self,
method_name: str, args: List[Argument], ret_type: Type,
self_type: Optional[Type] = None,
tvd: Optional[TypeVarDef] = None) -> None:
tvd: Optional[TypeVarType] = None) -> None:
"""Add a method: def <method_name>(self, <args>) -> <ret_type>): ... to info.

self_type: The type to use for the self argument or None to use the inferred self type.
Expand Down
6 changes: 3 additions & 3 deletions mypy/plugins/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from mypy.plugin import CheckerPluginInterface, ClassDefContext, SemanticAnalyzerPluginInterface
from mypy.semanal import set_callable_name
from mypy.types import (
CallableType, Overloaded, Type, TypeVarDef, deserialize_type, get_proper_type,
CallableType, Overloaded, Type, TypeVarType, deserialize_type, get_proper_type,
)
from mypy.typevars import fill_typevars
from mypy.util import get_unique_redefinition_name
Expand Down Expand Up @@ -88,7 +88,7 @@ def add_method(
args: List[Argument],
return_type: Type,
self_type: Optional[Type] = None,
tvar_def: Optional[TypeVarDef] = None,
tvar_def: Optional[TypeVarType] = None,
) -> None:
"""
Adds a new method to a class.
Expand All @@ -109,7 +109,7 @@ def add_method_to_class(
args: List[Argument],
return_type: Type,
self_type: Optional[Type] = None,
tvar_def: Optional[TypeVarDef] = None,
tvar_def: Optional[TypeVarType] = None,
) -> None:
"""Adds a new method to a class definition."""
info = cls.info
Expand Down
Loading