From 1541653e55b4b7e7367dd14bd963f12895aa491a Mon Sep 17 00:00:00 2001 From: malkarjun <145407983+malkarjun@users.noreply.github.com> Date: Thu, 2 Oct 2025 17:39:48 -0400 Subject: [PATCH 1/2] errorcodes: added optional code missing-return-annotation and enforce in semantic analysis file; added tests as well --- mypy/errorcodes.py | 7 +++++++ mypy/semanal.py | 21 ++++++++++++++++++- .../unit/check-missing-return-annotation.test | 8 +++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test-data/unit/check-missing-return-annotation.test diff --git a/mypy/errorcodes.py b/mypy/errorcodes.py index a96f5f723a7d2..810ae7b3f351d 100644 --- a/mypy/errorcodes.py +++ b/mypy/errorcodes.py @@ -319,5 +319,12 @@ def __hash__(self) -> int: default_enabled=False, ) +MISSING_RETURN_ANNOTATION = ErrorCode( + "missing-return-annotation", + "Function has no return type annotation", + "Optional", +) + + # This copy will not include any error codes defined later in the plugins. mypy_error_codes = error_codes.copy() diff --git a/mypy/semanal.py b/mypy/semanal.py index 17dc9bfadc1f2..37913a2967652 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -57,7 +57,7 @@ from mypy import errorcodes as codes, message_registry from mypy.constant_fold import constant_fold_expr -from mypy.errorcodes import PROPERTY_DECORATOR, ErrorCode +from mypy.errorcodes import PROPERTY_DECORATOR, ErrorCode, MISSING_RETURN_ANNOTATION from mypy.errors import Errors, report_internal_error from mypy.exprtotype import TypeTranslationError, expr_to_unanalyzed_type from mypy.message_registry import ErrorMessage @@ -926,6 +926,25 @@ def visit_func_def(self, defn: FuncDef) -> None: with self.inside_except_star_block_set(value=False): self.analyze_func_def(defn) + # Missing return annotation check (optional error code) + from mypy.types import CallableType + + if ( + # Makes sure return type is not specified, ignores lambdas and special cases + isinstance(defn.type, CallableType) + and defn.type.ret_type is None + and any(arg.type_annotation is not None for arg in defn.arguments) + and defn.name != "__init__" + and not defn.is_lambda + and not defn.is_overload + ): + self.msg.fail( + f'Function "{defn.name}" has no return type annotation', + defn, + code=MISSING_RETURN_ANNOTATION, + ) + + def function_fullname(self, fullname: str) -> str: if self.current_overload_item is None: return fullname diff --git a/test-data/unit/check-missing-return-annotation.test b/test-data/unit/check-missing-return-annotation.test new file mode 100644 index 0000000000000..1c4d74fe60132 --- /dev/null +++ b/test-data/unit/check-missing-return-annotation.test @@ -0,0 +1,8 @@ +[case test_missing_return_annotation_ok] +# flags: --enable-error-code missing-return-annotation +def g(x: int) -> int: + return x + +[case test_missing_return_annotation_off_by_default] +def h(x: int): + return x # no error expected, since code is opt-in From 671e083205e764c2453f601e51c43250910dcb37 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 21:56:59 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/errorcodes.py | 4 +--- mypy/semanal.py | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/mypy/errorcodes.py b/mypy/errorcodes.py index 810ae7b3f351d..87c6057449602 100644 --- a/mypy/errorcodes.py +++ b/mypy/errorcodes.py @@ -320,9 +320,7 @@ def __hash__(self) -> int: ) MISSING_RETURN_ANNOTATION = ErrorCode( - "missing-return-annotation", - "Function has no return type annotation", - "Optional", + "missing-return-annotation", "Function has no return type annotation", "Optional" ) diff --git a/mypy/semanal.py b/mypy/semanal.py index 37913a2967652..792ab35c79bd6 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -57,7 +57,7 @@ from mypy import errorcodes as codes, message_registry from mypy.constant_fold import constant_fold_expr -from mypy.errorcodes import PROPERTY_DECORATOR, ErrorCode, MISSING_RETURN_ANNOTATION +from mypy.errorcodes import MISSING_RETURN_ANNOTATION, PROPERTY_DECORATOR, ErrorCode from mypy.errors import Errors, report_internal_error from mypy.exprtotype import TypeTranslationError, expr_to_unanalyzed_type from mypy.message_registry import ErrorMessage @@ -943,7 +943,6 @@ def visit_func_def(self, defn: FuncDef) -> None: defn, code=MISSING_RETURN_ANNOTATION, ) - def function_fullname(self, fullname: str) -> str: if self.current_overload_item is None: