diff --git a/build-requirements.txt b/build-requirements.txt index d1a3a04dc832..0bf40e3c03e8 100644 --- a/build-requirements.txt +++ b/build-requirements.txt @@ -1,4 +1,4 @@ -r mypy-requirements.txt types-psutil types-setuptools -types-typed-ast>=1.5.0,<1.6.0 +types-typed-ast>=1.5.8,<1.6.0 diff --git a/mypy/build.py b/mypy/build.py index f5ebdf52d941..41b1be28598b 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -1292,11 +1292,15 @@ def find_cache_meta(id: str, path: str, manager: BuildManager) -> CacheMeta | No ) # Don't check for path match, that is dealt with in validate_meta(). + # + # TODO: these `type: ignore`s wouldn't be necessary + # if the type annotations for CacheMeta were more accurate + # (all of these attributes can be `None`) if ( m.id != id - or m.mtime is None - or m.size is None - or m.dependencies is None + or m.mtime is None # type: ignore[redundant-expr] + or m.size is None # type: ignore[redundant-expr] + or m.dependencies is None # type: ignore[redundant-expr] or m.data_mtime is None ): manager.log(f"Metadata abandoned for {id}: attributes are missing") diff --git a/mypy/checker.py b/mypy/checker.py index 106c8e9a0351..9f98adae27c1 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1311,7 +1311,7 @@ def check___new___signature(self, fdef: FuncDef, typ: CallableType) -> None: bound_type = bind_self(typ, self_type, is_classmethod=True) # Check that __new__ (after binding cls) returns an instance # type (or any). - if isinstance(fdef.info, TypeInfo) and fdef.info.is_metaclass(): + if fdef.info.is_metaclass(): # This is a metaclass, so it must return a new unrelated type. self.check_subtype( bound_type.ret_type, @@ -1899,7 +1899,7 @@ def check_override( ): fail = True op_method_wider_note = True - if isinstance(original, FunctionLike) and isinstance(override, FunctionLike): + if isinstance(override, FunctionLike): if original_class_or_static and not override_class_or_static: fail = True elif isinstance(original, CallableType) and isinstance(override, CallableType): @@ -2802,12 +2802,8 @@ def check_compatibility_all_supers( # The type of "__slots__" and some other attributes usually doesn't need to # be compatible with a base class. We'll still check the type of "__slots__" # against "object" as an exception. - if ( - isinstance(lvalue_node, Var) - and lvalue_node.allow_incompatible_override - and not ( - lvalue_node.name == "__slots__" and base.fullname == "builtins.object" - ) + if lvalue_node.allow_incompatible_override and not ( + lvalue_node.name == "__slots__" and base.fullname == "builtins.object" ): continue diff --git a/mypy/checkmember.py b/mypy/checkmember.py index ea2544442531..540706847e9a 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -305,7 +305,7 @@ def analyze_instance_member_access( # the first argument. pass else: - if isinstance(signature, FunctionLike) and name != "__call__": + if name != "__call__": # TODO: use proper treatment of special methods on unions instead # of this hack here and below (i.e. mx.self_type). dispatched_type = meet.meet_types(mx.original_type, typ) diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 77c9cb50bc98..95eff523041d 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -744,7 +744,7 @@ def _check_ifstmt_for_overloads( if stmt.else_body is None: return overload_name - if isinstance(stmt.else_body, Block) and len(stmt.else_body.body) == 1: + if len(stmt.else_body.body) == 1: # For elif: else_body contains an IfStmt itself -> do a recursive check. if ( isinstance(stmt.else_body.body[0], (Decorator, FuncDef, OverloadedFuncDef)) @@ -901,13 +901,11 @@ def do_func_def( # PEP 484 disallows both type annotations and type comments if n.returns or any(a.type_annotation is not None for a in args): self.fail(message_registry.DUPLICATE_TYPE_SIGNATURES, lineno, n.col_offset) - translated_args = TypeConverter( + translated_args: list[Type] = TypeConverter( self.errors, line=lineno, override_column=n.col_offset ).translate_expr_list(func_type_ast.argtypes) - arg_types = [ - a if a is not None else AnyType(TypeOfAny.unannotated) - for a in translated_args - ] + # Use a cast to work around `list` invariance + arg_types = cast(List[Optional[Type]], translated_args) return_type = TypeConverter(self.errors, line=lineno).visit(func_type_ast.returns) # add implicit self type diff --git a/mypy/messages.py b/mypy/messages.py index fa9b4e398394..3783d7dd5b10 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -2475,11 +2475,7 @@ def [T <: int] f(self, x: int, y: T) -> None slash = True # If we got a "special arg" (i.e: self, cls, etc...), prepend it to the arg list - if ( - isinstance(tp.definition, FuncDef) - and tp.definition.name is not None - and hasattr(tp.definition, "arguments") - ): + if isinstance(tp.definition, FuncDef) and hasattr(tp.definition, "arguments"): definition_arg_names = [arg.variable.name for arg in tp.definition.arguments] if ( len(definition_arg_names) > len(tp.arg_names) @@ -2671,7 +2667,7 @@ def find_defining_module(modules: dict[str, MypyFile], typ: CallableType) -> Myp if not typ.definition: return None fullname = typ.definition.fullname - if fullname is not None and "." in fullname: + if "." in fullname: for i in range(fullname.count(".")): module_name = fullname.rsplit(".", i + 1)[0] try: diff --git a/mypy/nodes.py b/mypy/nodes.py index 014550cc96aa..98fa54c0cd36 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -3580,7 +3580,10 @@ def serialize(self, prefix: str, name: str) -> JsonDict: if prefix is not None: fullname = self.node.fullname if ( - fullname is not None + # See the comment above SymbolNode.fullname -- fullname can often be None, + # but for complex reasons it's annotated as being `Bogus[str]` instead of `str | None`, + # meaning mypy erroneously thinks the `fullname is not None` check here is redundant + fullname is not None # type: ignore[redundant-expr] and "." in fullname and fullname != prefix + "." + name and not (isinstance(self.node, Var) and self.node.from_module_getattr) diff --git a/mypy/report.py b/mypy/report.py index f51c98721eb0..9e1e156236f2 100644 --- a/mypy/report.py +++ b/mypy/report.py @@ -372,7 +372,7 @@ def visit_func_def(self, defn: FuncDef) -> None: if cur_indent is None: # Consume the line, but don't mark it as belonging to the function yet. cur_line += 1 - elif start_indent is not None and cur_indent > start_indent: + elif cur_indent > start_indent: # A non-blank line that belongs to the function. cur_line += 1 end_line = cur_line diff --git a/mypy/semanal.py b/mypy/semanal.py index 160c319e0e9b..6ac5845824c4 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -5889,7 +5889,7 @@ def in_checked_function(self) -> bool: current_index = len(self.function_stack) - 1 while current_index >= 0: current_func = self.function_stack[current_index] - if isinstance(current_func, FuncItem) and not isinstance(current_func, LambdaExpr): + if not isinstance(current_func, LambdaExpr): return not current_func.is_dynamic() # Special case, `lambda` inherits the "checked" state from its parent. diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 84148167012f..ffd4d48bb458 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -643,7 +643,7 @@ def visit_overloaded_func_def(self, o: OverloadedFuncDef) -> None: self.visit_func_def(item.func, is_abstract=is_abstract, is_overload=is_overload) if is_overload: overload_chain = True - elif overload_chain and is_overload: + elif is_overload: self.visit_func_def(item.func, is_abstract=is_abstract, is_overload=is_overload) else: # skip the overload implementation and clear the decorator we just processed @@ -725,9 +725,7 @@ def visit_func_def( retname = None # implicit Any else: retname = self.print_annotation(o.unanalyzed_type.ret_type) - elif isinstance(o, FuncDef) and ( - o.abstract_status == IS_ABSTRACT or o.name in METHODS_WITH_RETURN_VALUE - ): + elif o.abstract_status == IS_ABSTRACT or o.name in METHODS_WITH_RETURN_VALUE: # Always assume abstract methods return Any unless explicitly annotated. Also # some dunder methods should not have a None return type. retname = None # implicit Any diff --git a/mypy/test/testsemanal.py b/mypy/test/testsemanal.py index 4f1e9d8460dd..70b96c9781fc 100644 --- a/mypy/test/testsemanal.py +++ b/mypy/test/testsemanal.py @@ -220,7 +220,7 @@ class TypeInfoMap(Dict[str, TypeInfo]): def __str__(self) -> str: a: list[str] = ["TypeInfoMap("] for x, y in sorted(self.items()): - if isinstance(x, str) and ( + if ( not x.startswith("builtins.") and not x.startswith("typing.") and not x.startswith("abc.") diff --git a/mypy/test/testtypegen.py b/mypy/test/testtypegen.py index 48e1695d0278..634649c973e5 100644 --- a/mypy/test/testtypegen.py +++ b/mypy/test/testtypegen.py @@ -53,7 +53,7 @@ def run_case(self, testcase: DataDrivenTestCase) -> None: # Filter nodes that should be included in the output. keys = [] for node in nodes: - if node.line is not None and node.line != -1 and map[node]: + if node.line != -1 and map[node]: if ignore_node(node) or node in ignored: continue if re.match(mask, short_type(node)) or ( diff --git a/mypy/types.py b/mypy/types.py index 9fb0ede51a68..e3797aeaad6a 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -1939,7 +1939,7 @@ def with_unpacked_kwargs(self) -> NormalizedCallableType: if not self.unpack_kwargs: return NormalizedCallableType(self.copy_modified()) last_type = get_proper_type(self.arg_types[-1]) - assert isinstance(last_type, ProperType) and isinstance(last_type, TypedDictType) + assert isinstance(last_type, TypedDictType) extra_kinds = [ ArgKind.ARG_NAMED if name in last_type.required_keys else ArgKind.ARG_NAMED_OPT for name in last_type.items diff --git a/mypy_self_check.ini b/mypy_self_check.ini index 39c97e625880..0852fd82cf47 100644 --- a/mypy_self_check.ini +++ b/mypy_self_check.ini @@ -11,4 +11,4 @@ always_false = MYPYC plugins = misc/proper_plugin.py python_version = 3.7 exclude = mypy/typeshed/|mypyc/test-data/|mypyc/lib-rt/ -enable_error_code = ignore-without-code +enable_error_code = ignore-without-code,redundant-expr