Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# We need to record this check to generate protocol fine-grained dependencies.
TypeState.record_protocol_subtype_check(left.type, right.type)
assuming = right.type.assuming_proper if proper_subtype else right.type.assuming
for (l, r) in reversed(assuming):
if (mypy.sametypes.is_same_type(l, left)
and mypy.sametypes.is_same_type(r, right)):
return True
with pop_on_exit(assuming, left, right):
for member in right.type.protocol_members:
# nominal subtyping currently ignores '__init__' and '__new__' signatures
if member in ('__init__', '__new__'):
continue
ignore_names = member != '__call__' # __call__ can be passed kwargs
# The third argument below indicates to what self type is bound.
# We always bind self to the subtype. (Similarly to nominal types).
supertype = get_proper_type(find_member(member, right, left))
assert supertype is not None
subtype = get_proper_type(find_member(member, left, left))
# Useful for debugging:
# print(member, 'of', left, 'has type', subtype)
# print(member, 'of', right, 'has type', supertype)
if not subtype:
return False
if not proper_subtype:
# Nominal check currently ignores arg names
# NOTE: If we ever change this, be sure to also change the call to
# SubtypeVisitor.build_subtype_kind(...) down below.
is_compat = is_subtype(subtype, supertype, ignore_pos_arg_names=ignore_names)
else:
is_compat = is_proper_subtype(subtype, supertype)
if not is_compat:
return False
def trivial_join(s: Type, t: Type) -> ProperType:
"""Return one of types (expanded) if it is a supertype of other, otherwise top type."""
if is_subtype(s, t):
return get_proper_type(t)
elif is_subtype(t, s):
return get_proper_type(s)
else:
return object_or_any_from_type(get_proper_type(t))
format(item_type)))
s = 'TypedDict({{{}}})'.format(', '.join(items))
return s
elif isinstance(typ, LiteralType):
if typ.is_enum_literal():
underlying_type = format(typ.fallback)
return 'Literal[{}.{}]'.format(underlying_type, typ.value)
else:
return str(typ)
elif isinstance(typ, UnionType):
# Only print Unions as Optionals if the Optional wouldn't have to contain another Union
print_as_optional = (len(typ.items) -
sum(isinstance(get_proper_type(t), NoneType)
for t in typ.items) == 1)
if print_as_optional:
rest = [t for t in typ.items if not isinstance(get_proper_type(t), NoneType)]
return 'Optional[{}]'.format(format(rest[0]))
else:
items = []
for t in typ.items:
items.append(format(t))
s = 'Union[{}]'.format(', '.join(items))
if len(s) < 400:
return s
else:
return ''.format(len(items))
elif isinstance(typ, NoneType):
return 'None'
elif isinstance(typ, AnyType):
return 'Any'
elif isinstance(typ, DeletedType):
return ''
def record_call_target_precision(self, o: CallExpr) -> None:
"""Record precision of formal argument types used in a call."""
if not self.typemap or o.callee not in self.typemap:
# Type not availabe.
return
callee_type = get_proper_type(self.typemap[o.callee])
if isinstance(callee_type, CallableType):
self.record_callable_target_precision(o, callee_type)
else:
pass # TODO: Handle overloaded functions, etc.
def format_type_inner(typ: Type,
verbosity: int,
fullnames: Optional[Set[str]]) -> str:
"""
Convert a type to a relatively short string suitable for error messages.
Args:
verbosity: a coarse grained control on the verbosity of the type
fullnames: a set of names that should be printed in full
"""
def format(typ: Type) -> str:
return format_type_inner(typ, verbosity, fullnames)
# TODO: show type alias names in errors.
typ = get_proper_type(typ)
if isinstance(typ, Instance):
itype = typ
# Get the short name of the type.
if itype.type.fullname in ('types.ModuleType', '_importlib_modulespec.ModuleType'):
# Make some common error messages simpler and tidier.
return 'Module'
if verbosity >= 2 or (fullnames and itype.type.fullname in fullnames):
base_str = itype.type.fullname
else:
base_str = itype.type.name
if itype.args == []:
# No type arguments, just return the type name
return base_str
elif itype.type.fullname == 'builtins.tuple':
item_type_str = format(itype.args[0])
def type(self, t: Optional[Type]) -> None:
t = get_proper_type(t)
if not t:
# If an expression does not have a type, it is often due to dead code.
# Don't count these because there can be an unanalyzed value on a line with other
# analyzed expressions, which overwrite the TYPE_UNANALYZED.
self.record_line(self.line, TYPE_UNANALYZED)
return
if isinstance(t, AnyType) and is_special_form_any(t):
# TODO: What if there is an error in special form definition?
self.record_line(self.line, TYPE_PRECISE)
return
if isinstance(t, AnyType):
self.log(' !! Any type around line %d' % self.line)
self.num_any_exprs += 1
def is_improper_type(typ: Type) -> bool:
"""Is this a type that is not a subtype of ProperType?"""
typ = get_proper_type(typ)
if isinstance(typ, Instance):
info = typ.type
return info.has_base('mypy.types.Type') and not info.has_base('mypy.types.ProperType')
if isinstance(typ, UnionType):
return any(is_improper_type(t) for t in typ.items)
return False
# Class-level function objects and classmethods become bound methods:
# the former to the instance, the latter to the class.
functype = typ
# Use meet to narrow original_type to the dispatched type.
# For example, assume
# * A.f: Callable[[A1], None] where A1 <: A (maybe A1 == A)
# * B.f: Callable[[B1], None] where B1 <: B (maybe B1 == B)
# * x: Union[A1, B1]
# In `x.f`, when checking `x` against A1 we assume x is compatible with A
# and similarly for B1 when checking agains B
dispatched_type = meet.meet_types(mx.original_type, itype)
signature = freshen_function_type_vars(functype)
signature = check_self_arg(signature, dispatched_type, var.is_classmethod,
mx.context, name, mx.msg)
signature = bind_self(signature, mx.self_type, var.is_classmethod)
expanded_signature = get_proper_type(expand_type_by_instance(signature, itype))
freeze_type_vars(expanded_signature)
if var.is_property:
# A property cannot have an overloaded type => the cast is fine.
assert isinstance(expanded_signature, CallableType)
result = expanded_signature.ret_type
else:
result = expanded_signature
else:
if not var.is_ready:
mx.not_ready_callback(var.name, mx.context)
# Implicit 'Any' type.
result = AnyType(TypeOfAny.special_form)
fullname = '{}.{}'.format(var.info.fullname, name)
hook = mx.chk.plugin.get_attribute_hook(fullname)
if result and not mx.is_lvalue and not implicit:
result = analyze_descriptor_access(mx.original_type, result, mx.builtin_type,
For example, if we have:
class Color(Enum):
RED = 1
BLUE = 2
YELLOW = 3
class Status(Enum):
SUCCESS = 1
FAILURE = 2
UNKNOWN = 3
...and if we call `try_expanding_enum_to_union(Union[Color, Status], 'module.Color')`,
this function will return Literal[Color.RED, Color.BLUE, Color.YELLOW, Status].
"""
typ = get_proper_type(typ)
if isinstance(typ, UnionType):
items = [try_expanding_enum_to_union(item, target_fullname) for item in typ.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():
if not isinstance(symbol.node, Var):
continue
# Skip "_order_" and "__order__", since Enum will remove it
if name in ("_order_", "__order__"):
continue
new_items.append(LiteralType(name, typ))
# SymbolTables are really just dicts, and dicts are guaranteed to preserve
# insertion order only starting with Python 3.7. So, we sort these for older
# versions of Python to help make tests deterministic.
def restrict_subtype_away(t: Type, s: Type, *, ignore_promotions: bool = False) -> Type:
"""Return t minus s for runtime type assertions.
If we can't determine a precise result, return a supertype of the
ideal result (just t is a valid result).
This is used for type inference of runtime type checks such as
isinstance(). Currently this just removes elements of a union type.
"""
t = get_proper_type(t)
s = get_proper_type(s)
if isinstance(t, UnionType):
new_items = [restrict_subtype_away(item, s, ignore_promotions=ignore_promotions)
for item in t.relevant_items()
if (isinstance(get_proper_type(item), AnyType) or
not covers_at_runtime(item, s, ignore_promotions))]
return UnionType.make_union(new_items)
else:
return t