Skip to content

Commit

Permalink
Change some sequence components in types from lists to tuples (python…
Browse files Browse the repository at this point in the history
…#8945)

This cuts down on memory a bit by avoiding the separate allocation
inside lists and by allowing all empty sequences to share the empty
tuple.
  • Loading branch information
msullivan authored Jun 8, 2020
1 parent a67b4af commit 109e15d
Show file tree
Hide file tree
Showing 9 changed files with 20 additions and 17 deletions.
4 changes: 3 additions & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -3135,7 +3135,9 @@ class LongName(Generic[T]): ...
# This type is invalid in most runtime contexts, give it an 'object' type.
return self.named_type('builtins.object')

def apply_type_arguments_to_callable(self, tp: Type, args: List[Type], ctx: Context) -> Type:
def apply_type_arguments_to_callable(
self, tp: Type, args: Sequence[Type], ctx: Context
) -> Type:
"""Apply type arguments to a generic callable type coming from a type object.
This will first perform type arguments count checks, report the
Expand Down
2 changes: 1 addition & 1 deletion mypy/expandtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def expand_type_by_instance(typ: Type, instance: Instance) -> Type:
"""Substitute type variables in type using values from an Instance.
Type variables are considered to be bound by the class declaration."""
# TODO: use an overloaded signature? (ProperType stays proper after expansion.)
if instance.args == []:
if not instance.args:
return typ
else:
variables = {} # type: Dict[TypeVarId, Type]
Expand Down
2 changes: 1 addition & 1 deletion mypy/exprtotype.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def expr_to_unanalyzed_type(expr: Expression, _parent: Optional[Expression] = No
args = expr.index.items
else:
args = [expr.index]
base.args = [expr_to_unanalyzed_type(arg, expr) for arg in args]
base.args = tuple(expr_to_unanalyzed_type(arg, expr) for arg in args)
if not base.args:
base.empty_tuple_index = True
return base
Expand Down
2 changes: 1 addition & 1 deletion mypy/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -1595,7 +1595,7 @@ def format(typ: Type) -> str:
base_str = itype.type.fullname
else:
base_str = itype.type.name
if itype.args == []:
if not itype.args:
# No type arguments, just return the type name
return base_str
elif itype.type.fullname == 'builtins.tuple':
Expand Down
2 changes: 1 addition & 1 deletion mypy/semanal_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,4 @@ def calculate_tuple_fallback(typ: TupleType) -> None:
"""
fallback = typ.partial_fallback
assert fallback.type.fullname == 'builtins.tuple'
fallback.args[0] = join.join_type_list(list(typ.items))
fallback.args = (join.join_type_list(list(typ.items)),) + fallback.args[1:]
2 changes: 1 addition & 1 deletion mypy/suggestions.py
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ def visit_instance(self, t: Instance) -> str:

if (mod, obj) == ('builtins', 'tuple'):
mod, obj = 'typing', 'Tuple[' + t.args[0].accept(self) + ', ...]'
elif t.args != []:
elif t.args:
obj += '[{}]'.format(self.list_str(t.args))

if mod_obj == ('builtins', 'unicode'):
Expand Down
9 changes: 5 additions & 4 deletions mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from contextlib import contextmanager
from mypy.ordered_dict import OrderedDict

from typing import Callable, List, Optional, Set, Tuple, Iterator, TypeVar, Iterable
from typing import Callable, List, Optional, Set, Tuple, Iterator, TypeVar, Iterable, Sequence
from typing_extensions import Final
from mypy_extensions import DefaultNamedArg

Expand Down Expand Up @@ -324,7 +324,8 @@ def get_omitted_any(self, typ: Type, fullname: Optional[str] = None) -> AnyType:
disallow_any = not self.is_typeshed_stub and self.options.disallow_any_generics
return get_omitted_any(disallow_any, self.fail, self.note, typ, fullname)

def analyze_type_with_type_info(self, info: TypeInfo, args: List[Type], ctx: Context) -> Type:
def analyze_type_with_type_info(
self, info: TypeInfo, args: Sequence[Type], ctx: Context) -> Type:
"""Bind unbound type when were able to find target TypeInfo.
This handles simple cases like 'int', 'modname.UserClass[str]', etc.
Expand Down Expand Up @@ -951,7 +952,7 @@ def fix_instance(t: Instance, fail: MsgCallback, note: MsgCallback,
else:
fullname = t.type.fullname
any_type = get_omitted_any(disallow_any, fail, note, t, fullname, unexpanded_type)
t.args = [any_type] * len(t.type.type_vars)
t.args = (any_type,) * len(t.type.type_vars)
return
# Invalid number of type parameters.
n = len(t.type.type_vars)
Expand All @@ -968,7 +969,7 @@ def fix_instance(t: Instance, fail: MsgCallback, note: MsgCallback,
# Construct the correct number of type arguments, as
# otherwise the type checker may crash as it expects
# things to be right.
t.args = [AnyType(TypeOfAny.from_error) for _ in t.type.type_vars]
t.args = tuple(AnyType(TypeOfAny.from_error) for _ in t.type.type_vars)
t.invalid = True


Expand Down
12 changes: 6 additions & 6 deletions mypy/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ class UnboundType(ProperType):

def __init__(self,
name: Optional[str],
args: Optional[List[Type]] = None,
args: Optional[Sequence[Type]] = None,
line: int = -1,
column: int = -1,
optional: bool = False,
Expand All @@ -410,7 +410,7 @@ def __init__(self,
args = []
assert name is not None
self.name = name
self.args = args
self.args = tuple(args)
# Should this type be wrapped in an Optional?
self.optional = optional
# Special case for X[()]
Expand All @@ -432,7 +432,7 @@ def __init__(self,
self.original_str_fallback = original_str_fallback

def copy_modified(self,
args: Bogus[Optional[List[Type]]] = _dummy,
args: Bogus[Optional[Sequence[Type]]] = _dummy,
) -> 'UnboundType':
if args is _dummy:
args = self.args
Expand Down Expand Up @@ -731,12 +731,12 @@ class Instance(ProperType):

__slots__ = ('type', 'args', 'erased', 'invalid', 'type_ref', 'last_known_value')

def __init__(self, typ: mypy.nodes.TypeInfo, args: List[Type],
def __init__(self, typ: mypy.nodes.TypeInfo, args: Sequence[Type],
line: int = -1, column: int = -1, erased: bool = False,
last_known_value: Optional['LiteralType'] = None) -> None:
super().__init__(line, column)
self.type = typ
self.args = args
self.args = tuple(args)
self.type_ref = None # type: Optional[str]

# True if result of type variable substitution
Expand Down Expand Up @@ -2013,7 +2013,7 @@ def visit_instance(self, t: Instance) -> str:

if t.erased:
s += '*'
if t.args != []:
if t.args:
s += '[{}]'.format(self.list_str(t.args))
if self.id_mapper:
s += '<{}>'.format(self.id_mapper.id(t.type))
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/plugins/dyn_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def replace_col_hook(ctx):
if new_sym:
new_info = new_sym.node
assert isinstance(new_info, TypeInfo)
node.type = Instance(new_info, node.type.args.copy(),
node.type = Instance(new_info, node.type.args,
node.type.line,
node.type.column)

Expand Down

0 comments on commit 109e15d

Please sign in to comment.