Skip to content

Commit ebcfaf3

Browse files
committed
Keep trivial instances and aliases during expansion
1 parent 0f78f9c commit ebcfaf3

File tree

3 files changed

+25
-32
lines changed

3 files changed

+25
-32
lines changed

mypy/expandtype.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,7 @@ def visit_erased_type(self, t: ErasedType) -> Type:
210210

211211
def visit_instance(self, t: Instance) -> Type:
212212
if len(t.args) == 0:
213-
# TODO: Why do we need to create a copy here?
214-
return t.copy_modified()
213+
return t
215214

216215
args = self.expand_type_tuple_with_unpack(t.args)
217216

@@ -525,6 +524,8 @@ def visit_type_type(self, t: TypeType) -> Type:
525524
def visit_type_alias_type(self, t: TypeAliasType) -> Type:
526525
# Target of the type alias cannot contain type variables (not bound by the type
527526
# alias itself), so we just expand the arguments.
527+
if len(t.args) == 0:
528+
return t
528529
args = self.expand_type_list_with_unpack(t.args)
529530
# TODO: normalize if target is Tuple, and args are [*tuple[X, ...]]?
530531
return t.copy_modified(args=args)

mypy/semanal.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,12 +1046,12 @@ def remove_unpack_kwargs(self, defn: FuncDef, typ: CallableType) -> CallableType
10461046
last_type = typ.arg_types[-1]
10471047
if not isinstance(last_type, UnpackType):
10481048
return typ
1049-
last_type = get_proper_type(last_type.type)
1050-
if not isinstance(last_type, TypedDictType):
1049+
p_last_type = get_proper_type(last_type.type)
1050+
if not isinstance(p_last_type, TypedDictType):
10511051
self.fail("Unpack item in ** argument must be a TypedDict", last_type)
10521052
new_arg_types = typ.arg_types[:-1] + [AnyType(TypeOfAny.from_error)]
10531053
return typ.copy_modified(arg_types=new_arg_types)
1054-
overlap = set(typ.arg_names) & set(last_type.items)
1054+
overlap = set(typ.arg_names) & set(p_last_type.items)
10551055
# It is OK for TypedDict to have a key named 'kwargs'.
10561056
overlap.discard(typ.arg_names[-1])
10571057
if overlap:
@@ -1060,7 +1060,7 @@ def remove_unpack_kwargs(self, defn: FuncDef, typ: CallableType) -> CallableType
10601060
new_arg_types = typ.arg_types[:-1] + [AnyType(TypeOfAny.from_error)]
10611061
return typ.copy_modified(arg_types=new_arg_types)
10621062
# OK, everything looks right now, mark the callable type as using unpack.
1063-
new_arg_types = typ.arg_types[:-1] + [last_type]
1063+
new_arg_types = typ.arg_types[:-1] + [p_last_type]
10641064
return typ.copy_modified(arg_types=new_arg_types, unpack_kwargs=True)
10651065

10661066
def prepare_method_signature(self, func: FuncDef, info: TypeInfo, has_self_type: bool) -> None:

mypy/types.py

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,7 @@ def _expand_once(self) -> Type:
355355
):
356356
mapping[tvar.id] = sub
357357

358-
new_tp = self.alias.target.accept(InstantiateAliasVisitor(mapping))
359-
new_tp.accept(LocationSetter(self.line, self.column))
360-
new_tp.line = self.line
361-
new_tp.column = self.column
362-
return new_tp
358+
return self.alias.target.accept(InstantiateAliasVisitor(mapping))
363359

364360
def _partial_expansion(self, nothing_args: bool = False) -> tuple[ProperType, bool]:
365361
# Private method mostly for debugging and testing.
@@ -3260,7 +3256,6 @@ def get_proper_types(
32603256
TypeTranslator as TypeTranslator,
32613257
TypeVisitor as TypeVisitor,
32623258
)
3263-
from mypy.typetraverser import TypeTraverserVisitor
32643259

32653260

32663261
class TypeStrVisitor(SyntheticTypeVisitor[str]):
@@ -3598,23 +3593,6 @@ def is_named_instance(t: Type, fullnames: str | tuple[str, ...]) -> TypeGuard[In
35983593
return isinstance(t, Instance) and t.type.fullname in fullnames
35993594

36003595

3601-
class LocationSetter(TypeTraverserVisitor):
3602-
# TODO: Should we update locations of other Type subclasses?
3603-
def __init__(self, line: int, column: int) -> None:
3604-
self.line = line
3605-
self.column = column
3606-
3607-
def visit_instance(self, typ: Instance) -> None:
3608-
typ.line = self.line
3609-
typ.column = self.column
3610-
super().visit_instance(typ)
3611-
3612-
def visit_type_alias_type(self, typ: TypeAliasType) -> None:
3613-
typ.line = self.line
3614-
typ.column = self.column
3615-
super().visit_type_alias_type(typ)
3616-
3617-
36183596
class HasTypeVars(BoolTypeQuery):
36193597
"""Visitor for querying whether a type has a type variable component."""
36203598

@@ -3709,8 +3687,8 @@ def flatten_nested_unions(
37093687

37103688
flat_items: list[Type] = []
37113689
for t in typelist:
3712-
if handle_type_alias_type:
3713-
if not handle_recursive and isinstance(t, TypeAliasType) and t.is_recursive:
3690+
if handle_type_alias_type and isinstance(t, TypeAliasType):
3691+
if not handle_recursive and t.is_recursive:
37143692
tp: Type = t
37153693
else:
37163694
tp = get_proper_type(t)
@@ -3757,7 +3735,21 @@ def flatten_nested_tuples(types: Iterable[Type]) -> list[Type]:
37573735
if not isinstance(p_type, TupleType):
37583736
res.append(typ)
37593737
continue
3760-
res.extend(flatten_nested_tuples(p_type.items))
3738+
if isinstance(typ.type, TypeAliasType):
3739+
items = []
3740+
for item in p_type.items:
3741+
if (
3742+
isinstance(item, ProperType)
3743+
and isinstance(item, Instance)
3744+
or isinstance(item, TypeAliasType)
3745+
):
3746+
if len(item.args) == 0:
3747+
item = item.copy_modified()
3748+
item.set_line(typ)
3749+
items.append(item)
3750+
else:
3751+
items = p_type.items
3752+
res.extend(flatten_nested_tuples(items))
37613753
return res
37623754

37633755

0 commit comments

Comments
 (0)