diff --git a/mypy/checker.py b/mypy/checker.py index 1a8b22aaa79e..9f9cd41bdaaa 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -62,7 +62,7 @@ from mypy.message_registry import ErrorMessage from mypy.subtypes import ( is_subtype, is_equivalent, is_proper_subtype, is_more_precise, - restrict_subtype_away, is_subtype_ignoring_tvars, is_callable_compatible, + restrict_subtype_away, is_callable_compatible, unify_generic_callable, find_member ) from mypy.constraints import SUPERTYPE_OF @@ -961,7 +961,7 @@ def check_func_def(self, defn: FuncItem, typ: CallableType, name: Optional[str]) if isclass: ref_type = mypy.types.TypeType.make_normalized(ref_type) erased = get_proper_type(erase_to_bound(arg_type)) - if not is_subtype_ignoring_tvars(ref_type, erased): + if not is_subtype(ref_type, erased, ignore_type_params=True): note = None if (isinstance(erased, Instance) and erased.type.is_protocol or isinstance(erased, TypeType) and @@ -1742,7 +1742,7 @@ def erase_override(t: Type) -> Type: if len(order) == len(original.items) and order != sorted(order): self.msg.overload_signature_incompatible_with_supertype( - name, name_in_super, supertype, override, node) + name, name_in_super, supertype, node) emitted_msg = True if not emitted_msg: diff --git a/mypy/git.py b/mypy/git.py index da36ff2cb54a..8e73b1eeb9c5 100644 --- a/mypy/git.py +++ b/mypy/git.py @@ -30,9 +30,3 @@ def is_dirty(dir: str) -> bool: """Check whether a git repository has uncommitted changes.""" output = subprocess.check_output(["git", "status", "-uno", "--porcelain"], cwd=dir) return output.strip() != b"" - - -def has_extra_files(dir: str) -> bool: - """Check whether a git repository has untracked files.""" - output = subprocess.check_output(["git", "clean", "--dry-run", "-d"], cwd=dir) - return output.strip() != b"" diff --git a/mypy/join.py b/mypy/join.py index e0d926f3fcf4..d298b495fdc5 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -11,7 +11,7 @@ ) from mypy.maptype import map_instance_to_supertype from mypy.subtypes import ( - is_subtype, is_equivalent, is_subtype_ignoring_tvars, is_proper_subtype, + is_subtype, is_equivalent, is_proper_subtype, is_protocol_implementation, find_member ) from mypy.nodes import INVARIANT, COVARIANT, CONTRAVARIANT @@ -72,7 +72,7 @@ def join_instances(self, t: Instance, s: Instance) -> ProperType: assert new_type is not None args.append(new_type) result: ProperType = Instance(t.type, args) - elif t.type.bases and is_subtype_ignoring_tvars(t, s): + elif t.type.bases and is_subtype(t, s, ignore_type_params=True): result = self.join_instances_via_supertype(t, s) else: # Now t is not a subtype of s, and t != s. Now s could be a subtype @@ -402,8 +402,7 @@ def visit_typeddict_type(self, t: TypedDictType) -> ProperType: if (is_equivalent(s_item_type, t_item_type) and (item_name in t.required_keys) == (item_name in self.s.required_keys)) ]) - mapping_value_type = join_type_list(list(items.values())) - fallback = self.s.create_anonymous_fallback(value_type=mapping_value_type) + fallback = self.s.create_anonymous_fallback() # We need to filter by items.keys() since some required keys present in both t and # self.s might be missing from the join if the types are incompatible. required_keys = set(items.keys()) & t.required_keys & self.s.required_keys diff --git a/mypy/meet.py b/mypy/meet.py index 644b57afbcbe..2ea2bc62a660 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -629,8 +629,7 @@ def visit_typeddict_type(self, t: TypedDictType) -> ProperType: assert t_item_type is not None item_list.append((item_name, t_item_type)) items = OrderedDict(item_list) - mapping_value_type = join.join_type_list(list(items.values())) - fallback = self.s.create_anonymous_fallback(value_type=mapping_value_type) + fallback = self.s.create_anonymous_fallback() required_keys = t.required_keys | self.s.required_keys return TypedDictType(items, required_keys, fallback) elif isinstance(self.s, Instance) and is_subtype(t, self.s): diff --git a/mypy/messages.py b/mypy/messages.py index da284cc88ba4..1e89585000ea 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -807,7 +807,7 @@ def incompatible_operator_assignment(self, op: str, def overload_signature_incompatible_with_supertype( self, name: str, name_in_super: str, supertype: str, - overload: Overloaded, context: Context) -> None: + context: Context) -> None: target = self.override_target(name, name_in_super, supertype) self.fail('Signature of "{}" incompatible with {}'.format( name, target), context, code=codes.OVERRIDE) @@ -1399,9 +1399,6 @@ def redundant_condition_in_comprehension(self, truthiness: bool, context: Contex def redundant_condition_in_if(self, truthiness: bool, context: Context) -> None: self.redundant_expr("If condition", truthiness, context) - def redundant_condition_in_assert(self, truthiness: bool, context: Context) -> None: - self.redundant_expr("Condition in assert", truthiness, context) - def redundant_expr(self, description: str, truthiness: bool, context: Context) -> None: self.fail("{} is always {}".format(description, str(truthiness).lower()), context, code=codes.REDUNDANT_EXPR) @@ -1855,8 +1852,7 @@ def format_type(typ: Type, verbosity: int = 0) -> str: def format_type_bare(typ: Type, - verbosity: int = 0, - fullnames: Optional[Set[str]] = None) -> str: + verbosity: int = 0) -> str: """ Convert a type to a relatively short string suitable for error messages. diff --git a/mypy/plugins/singledispatch.py b/mypy/plugins/singledispatch.py index 104faa38d1ce..f4b3d7c19425 100644 --- a/mypy/plugins/singledispatch.py +++ b/mypy/plugins/singledispatch.py @@ -201,15 +201,6 @@ def call_singledispatch_function_after_register_argument(ctx: MethodContext) -> return ctx.default_return_type -def rename_func(func: CallableType, new_name: CallableType) -> CallableType: - """Return a new CallableType that is `function` with the name of `new_name`""" - if new_name.name is not None: - signature_used = func.with_name(new_name.name) - else: - signature_used = func - return signature_used - - def call_singledispatch_function_callback(ctx: MethodSigContext) -> FunctionLike: """Called for functools._SingleDispatchCallable.__call__""" if not isinstance(ctx.type, Instance): diff --git a/mypy/semanal.py b/mypy/semanal.py index fe3151ce6cd2..68d97389959c 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -4934,19 +4934,6 @@ def add_exports(self, exp_or_exps: Union[Iterable[Expression], Expression]) -> N if isinstance(exp, StrExpr): self.all_exports.append(exp.value) - def check_no_global(self, - name: str, - ctx: Context, - is_overloaded_func: bool = False) -> None: - if name in self.globals: - prev_is_overloaded = isinstance(self.globals[name], OverloadedFuncDef) - if is_overloaded_func and prev_is_overloaded: - self.fail("Nonconsecutive overload {} found".format(name), ctx) - elif prev_is_overloaded: - self.fail("Definition of '{}' missing 'overload'".format(name), ctx) - else: - self.name_already_defined(name, ctx, self.globals[name]) - def name_not_defined(self, name: str, ctx: Context, namespace: Optional[str] = None) -> None: incomplete = self.is_incomplete_namespace(namespace or self.cur_mod_id) if (namespace is None @@ -5076,9 +5063,6 @@ def fail(self, assert ctx is not None, msg self.errors.report(ctx.get_line(), ctx.get_column(), msg, blocker=blocker, code=code) - def fail_blocker(self, msg: str, ctx: Context) -> None: - self.fail(msg, ctx, blocker=True) - def note(self, msg: str, ctx: Context, code: Optional[ErrorCode] = None) -> None: if not self.in_checked_function(): return diff --git a/mypy/semanal_shared.py b/mypy/semanal_shared.py index 3638d0878d8f..85a6779ac9f3 100644 --- a/mypy/semanal_shared.py +++ b/mypy/semanal_shared.py @@ -7,10 +7,9 @@ from mypy_extensions import trait from mypy.nodes import ( - Context, SymbolTableNode, MypyFile, ImportedName, FuncDef, Node, TypeInfo, Expression, GDEF, + Context, SymbolTableNode, FuncDef, Node, TypeInfo, Expression, SymbolNode, SymbolTable ) -from mypy.util import correct_relative_import from mypy.types import ( Type, FunctionLike, Instance, TupleType, TPDICT_FB_NAMES, ProperType, get_proper_type ) @@ -179,27 +178,6 @@ def is_func_scope(self) -> bool: raise NotImplementedError -def create_indirect_imported_name(file_node: MypyFile, - module: str, - relative: int, - imported_name: str) -> Optional[SymbolTableNode]: - """Create symbol table entry for a name imported from another module. - - These entries act as indirect references. - """ - target_module, ok = correct_relative_import( - file_node.fullname, - relative, - module, - file_node.is_package_init_file()) - if not ok: - return None - target_name = '%s.%s' % (target_module, imported_name) - link = ImportedName(target_name) - # Use GDEF since this refers to a module-level definition. - return SymbolTableNode(GDEF, link) - - def set_callable_name(sig: Type, fdef: FuncDef) -> ProperType: sig = get_proper_type(sig) if isinstance(sig, FunctionLike): diff --git a/mypy/server/update.py b/mypy/server/update.py index e82064c63a11..2f57001766d5 100644 --- a/mypy/server/update.py +++ b/mypy/server/update.py @@ -485,13 +485,6 @@ def ensure_trees_loaded(manager: BuildManager, graph: Dict[str, State], process_fresh_modules(graph, to_process, manager) -def fix_fg_dependencies(manager: BuildManager, deps: Dict[str, Set[str]]) -> None: - """Populate the dependencies with stuff that build may have missed""" - # This means the root module and typestate - merge_dependencies(manager.load_fine_grained_deps(FAKE_ROOT_MODULE), deps) - # TypeState.add_all_protocol_deps(deps) - - # The result of update_module_isolated when no blockers, with these items: # # - Id of the changed module (can be different from the module argument) diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 26054a057540..96cf43fbe21f 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -151,10 +151,6 @@ def _is_subtype(left: Type, right: Type, ignore_promotions=ignore_promotions)) -def is_subtype_ignoring_tvars(left: Type, right: Type) -> bool: - return is_subtype(left, right, ignore_type_params=True) - - def is_equivalent(a: Type, b: Type, *, ignore_type_params: bool = False, diff --git a/mypy/suggestions.py b/mypy/suggestions.py index 87b54814c637..af42cca8a216 100644 --- a/mypy/suggestions.py +++ b/mypy/suggestions.py @@ -344,9 +344,11 @@ def get_args(self, is_method: bool, types.append(arg_types) return types - def get_default_arg_types(self, state: State, fdef: FuncDef) -> List[Optional[Type]]: - return [self.manager.all_types[arg.initializer] if arg.initializer else None - for arg in fdef.arguments] + def get_default_arg_types(self, fdef: FuncDef) -> List[Optional[Type]]: + return [ + self.manager.all_types[arg.initializer] if arg.initializer else None + for arg in fdef.arguments + ] def add_adjustments(self, typs: List[Type]) -> List[Type]: if not self.try_text or self.manager.options.python_version[0] != 2: @@ -441,7 +443,7 @@ def get_suggestion(self, mod: str, node: FuncDef) -> PyAnnotateSignature: guesses = self.get_guesses( is_method, self.get_starting_type(node), - self.get_default_arg_types(graph[mod], node), + self.get_default_arg_types(node), callsites, uses, ) @@ -632,11 +634,8 @@ def try_type(self, func: FuncDef, typ: ProperType) -> List[str]: finally: func.unanalyzed_type = old - def reload(self, state: State, check_errors: bool = False) -> List[str]: - """Recheck the module given by state. - - If check_errors is true, raise an exception if there are errors. - """ + def reload(self, state: State) -> List[str]: + """Recheck the module given by state.""" assert state.path is not None self.fgmanager.flush_cache() return self.fgmanager.update([(state.id, state.path)], []) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index f7b584eadae8..6b7f48fd22aa 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -1356,26 +1356,6 @@ def visit_typeddict_type(self, t: TypedDictType) -> bool: return False -def collect_any_types(t: Type) -> List[AnyType]: - """Return all inner `AnyType`s of type t""" - return t.accept(CollectAnyTypesQuery()) - - -class CollectAnyTypesQuery(TypeQuery[List[AnyType]]): - def __init__(self) -> None: - super().__init__(self.combine_lists_strategy) - - def visit_any(self, t: AnyType) -> List[AnyType]: - return [t] - - @classmethod - def combine_lists_strategy(cls, it: Iterable[List[AnyType]]) -> List[AnyType]: - result: List[AnyType] = [] - for l in it: - result.extend(l) - return result - - def collect_all_inner_types(t: Type) -> List[Type]: """ Return all types that `t` contains diff --git a/mypy/typeops.py b/mypy/typeops.py index e7e9b098eb43..915e13f1c664 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -12,7 +12,7 @@ from mypy.types import ( TupleType, Instance, FunctionLike, Type, CallableType, TypeVarLikeType, Overloaded, - TypeVarType, UninhabitedType, FormalArgument, UnionType, NoneType, TypedDictType, + TypeVarType, UninhabitedType, FormalArgument, UnionType, NoneType, AnyType, TypeOfAny, TypeType, ProperType, LiteralType, get_proper_type, get_proper_types, copy_type, TypeAliasType, TypeQuery, ParamSpecType ) @@ -44,25 +44,6 @@ def tuple_fallback(typ: TupleType) -> Instance: return Instance(info, [join_type_list(typ.items)]) -def try_getting_instance_fallback(typ: ProperType) -> Optional[Instance]: - """Returns the Instance fallback for this type if one exists. - - Otherwise, returns None. - """ - if isinstance(typ, Instance): - return typ - elif isinstance(typ, TupleType): - return tuple_fallback(typ) - elif isinstance(typ, TypedDictType): - return typ.fallback - elif isinstance(typ, FunctionLike): - return typ.fallback - elif isinstance(typ, LiteralType): - return typ.fallback - else: - return None - - def type_object_type_from_function(signature: FunctionLike, info: TypeInfo, def_info: TypeInfo, diff --git a/mypy/types.py b/mypy/types.py index 14eefea7dd81..16bee40045ab 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -903,6 +903,31 @@ class Instance(ProperType): """An instance type of form C[T1, ..., Tn]. The list of type variables may be empty. + + Several types has fallbacks to `Instance`. Why? + Because, for example `TupleTuple` is related to `builtins.tuple` instance. + And `FunctionLike` has `builtins.function` fallback. + This allows us to use types defined + in typeshed for our "special" and more precise types. + + We used to have this helper function to get a fallback from different types. + Note, that it might be incomplete, since it is not used and not updated. + It just illustrates the concept: + + def try_getting_instance_fallback(typ: ProperType) -> Optional[Instance]: + '''Returns the Instance fallback for this type if one exists or None.''' + if isinstance(typ, Instance): + return typ + elif isinstance(typ, TupleType): + return tuple_fallback(typ) + elif isinstance(typ, TypedDictType): + return typ.fallback + elif isinstance(typ, FunctionLike): + return typ.fallback + elif isinstance(typ, LiteralType): + return typ.fallback + return None + """ __slots__ = ('type', 'args', 'erased', 'invalid', 'type_ref', 'last_known_value') @@ -1033,10 +1058,11 @@ class FunctionLike(ProperType): __slots__ = ('fallback',) + fallback: Instance + def __init__(self, line: int = -1, column: int = -1) -> None: super().__init__(line, column) self.can_be_false = False - self.fallback: Instance @abstractmethod def is_type_obj(self) -> bool: pass @@ -1639,7 +1665,7 @@ def copy_modified(self, *, fallback: Optional[Instance] = None, required_keys = self.required_keys return TypedDictType(items, required_keys, fallback, self.line, self.column) - def create_anonymous_fallback(self, *, value_type: Type) -> Instance: + def create_anonymous_fallback(self) -> Instance: anonymous = self.as_anonymous() return anonymous.fallback