Repository: python/mypy

Issue:
mypy doesn't warn when arguments are type annotated but the return type isn't annotated
I had a function that passed mypy checks when it shouldn't:
```

 40
 41 async def lol(app: App):
 42     return 1
```

This function should generate a warning that it's untyped.

my config.ini:

```
[mypy]
python_version = 3.6
# otherwise mypy complains about modules without stubs
ignore_missing_imports = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_no_return = True
strict_optional = True
show_traceback = True
show_column_numbers = True
no_implicit_optional = True
disallow_incomplete_defs = True
disallow_untyped_defs = True
disallow_any = generics
```


Discussion:
adding to nosy list (@JelleZijlstra)
Confirmed -- looks like `disallow_incomplete_defs = True` isn't honored for `async def`.

Resolving patch:
diff --git a/mypy/checker.py b/mypy/checker.py
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -789,7 +789,11 @@ def is_unannotated_any(t: Type) -> bool:
             if fdef.type is None and self.options.disallow_untyped_defs:
                 self.fail(messages.FUNCTION_TYPE_EXPECTED, fdef)
             elif isinstance(fdef.type, CallableType):
-                if is_unannotated_any(fdef.type.ret_type):
+                ret_type = fdef.type.ret_type
+                if is_unannotated_any(ret_type):
+                    self.fail(messages.RETURN_TYPE_EXPECTED, fdef)
+                elif (fdef.is_coroutine and isinstance(ret_type, Instance) and
+                      is_unannotated_any(ret_type.args[0])):
                     self.fail(messages.RETURN_TYPE_EXPECTED, fdef)
                 if any(is_unannotated_any(t) for t in fdef.type.arg_types):
                     self.fail(messages.ARGUMENT_TYPE_EXPECTED, fdef)


Test patch:
diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test
--- a/test-data/unit/check-flags.test
+++ b/test-data/unit/check-flags.test
@@ -10,12 +10,6 @@ def f(x) -> int: pass
 [out]
 main:2: error: Function is missing a type annotation for one or more arguments
 
-[case testUnannotatedArgumentWithFastParser]
-# flags: --disallow-untyped-defs
-def f(x) -> int: pass
-[out]
-main:2: error: Function is missing a type annotation for one or more arguments
-
 [case testNoArgumentFunction]
 # flags: --disallow-untyped-defs
 def f() -> int: pass
@@ -45,6 +39,31 @@ def f():
 [out]
 main:2: error: Function is missing a type annotation
 
+[case testUntypedAsyncDef]
+# flags: --disallow-untyped-defs
+async def f():  # E: Function is missing a type annotation
+    pass
+[builtins fixtures/async_await.pyi]
+[typing fixtures/typing-full.pyi]
+
+[case testAsyncUnannotatedArgument]
+# flags: --disallow-untyped-defs
+async def f(x) -> None:  # E: Function is missing a type annotation for one or more arguments
+    pass
+[builtins fixtures/async_await.pyi]
+[typing fixtures/typing-full.pyi]
+
+[case testAsyncUnannotatedReturn]
+# flags: --disallow-untyped-defs
+from typing import Any
+async def f(x: int):  # E: Function is missing a return type annotation
+    pass
+# Make sure explicit Any is allowed.
+async def g(x: int) -> Any:
+    pass
+[builtins fixtures/async_await.pyi]
+[typing fixtures/typing-full.pyi]
+
 [case testDisallowUntypedDefsUntypedDecorator]
 # flags: --disallow-untyped-decorators
 def d(p):