diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 8b40fbb59278..ad227d98a080 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4434,12 +4434,14 @@ def check_op( recent_context.line = err.line recent_context.column = err.column if len(left_variants) >= 2 and len(right_variants) >= 2: - self.msg.warn_both_operands_are_from_unions(recent_context) + self.msg.warn_both_operands_are_from_unions(recent_context, parent_error=err) elif len(left_variants) >= 2: - self.msg.warn_operand_was_from_union("Left", base_type, context=recent_context) + self.msg.warn_operand_was_from_union( + "Left", base_type, context=recent_context, parent_error=err + ) elif len(right_variants) >= 2: self.msg.warn_operand_was_from_union( - "Right", right_type, context=recent_context + "Right", right_type, context=recent_context, parent_error=err ) # See the comment in 'check_overload_call' for more details on why diff --git a/mypy/errors.py b/mypy/errors.py index e95904ce355e..ba3fc367f723 100644 --- a/mypy/errors.py +++ b/mypy/errors.py @@ -809,7 +809,7 @@ def add_error_info(self, info: ErrorInfo, *, file: str | None = None) -> None: self.report_hidden_errors(file, info) self._add_error_info(file, info) ignored_codes = self.ignored_lines.get(file, {}).get(info.line, []) - if ignored_codes and info.code: + if ignored_codes and info.code and info.severity == "error": # Something is ignored on the line, but not this error, so maybe the error # code is incorrect. msg = f"""Error code "{info.code.code}" not covered by "type: ignore[{', '.join(ignored_codes)}]" comment""" diff --git a/mypy/messages.py b/mypy/messages.py index 0f3a5be368a4..df247cf02066 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -1775,14 +1775,24 @@ def overloaded_signatures_ret_specific(self, index: int, context: Context) -> No context, ) - def warn_both_operands_are_from_unions(self, context: Context) -> None: - self.note("Both left and right operands are unions", context, code=codes.OPERATOR) + def warn_both_operands_are_from_unions( + self, context: Context, parent_error: ErrorInfo | None = None + ) -> None: + self.note( + "Both left and right operands are unions", + context, + code=codes.OPERATOR if parent_error is None else None, + parent_error=parent_error, + ) - def warn_operand_was_from_union(self, side: str, original: Type, context: Context) -> None: + def warn_operand_was_from_union( + self, side: str, original: Type, context: Context, parent_error: ErrorInfo | None = None + ) -> None: self.note( f"{side} operand is of type {format_type(original, self.options)}", context, - code=codes.OPERATOR, + code=codes.OPERATOR if parent_error is None else None, + parent_error=parent_error, ) def operator_method_signatures_overlap( diff --git a/test-data/unit/check-ignore.test b/test-data/unit/check-ignore.test index 9a30490e8833..2e78617e8349 100644 --- a/test-data/unit/check-ignore.test +++ b/test-data/unit/check-ignore.test @@ -418,3 +418,15 @@ y # mypy: ignore[assignment] # type: ignore [out] main:1: error: Unrecognized error code "whatever" main:1: note: Error code "misc" not covered by "type: ignore[whatever]" comment + +[case testIgnoreOperatorNoteWithDifferentErrorCode] +# flags: --warn-unused-ignores +class OnlyA: + def __call__(self, other: "A") -> bool: + return True + +class A: + __le__ = OnlyA() + +def f(x: A, y: A | int) -> None: + x <= y # type: ignore[arg-type]