Skip to content

Commit

Permalink
Propagate TypeVarType column in TypeAnalyser (#15304)
Browse files Browse the repository at this point in the history
Also use keyword arguments + copy_modified for this in many places
  • Loading branch information
hauntsaninja authored May 25, 2023
1 parent cbf1665 commit f66199f
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 67 deletions.
12 changes: 6 additions & 6 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -4189,7 +4189,7 @@ def check_lst_expr(self, e: ListExpr | SetExpr | TupleExpr, fullname: str, tag:
# 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. :-)
tv = TypeVarType("T", "T", -1, [], self.object_type())
tv = TypeVarType("T", "T", id=-1, values=[], upper_bound=self.object_type())
constructor = CallableType(
[tv],
[nodes.ARG_STAR],
Expand Down Expand Up @@ -4357,8 +4357,8 @@ def visit_dict_expr(self, e: DictExpr) -> Type:
return dt

# Define type variables (used in constructors below).
kt = TypeVarType("KT", "KT", -1, [], self.object_type())
vt = TypeVarType("VT", "VT", -2, [], self.object_type())
kt = TypeVarType("KT", "KT", id=-1, values=[], upper_bound=self.object_type())
vt = TypeVarType("VT", "VT", id=-2, values=[], upper_bound=self.object_type())

# Collect function arguments, watching out for **expr.
args: list[Expression] = []
Expand Down Expand Up @@ -4722,7 +4722,7 @@ def check_generator_or_comprehension(

# Infer the type of the list comprehension by using a synthetic generic
# callable type.
tv = TypeVarType("T", "T", -1, [], self.object_type())
tv = TypeVarType("T", "T", id=-1, values=[], upper_bound=self.object_type())
tv_list: list[Type] = [tv]
constructor = CallableType(
tv_list,
Expand All @@ -4742,8 +4742,8 @@ def visit_dictionary_comprehension(self, e: DictionaryComprehension) -> Type:

# Infer the type of the list comprehension by using a synthetic generic
# callable type.
ktdef = TypeVarType("KT", "KT", -1, [], self.object_type())
vtdef = TypeVarType("VT", "VT", -2, [], self.object_type())
ktdef = TypeVarType("KT", "KT", id=-1, values=[], upper_bound=self.object_type())
vtdef = TypeVarType("VT", "VT", id=-2, values=[], upper_bound=self.object_type())
constructor = CallableType(
[ktdef, vtdef],
[nodes.ARG_POS, nodes.ARG_POS],
Expand Down
10 changes: 1 addition & 9 deletions mypy/copytype.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,7 @@ def visit_instance(self, t: Instance) -> ProperType:
return self.copy_common(t, dup)

def visit_type_var(self, t: TypeVarType) -> ProperType:
dup = TypeVarType(
t.name,
t.fullname,
t.id,
values=t.values,
upper_bound=t.upper_bound,
variance=t.variance,
)
return self.copy_common(t, dup)
return self.copy_common(t, t.copy_modified())

def visit_param_spec(self, t: ParamSpecType) -> ProperType:
dup = ParamSpecType(t.name, t.fullname, t.id, t.flavor, t.upper_bound, prefix=t.prefix)
Expand Down
6 changes: 5 additions & 1 deletion mypy/plugins/attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,11 @@ def _add_order(ctx: mypy.plugin.ClassDefContext, adder: MethodAdder) -> None:
# def __lt__(self: AT, other: AT) -> bool
# This way comparisons with subclasses will work correctly.
tvd = TypeVarType(
SELF_TVAR_NAME, ctx.cls.info.fullname + "." + SELF_TVAR_NAME, -1, [], object_type
SELF_TVAR_NAME,
ctx.cls.info.fullname + "." + SELF_TVAR_NAME,
id=-1,
values=[],
upper_bound=object_type,
)
self_tvar_expr = TypeVarExpr(
SELF_TVAR_NAME, ctx.cls.info.fullname + "." + SELF_TVAR_NAME, [], object_type
Expand Down
6 changes: 5 additions & 1 deletion mypy/plugins/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,11 @@ def transform(self) -> bool:
# the self type.
obj_type = self._api.named_type("builtins.object")
order_tvar_def = TypeVarType(
SELF_TVAR_NAME, info.fullname + "." + SELF_TVAR_NAME, -1, [], obj_type
SELF_TVAR_NAME,
info.fullname + "." + SELF_TVAR_NAME,
id=-1,
values=[],
upper_bound=obj_type,
)
order_return_type = self._api.named_type("builtins.bool")
order_args = [
Expand Down
4 changes: 3 additions & 1 deletion mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,9 @@ def setup_self_type(self) -> None:
)
else:
return
info.self_type = TypeVarType("Self", f"{info.fullname}.Self", 0, [], fill_typevars(info))
info.self_type = TypeVarType(
"Self", f"{info.fullname}.Self", id=0, values=[], upper_bound=fill_typevars(info)
)

def visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
self.statement = defn
Expand Down
10 changes: 5 additions & 5 deletions mypy/semanal_namedtuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,11 +544,11 @@ def add_field(

assert info.tuple_type is not None # Set by update_tuple_type() above.
tvd = TypeVarType(
SELF_TVAR_NAME,
info.fullname + "." + SELF_TVAR_NAME,
self.api.tvar_scope.new_unique_func_id(),
[],
info.tuple_type,
name=SELF_TVAR_NAME,
fullname=info.fullname + "." + SELF_TVAR_NAME,
id=self.api.tvar_scope.new_unique_func_id(),
values=[],
upper_bound=info.tuple_type,
)
selftype = tvd

Expand Down
6 changes: 3 additions & 3 deletions mypy/tvar_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ def bind_new(self, name: str, tvar_expr: TypeVarLikeExpr) -> TypeVarLikeType:
namespace = ""
if isinstance(tvar_expr, TypeVarExpr):
tvar_def: TypeVarLikeType = TypeVarType(
name,
tvar_expr.fullname,
TypeVarId(i, namespace=namespace),
name=name,
fullname=tvar_expr.fullname,
id=TypeVarId(i, namespace=namespace),
values=tvar_expr.values,
upper_bound=tvar_expr.upper_bound,
variance=tvar_expr.variance,
Expand Down
26 changes: 9 additions & 17 deletions mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,16 +343,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
f'Type variable "{t.name}" used with arguments', t, code=codes.VALID_TYPE
)
# Change the line number
return TypeVarType(
tvar_def.name,
tvar_def.fullname,
tvar_def.id,
tvar_def.values,
tvar_def.upper_bound,
tvar_def.variance,
line=t.line,
column=t.column,
)
return tvar_def.copy_modified(line=t.line, column=t.column)
if isinstance(sym.node, TypeVarTupleExpr) and (
tvar_def is not None
and self.defining_alias
Expand Down Expand Up @@ -1553,13 +1544,14 @@ def anal_type(self, t: Type, nested: bool = True, *, allow_param_spec: bool = Fa
def anal_var_def(self, var_def: TypeVarLikeType) -> TypeVarLikeType:
if isinstance(var_def, TypeVarType):
return TypeVarType(
var_def.name,
var_def.fullname,
var_def.id.raw_id,
self.anal_array(var_def.values),
var_def.upper_bound.accept(self),
var_def.variance,
var_def.line,
name=var_def.name,
fullname=var_def.fullname,
id=var_def.id.raw_id,
values=self.anal_array(var_def.values),
upper_bound=var_def.upper_bound.accept(self),
variance=var_def.variance,
line=var_def.line,
column=var_def.column,
)
else:
return var_def
Expand Down
28 changes: 14 additions & 14 deletions mypy/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,14 +596,14 @@ def copy_modified(
column: int = _dummy_int,
) -> TypeVarType:
return TypeVarType(
self.name,
self.fullname,
self.id if id is _dummy else id,
self.values if values is _dummy else values,
self.upper_bound if upper_bound is _dummy else upper_bound,
self.variance,
self.line if line == _dummy_int else line,
self.column if column == _dummy_int else column,
name=self.name,
fullname=self.fullname,
id=self.id if id is _dummy else id,
values=self.values if values is _dummy else values,
upper_bound=self.upper_bound if upper_bound is _dummy else upper_bound,
variance=self.variance,
line=self.line if line == _dummy_int else line,
column=self.column if column == _dummy_int else column,
)

def accept(self, visitor: TypeVisitor[T]) -> T:
Expand Down Expand Up @@ -638,12 +638,12 @@ def serialize(self) -> JsonDict:
def deserialize(cls, data: JsonDict) -> TypeVarType:
assert data[".class"] == "TypeVarType"
return TypeVarType(
data["name"],
data["fullname"],
TypeVarId(data["id"], namespace=data["namespace"]),
[deserialize_type(v) for v in data["values"]],
deserialize_type(data["upper_bound"]),
data["variance"],
name=data["name"],
fullname=data["fullname"],
id=TypeVarId(data["id"], namespace=data["namespace"]),
values=[deserialize_type(v) for v in data["values"]],
upper_bound=deserialize_type(data["upper_bound"]),
variance=data["variance"],
)


Expand Down
11 changes: 1 addition & 10 deletions mypy/typevars.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,7 @@ def fill_typevars(typ: TypeInfo) -> Instance | TupleType:
tv: TypeVarLikeType | UnpackType = typ.defn.type_vars[i]
# Change the line number
if isinstance(tv, TypeVarType):
tv = TypeVarType(
tv.name,
tv.fullname,
tv.id,
tv.values,
tv.upper_bound,
tv.variance,
line=-1,
column=-1,
)
tv = tv.copy_modified(line=-1, column=-1)
elif isinstance(tv, TypeVarTupleType):
tv = UnpackType(
TypeVarTupleType(
Expand Down

0 comments on commit f66199f

Please sign in to comment.