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

Untangle most of the big import cycle #7397

Merged
merged 8 commits into from
Aug 27, 2019
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 23 additions & 19 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
Type, AnyType, CallableType, FunctionLike, Overloaded, TupleType, TypedDictType,
Instance, NoneType, strip_type, TypeType, TypeOfAny,
UnionType, TypeVarId, TypeVarType, PartialType, DeletedType, UninhabitedType, TypeVarDef,
true_only, false_only, function_type, is_named_instance, union_items, TypeQuery, LiteralType,
function_type, is_named_instance, union_items, TypeQuery, LiteralType,
is_optional, remove_optional, TypeTranslator, StarType, get_proper_type, ProperType,
get_proper_types, is_literal_type
)
Expand All @@ -45,8 +45,12 @@
)
import mypy.checkexpr
from mypy.checkmember import (
map_type_from_supertype, bind_self, erase_to_bound, type_object_type,
analyze_descriptor_access,
analyze_descriptor_access, type_object_type,
)
from mypy.typeops import (
map_type_from_supertype, bind_self, erase_to_bound, make_simplified_union,
erase_def_to_union_or_bound, erase_to_union_or_bound,
true_only, false_only,
)
from mypy import message_registry
from mypy.subtypes import (
Expand Down Expand Up @@ -1539,7 +1543,7 @@ def get_op_other_domain(self, tp: FunctionLike) -> Optional[Type]:
raw_items = [self.get_op_other_domain(it) for it in tp.items()]
items = [it for it in raw_items if it]
if items:
return UnionType.make_simplified_union(items)
return make_simplified_union(items)
return None
else:
assert False, "Need to check all FunctionLike subtypes here"
Expand Down Expand Up @@ -1973,7 +1977,7 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
if not self.current_node_deferred:
# Partial type can't be final, so strip any literal values.
rvalue_type = remove_instance_last_known_values(rvalue_type)
inferred_type = UnionType.make_simplified_union(
inferred_type = make_simplified_union(
[rvalue_type, NoneType()])
self.set_inferred_type(var, lvalue, inferred_type)
else:
Expand Down Expand Up @@ -2417,7 +2421,7 @@ def check_multi_assignment_from_union(self, lvalues: List[Expression], rvalue: E
rv_type=item, undefined_rvalue=True)
for t, lv in zip(transposed, self.flatten_lvalues(lvalues)):
t.append(self.type_map.pop(lv, AnyType(TypeOfAny.special_form)))
union_types = tuple(UnionType.make_simplified_union(col) for col in transposed)
union_types = tuple(make_simplified_union(col) for col in transposed)
for expr, items in assignments.items():
# Bind a union of types collected in 'assignments' to every expression.
if isinstance(expr, StarExpr):
Expand All @@ -2432,8 +2436,8 @@ def check_multi_assignment_from_union(self, lvalues: List[Expression], rvalue: E

types, declared_types = zip(*clean_items)
self.binder.assign_type(expr,
UnionType.make_simplified_union(list(types)),
UnionType.make_simplified_union(list(declared_types)),
make_simplified_union(list(types)),
make_simplified_union(list(declared_types)),
False)
for union, lv in zip(union_types, self.flatten_lvalues(lvalues)):
# Properly store the inferred types.
Expand Down Expand Up @@ -2856,9 +2860,9 @@ def try_infer_partial_type_from_indexed_assignment(
# TODO: Don't infer things twice.
key_type = self.expr_checker.accept(lvalue.index)
value_type = self.expr_checker.accept(rvalue)
full_key_type = UnionType.make_simplified_union(
full_key_type = make_simplified_union(
[key_type, var.type.inner_types[0]])
full_value_type = UnionType.make_simplified_union(
full_value_type = make_simplified_union(
[value_type, var.type.inner_types[1]])
if (is_valid_inferred_type(full_key_type) and
is_valid_inferred_type(full_value_type)):
Expand Down Expand Up @@ -3176,7 +3180,7 @@ def check_except_handler_test(self, n: Expression) -> Type:

all_types.append(exc_type)

return UnionType.make_simplified_union(all_types)
return make_simplified_union(all_types)

def get_types_from_except_handler(self, typ: Type, n: Expression) -> List[Type]:
"""Helper for check_except_handler_test to retrieve handler types."""
Expand Down Expand Up @@ -3524,7 +3528,7 @@ def partition_by_callable(self, typ: Type,
# do better.
# If it is possible for the false branch to execute, return the original
# type to avoid losing type information.
callables, uncallables = self.partition_by_callable(typ.erase_to_union_or_bound(),
callables, uncallables = self.partition_by_callable(erase_to_union_or_bound(typ),
unsound_partition)
uncallables = [typ] if len(uncallables) else []
return callables, uncallables
Expand Down Expand Up @@ -4087,7 +4091,7 @@ def conditional_type_map(expr: Expression,
if it was not the proposed type, if any. None means bot, {} means top"""
if proposed_type_ranges:
proposed_items = [type_range.item for type_range in proposed_type_ranges]
proposed_type = UnionType.make_simplified_union(proposed_items)
proposed_type = make_simplified_union(proposed_items)
if current_type:
if isinstance(proposed_type, AnyType):
# We don't really know much about the proposed type, so we shouldn't
Expand Down Expand Up @@ -4170,7 +4174,7 @@ def builtin_item_type(tp: Type) -> Optional[Type]:
return tp.args[0]
elif isinstance(tp, TupleType) and all(not isinstance(it, AnyType)
for it in get_proper_types(tp.items)):
return UnionType.make_simplified_union(tp.items) # this type is not externally visible
return make_simplified_union(tp.items) # this type is not externally visible
elif isinstance(tp, TypedDictType):
# TypedDict always has non-optional string keys. Find the key type from the Mapping
# base class.
Expand Down Expand Up @@ -4221,7 +4225,7 @@ def or_conditional_maps(m1: TypeMap, m2: TypeMap) -> TypeMap:
for n1 in m1:
for n2 in m2:
if literal_hash(n1) == literal_hash(n2):
result[n1] = UnionType.make_simplified_union([m1[n1], m2[n2]])
result[n1] = make_simplified_union([m1[n1], m2[n2]])
return result


Expand Down Expand Up @@ -4435,7 +4439,7 @@ def overload_can_never_match(signature: CallableType, other: CallableType) -> bo
# the below subtype check and (surprisingly?) `is_proper_subtype(Any, Any)`
# returns `True`.
# TODO: find a cleaner solution instead of this ad-hoc erasure.
exp_signature = expand_type(signature, {tvar.id: tvar.erase_to_union_or_bound()
exp_signature = expand_type(signature, {tvar.id: erase_def_to_union_or_bound(tvar)
for tvar in signature.variables})
assert isinstance(exp_signature, CallableType)
return is_callable_compatible(exp_signature, other,
Expand Down Expand Up @@ -4689,7 +4693,7 @@ class Status(Enum):

if isinstance(typ, UnionType):
items = [try_expanding_enum_to_union(item, target_fullname) for item in typ.items]
return UnionType.make_simplified_union(items)
return make_simplified_union(items)
elif isinstance(typ, Instance) and typ.type.is_enum and typ.type.fullname() == target_fullname:
new_items = []
for name, symbol in typ.type.names.items():
Expand All @@ -4704,7 +4708,7 @@ class Status(Enum):
# only using CPython, but we might as well for the sake of full correctness.
if sys.version_info < (3, 7):
new_items.sort(key=lambda lit: lit.value)
return UnionType.make_simplified_union(new_items)
return make_simplified_union(new_items)
else:
return typ

Expand All @@ -4716,7 +4720,7 @@ def coerce_to_literal(typ: Type) -> ProperType:
typ = get_proper_type(typ)
if isinstance(typ, UnionType):
new_items = [coerce_to_literal(item) for item in typ.items]
return UnionType.make_simplified_union(new_items)
return make_simplified_union(new_items)
elif isinstance(typ, Instance) and typ.last_known_value:
return typ.last_known_value
else:
Expand Down
54 changes: 28 additions & 26 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
Type, AnyType, CallableType, Overloaded, NoneType, TypeVarDef,
TupleType, TypedDictType, Instance, TypeVarType, ErasedType, UnionType,
PartialType, DeletedType, UninhabitedType, TypeType, TypeOfAny, LiteralType, LiteralValue,
true_only, false_only, is_named_instance, function_type, callable_type, FunctionLike,
is_named_instance, function_type, callable_type, FunctionLike,
StarType, is_optional, remove_optional, is_generic_instance, get_proper_type, ProperType,
get_proper_types
)
Expand Down Expand Up @@ -59,7 +59,9 @@
from mypy.typevars import fill_typevars
from mypy.visitor import ExpressionVisitor
from mypy.plugin import Plugin, MethodContext, MethodSigContext, FunctionContext
from mypy.typeops import tuple_fallback
from mypy.typeops import (
tuple_fallback, make_simplified_union, true_only, false_only, erase_to_union_or_bound,
)
import mypy.errorcodes as codes

# Type of callback user for checking individual function arguments. See
Expand Down Expand Up @@ -528,7 +530,7 @@ def try_infer_partial_type(self, e: CallExpr) -> None:
if (typename in self.item_args and methodname in self.item_args[typename]
and e.arg_kinds == [ARG_POS]):
item_type = self.accept(e.args[0])
full_item_type = UnionType.make_simplified_union(
full_item_type = make_simplified_union(
[item_type, partial_type.inner_types[0]])
if mypy.checker.is_valid_inferred_type(full_item_type):
var.type = self.chk.named_generic_type(typename, [full_item_type])
Expand All @@ -541,7 +543,7 @@ def try_infer_partial_type(self, e: CallExpr) -> None:
arg_typename = arg_type.type.fullname()
if arg_typename in self.container_args[typename][methodname]:
full_item_types = [
UnionType.make_simplified_union([item_type, prev_type])
make_simplified_union([item_type, prev_type])
for item_type, prev_type
in zip(arg_type.args, partial_type.inner_types)
]
Expand Down Expand Up @@ -713,7 +715,7 @@ def check_union_call_expr(self, e: CallExpr, object_type: UnionType, member: str
item_object_type = typ if callable_name else None
res.append(self.check_call_expr_with_callee_type(narrowed, e, callable_name,
item_object_type))
return UnionType.make_simplified_union(res)
return make_simplified_union(res)

def check_call(self,
callee: Type,
Expand Down Expand Up @@ -1377,9 +1379,9 @@ def check_overload_call(self,
# a union of inferred callables because for example a call
# Union[int -> int, str -> str](Union[int, str]) is invalid and
# we don't want to introduce internal inconsistencies.
unioned_result = (UnionType.make_simplified_union(list(returns),
context.line,
context.column),
unioned_result = (make_simplified_union(list(returns),
context.line,
context.column),
self.combine_function_signatures(inferred_types))

# Step 3: We try checking each branch one-by-one.
Expand Down Expand Up @@ -1736,7 +1738,7 @@ def combine_function_signatures(self, types: Sequence[Type]) -> Union[AnyType, C
new_args[i].append(arg)
new_returns.append(target.ret_type)

union_return = UnionType.make_simplified_union(new_returns)
union_return = make_simplified_union(new_returns)
if too_complex:
any = AnyType(TypeOfAny.special_form)
return callables[0].copy_modified(
Expand All @@ -1749,7 +1751,7 @@ def combine_function_signatures(self, types: Sequence[Type]) -> Union[AnyType, C

final_args = []
for args_list in new_args:
new_type = UnionType.make_simplified_union(args_list)
new_type = make_simplified_union(args_list)
final_args.append(new_type)

return callables[0].copy_modified(
Expand Down Expand Up @@ -1818,7 +1820,7 @@ def check_union_call(self,
arg_messages=arg_messages)
for subtype in callee.relevant_items()]
self.msg.disable_type_names -= 1
return (UnionType.make_simplified_union([res[0] for res in results]),
return (make_simplified_union([res[0] for res in results]),
callee)

def visit_member_expr(self, e: MemberExpr, is_lvalue: bool = False) -> Type:
Expand Down Expand Up @@ -2168,7 +2170,7 @@ def check_union_method_call_by_name(self,
local_errors.disable_type_names -= 1
res.append(item)
meth_res.append(meth_item)
return UnionType.make_simplified_union(res), UnionType.make_simplified_union(meth_res)
return make_simplified_union(res), make_simplified_union(meth_res)

def check_method_call(self,
method_name: str,
Expand Down Expand Up @@ -2425,8 +2427,8 @@ def check_op(self, method: str, base_type: Type,
all_inferred.append(inferred)

if not msg.is_errors():
results_final = UnionType.make_simplified_union(all_results)
inferred_final = UnionType.make_simplified_union(all_inferred)
results_final = make_simplified_union(all_results)
inferred_final = make_simplified_union(all_inferred)
return results_final, inferred_final

# Step 2: If that fails, we try again but also destructure the right argument.
Expand Down Expand Up @@ -2475,7 +2477,7 @@ def check_op(self, method: str, base_type: Type,
# See the comment in 'check_overload_call' for more details on why
# we call 'combine_function_signature' instead of just unioning the inferred
# callable types.
results_final = UnionType.make_simplified_union(all_results)
results_final = make_simplified_union(all_results)
inferred_final = self.combine_function_signatures(all_inferred)
return results_final, inferred_final
else:
Expand Down Expand Up @@ -2560,7 +2562,7 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type:
# The left operand is always the result
return left_type
else:
return UnionType.make_simplified_union([restricted_left_type, right_type])
return make_simplified_union([restricted_left_type, right_type])

def check_list_multiply(self, e: OpExpr) -> Type:
"""Type check an expression of form '[...] * e'.
Expand Down Expand Up @@ -2626,9 +2628,9 @@ def visit_index_with_type(self, left_type: Type, e: IndexExpr,

if isinstance(left_type, UnionType):
original_type = original_type or left_type
return UnionType.make_simplified_union([self.visit_index_with_type(typ, e,
original_type)
for typ in left_type.relevant_items()])
return make_simplified_union([self.visit_index_with_type(typ, e,
original_type)
for typ in left_type.relevant_items()])
elif isinstance(left_type, TupleType) and self.chk.in_checked_function():
# Special case for tuples. They return a more specific type when
# indexed by an integer literal.
Expand All @@ -2646,7 +2648,7 @@ def visit_index_with_type(self, left_type: Type, e: IndexExpr,
else:
self.chk.fail(message_registry.TUPLE_INDEX_OUT_OF_RANGE, e)
return AnyType(TypeOfAny.from_error)
return UnionType.make_simplified_union(out)
return make_simplified_union(out)
else:
return self.nonliteral_tuple_index_helper(left_type, index)
elif isinstance(left_type, TypedDictType):
Expand Down Expand Up @@ -2687,7 +2689,7 @@ def visit_tuple_slice_helper(self, left_type: TupleType, slic: SliceExpr) -> Typ
items = [] # type: List[Type]
for b, e, s in itertools.product(begin, end, stride):
items.append(left_type.slice(b, e, s))
return UnionType.make_simplified_union(items)
return make_simplified_union(items)

def try_getting_int_literals(self, index: Expression) -> Optional[List[int]]:
"""If the given expression or type corresponds to an int literal
Expand Down Expand Up @@ -2732,7 +2734,7 @@ def nonliteral_tuple_index_helper(self, left_type: TupleType, index: Expression)
'actual type', 'expected type'):
return AnyType(TypeOfAny.from_error)
else:
union = UnionType.make_simplified_union(left_type.items)
union = make_simplified_union(left_type.items)
if isinstance(index, SliceExpr):
return self.chk.named_generic_type('builtins.tuple', [union])
else:
Expand Down Expand Up @@ -2767,7 +2769,7 @@ def visit_typeddict_index_expr(self, td_type: TypedDictType, index: Expression)
return AnyType(TypeOfAny.from_error)
else:
value_types.append(value_type)
return UnionType.make_simplified_union(value_types)
return make_simplified_union(value_types)

def visit_enum_index_expr(self, enum_type: TypeInfo, index: Expression,
context: Context) -> Type:
Expand Down Expand Up @@ -3471,7 +3473,7 @@ def visit_conditional_expr(self, e: ConditionalExpr) -> Type:
#
# TODO: Always create a union or at least in more cases?
if isinstance(get_proper_type(self.type_context[-1]), UnionType):
res = UnionType.make_simplified_union([if_type, else_type])
res = make_simplified_union([if_type, else_type])
else:
res = join.join_types(if_type, else_type)

Expand Down Expand Up @@ -3919,9 +3921,9 @@ def arg_approximate_similarity(actual: Type, formal: Type) -> bool:

# Erase typevars: we'll consider them all to have the same "shape".
if isinstance(actual, TypeVarType):
actual = actual.erase_to_union_or_bound()
actual = erase_to_union_or_bound(actual)
if isinstance(formal, TypeVarType):
formal = formal.erase_to_union_or_bound()
formal = erase_to_union_or_bound(formal)

# Callable or Type[...]-ish types
def is_typetype_like(typ: ProperType) -> bool:
Expand Down
Loading