Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
messages: MessageBuilder = None) -> Type:
"""Infer the correct overload item to call with given argument types.
The return value may be CallableType or AnyType (if an unique item
could not be determined).
"""
messages = messages or self.msg
# TODO: For overlapping signatures we should try to get a more precise
# result than 'Any'.
match = [] # type: List[CallableType]
best_match = 0
for typ in overload.items():
similarity = self.erased_signature_similarity(arg_types, arg_kinds, arg_names,
typ, context=context)
if similarity > 0 and similarity >= best_match:
if (match and not is_same_type(match[-1].ret_type,
typ.ret_type) and
not mypy.checker.is_more_precise_signature(
match[-1], typ)):
# Ambiguous return type. Either the function overload is
# overlapping (which we don't handle very well here) or the
# caller has provided some Any argument types; in either
# case we'll fall back to Any. It's okay to use Any types
# in calls.
#
# Overlapping overload items are generally fine if the
# overlapping is only possible when there is multiple
# inheritance, as this is rare. See docstring of
# mypy.meet.is_overlapping_types for more about this.
#
# Note that there is no ambiguity if the items are
# covariant in both argument types and return types with
def has_no_typevars(typ: Type) -> bool:
return is_same_type(typ, erase_typevars(typ))
min_args = max(signature.min_args, other.min_args)
max_args = min(len(signature.arg_types), len(other.arg_types))
if min_args > max_args:
# Argument counts are not overlapping.
return False
# Signatures are overlapping iff if they are overlapping for the
# smallest common argument count.
for i in range(min_args):
t1 = signature.arg_types[i]
t2 = other.arg_types[i]
if not is_overlapping_types(t1, t2):
return False
# All arguments types for the smallest common argument count are
# overlapping => the signature is overlapping. The overlapping is
# safe if the return types are identical.
if is_same_type(signature.ret_type, other.ret_type):
return False
# If the first signature has more general argument types, the
# latter will never be called
if is_more_general_arg_prefix(signature, other):
return False
return not is_more_precise_signature(signature, other)
return True
def check_type_var_values(self, type: TypeInfo, actuals: List[Type], arg_name: str,
valids: List[Type], arg_number: int, context: Context) -> None:
for actual in get_proper_types(actuals):
if (not isinstance(actual, AnyType) and
not any(is_same_type(actual, value)
for value in valids)):
if len(actuals) > 1 or not isinstance(actual, Instance):
self.fail('Invalid type argument value for "{}"'.format(
type.name), context, code=codes.TYPE_VAR)
else:
class_name = '"{}"'.format(type.name)
actual_type_name = '"{}"'.format(actual.type.name)
self.fail(
message_registry.INCOMPATIBLE_TYPEVAR_VALUE.format(
arg_name, class_name, actual_type_name),
context,
code=codes.TYPE_VAR)
def is_valid_inferred_type(typ: Type) -> bool:
"""Is an inferred type valid?
Examples of invalid types include the None type or a type with a None component.
"""
if is_same_type(typ, NoneTyp()):
# With strict Optional checking, we *may* eventually infer NoneTyp, but
# we only do that if we can't infer a specific Optional type. This
# resolution happens in leave_partial_types when we pop a partial types
# scope.
return False
if is_same_type(typ, UninhabitedType()):
return False
elif isinstance(typ, Instance):
for arg in typ.args:
if not is_valid_inferred_type(arg):
return False
elif isinstance(typ, TupleType):
for item in typ.items:
if not is_valid_inferred_type(item):
return False
return True
def check_argument(leftarg: Type, rightarg: Type, variance: int) -> bool:
if variance == COVARIANT:
return self._is_proper_subtype(leftarg, rightarg)
elif variance == CONTRAVARIANT:
return self._is_proper_subtype(rightarg, leftarg)
else:
return mypy.sametypes.is_same_type(leftarg, rightarg)
# Map left type to corresponding right instances.
# Flag redefinition unless this is a reimport of a module.
if not (node.kind == MODULE_REF and
self.locals[-1][name].node == node.node):
self.name_already_defined(name, context)
self.locals[-1][name] = node
elif self.type:
self.type.names[name] = node
else:
existing = self.globals.get(name)
if existing and (not isinstance(node.node, MypyFile) or
existing.node != node.node) and existing.kind != UNBOUND_IMPORTED:
# Modules can be imported multiple times to support import
# of multiple submodules of a package (e.g. a.x and a.y).
ok = False
# Only report an error if the symbol collision provides a different type.
if existing.type and node.type and is_same_type(existing.type, node.type):
ok = True
if not ok:
self.name_already_defined(name, context)
self.globals[name] = node
def is_valid_inferred_type(typ: Type) -> bool:
"""Is an inferred type valid?
Examples of invalid types include the None type or List[].
When not doing strict Optional checking, all types containing None are
invalid. When doing strict Optional checking, only None and types that are
incompletely defined (i.e. contain UninhabitedType) are invalid.
"""
if is_same_type(typ, NoneTyp()):
# With strict Optional checking, we *may* eventually infer NoneTyp, but
# we only do that if we can't infer a specific Optional type. This
# resolution happens in leave_partial_types when we pop a partial types
# scope.
return False
return is_valid_inferred_type_component(typ)
def visit_cast_expr(self, expr: CastExpr) -> Type:
"""Type check a cast expression."""
source_type = self.accept(expr.expr, type_context=AnyType(), allow_none_return=True,
always_allow_any=True)
target_type = expr.type
options = self.chk.options
if options.warn_redundant_casts and is_same_type(source_type, target_type):
self.msg.redundant_cast(target_type, expr)
if 'unimported' in options.disallow_any and has_any_from_unimported_type(target_type):
self.msg.unimported_type_becomes_any("Target type of cast", target_type, expr)
return target_type
If a key is declared as AnyType, only update it if all the
options are the same.
"""
changed = False
keys = set(key for f in frames for key in f)
for key in keys:
current_value = self._get(key)
resulting_values = [f.get(key, current_value) for f in frames]
if any(x is None for x in resulting_values):
continue
if isinstance(self.declarations.get(key), AnyType):
type = resulting_values[0]
if not all(is_same_type(type, t) for t in resulting_values[1:]):
type = AnyType()
else:
type = resulting_values[0]
for other in resulting_values[1:]:
type = join_simple(self.declarations[key], type, other)
if not is_same_type(type, current_value):
self._push(key, type)
changed = True
return changed