diff --git a/build-requirements.txt b/build-requirements.txt index 0bf40e3c03e8..d1a3a04dc832 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.8,<1.6.0 +types-typed-ast>=1.5.0,<1.6.0 diff --git a/mypy/build.py b/mypy/build.py index 41b1be28598b..f5ebdf52d941 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -1292,15 +1292,11 @@ 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 # type: ignore[redundant-expr] - or m.size is None # type: ignore[redundant-expr] - or m.dependencies is None # type: ignore[redundant-expr] + or m.mtime is None + or m.size is None + or m.dependencies is None 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 1f4cb8bc7b3a..1eb9ab9e8626 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1313,7 +1313,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 fdef.info.is_metaclass(): + if isinstance(fdef.info, TypeInfo) and fdef.info.is_metaclass(): # This is a metaclass, so it must return a new unrelated type. self.check_subtype( bound_type.ret_type, @@ -1901,7 +1901,7 @@ def check_override( ): fail = True op_method_wider_note = True - if isinstance(override, FunctionLike): + if isinstance(original, FunctionLike) and isinstance(override, FunctionLike): if original_class_or_static and not override_class_or_static: fail = True elif isinstance(original, CallableType) and isinstance(override, CallableType): @@ -2804,8 +2804,12 @@ 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 lvalue_node.allow_incompatible_override and not ( - lvalue_node.name == "__slots__" and base.fullname == "builtins.object" + if ( + isinstance(lvalue_node, Var) + and 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 5acef28310fb..25f22df2cd45 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -310,7 +310,7 @@ def analyze_instance_member_access( # the first argument. pass else: - if name != "__call__": + if isinstance(signature, FunctionLike) and 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 95eff523041d..77c9cb50bc98 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 len(stmt.else_body.body) == 1: + if isinstance(stmt.else_body, Block) and 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,11 +901,13 @@ 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: list[Type] = TypeConverter( + translated_args = TypeConverter( self.errors, line=lineno, override_column=n.col_offset ).translate_expr_list(func_type_ast.argtypes) - # Use a cast to work around `list` invariance - arg_types = cast(List[Optional[Type]], translated_args) + arg_types = [ + a if a is not None else AnyType(TypeOfAny.unannotated) + for a in 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 e5c2cb372cc6..a3d1f1afe0dd 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -2486,7 +2486,11 @@ 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 hasattr(tp.definition, "arguments"): + if ( + isinstance(tp.definition, FuncDef) + and tp.definition.name is not None + 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) @@ -2680,7 +2684,7 @@ def find_defining_module(modules: dict[str, MypyFile], typ: CallableType) -> Myp if not typ.definition: return None fullname = typ.definition.fullname - if "." in fullname: + if fullname is not None and "." 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 98fa54c0cd36..014550cc96aa 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -3580,10 +3580,7 @@ def serialize(self, prefix: str, name: str) -> JsonDict: if prefix is not None: fullname = self.node.fullname if ( - # 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] + fullname is not None 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 9e1e156236f2..f51c98721eb0 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 cur_indent > start_indent: + elif start_indent is not None and 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 65b883793907..3b281194d537 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -5892,7 +5892,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 not isinstance(current_func, LambdaExpr): + if isinstance(current_func, FuncItem) and 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 ffd4d48bb458..84148167012f 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 is_overload: + elif overload_chain and 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,7 +725,9 @@ def visit_func_def( retname = None # implicit Any else: retname = self.print_annotation(o.unanalyzed_type.ret_type) - elif o.abstract_status == IS_ABSTRACT or o.name in METHODS_WITH_RETURN_VALUE: + elif isinstance(o, FuncDef) and ( + 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 70b96c9781fc..4f1e9d8460dd 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 ( + if isinstance(x, str) and ( 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 634649c973e5..48e1695d0278 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 != -1 and map[node]: + if node.line is not None and 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 d82b511f7d5a..fbbbb92a81d1 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, TypedDictType) + assert isinstance(last_type, ProperType) and 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 0852fd82cf47..39c97e625880 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,redundant-expr +enable_error_code = ignore-without-code