diff --git a/docs/source/error_code_list2.rst b/docs/source/error_code_list2.rst index f160515f0a9e..673ac62b5058 100644 --- a/docs/source/error_code_list2.rst +++ b/docs/source/error_code_list2.rst @@ -62,6 +62,21 @@ Example: def __init__(self) -> None: self.value = 0 +Check that every function has a return annotation [no-incomplete-def] +--------------------------------------------------------------------- + +If you use :option:`--disallow-incomplete-defs `, mypy requires that all functions +fully annotated. + +Example: + +.. code-block:: python + + # mypy: disallow-incomplete-defs + + def example(x: int): # Error: Function is missing a return type annotation [no-incomplete-def] + pass + Check that cast is not redundant [redundant-cast] ------------------------------------------------- diff --git a/mypy/checker.py b/mypy/checker.py index 09dc0a726b99..bc4be0411ac6 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1401,7 +1401,9 @@ def is_unannotated_any(t: Type) -> bool: self.fail(message_registry.FUNCTION_TYPE_EXPECTED, fdef) elif isinstance(fdef.type, CallableType): ret_type = get_proper_type(fdef.type.ret_type) - if is_unannotated_any(ret_type): + if is_unannotated_any(ret_type) and check_incomplete_defs: + self.fail(message_registry.RETURN_TYPE_EXPECTED_INCOMPLETE_DEF, fdef) + elif is_unannotated_any(ret_type): self.fail(message_registry.RETURN_TYPE_EXPECTED, fdef) elif fdef.is_generator: if is_unannotated_any( @@ -1411,7 +1413,12 @@ def is_unannotated_any(t: Type) -> bool: elif fdef.is_coroutine and isinstance(ret_type, Instance): if is_unannotated_any(self.get_coroutine_return_type(ret_type)): self.fail(message_registry.RETURN_TYPE_EXPECTED, fdef) - if any(is_unannotated_any(t) for t in fdef.type.arg_types): + if ( + any(is_unannotated_any(t) for t in fdef.type.arg_types) + and check_incomplete_defs + ): + self.fail(message_registry.ARGUMENT_TYPE_EXPECTED_INCOMPLETE_DEF, fdef) + elif any(is_unannotated_any(t) for t in fdef.type.arg_types): self.fail(message_registry.ARGUMENT_TYPE_EXPECTED, fdef) def check___new___signature(self, fdef: FuncDef, typ: CallableType) -> None: diff --git a/mypy/errorcodes.py b/mypy/errorcodes.py index d274bb6dd5f0..a066635341e3 100644 --- a/mypy/errorcodes.py +++ b/mypy/errorcodes.py @@ -223,6 +223,11 @@ def __str__(self) -> str: ) +NO_INCOMPLETE_DEF: Final[ErrorCode] = ErrorCode( + "no-incomplete-def", "Function is missing a return type annotation", "General" +) + + # Syntax errors are often blocking. SYNTAX: Final[ErrorCode] = ErrorCode("syntax", "Report syntax errors", "General") diff --git a/mypy/message_registry.py b/mypy/message_registry.py index b32edc06571a..d3e282fa3825 100644 --- a/mypy/message_registry.py +++ b/mypy/message_registry.py @@ -119,9 +119,15 @@ def with_additional_msg(self, info: str) -> ErrorMessage: RETURN_TYPE_EXPECTED: Final = ErrorMessage( "Function is missing a return type annotation", codes.NO_UNTYPED_DEF ) +RETURN_TYPE_EXPECTED_INCOMPLETE_DEF: Final = ErrorMessage( + "Function is missing a return type annotation", codes.NO_INCOMPLETE_DEF +) ARGUMENT_TYPE_EXPECTED: Final = ErrorMessage( "Function is missing a type annotation for one or more arguments", codes.NO_UNTYPED_DEF ) +ARGUMENT_TYPE_EXPECTED_INCOMPLETE_DEF: Final = ErrorMessage( + "Function is missing a type annotation for one or more arguments", codes.NO_INCOMPLETE_DEF +) KEYWORD_ARGUMENT_REQUIRES_STR_KEY_TYPE: Final = ErrorMessage( 'Keyword argument only valid with "str" key type in call to "dict"' ) diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 33c8f7365375..34f22ee2399c 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -379,6 +379,15 @@ def f() -> None: def g(): pass +[case testErrorCodeNoReturnAnnotation] +# flags: --disallow-incomplete-defs + +def f(i: int): # E: Function is missing a return type annotation [no-incomplete-def] + pass + +def g(i) -> None: # E: Function is missing a type annotation for one or more arguments [no-incomplete-def] + pass + [case testErrorCodeIndexing] from typing import Dict x: Dict[int, int]