Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5720,8 +5720,7 @@ def visit_decorator_inner(
) -> None:
# Fix the type if decorated with `@types.coroutine` or `@asyncio.coroutine`.
defn = e.func
if defn.is_awaitable_coroutine:
assert isinstance(defn.type, CallableType)
if defn.is_awaitable_coroutine and isinstance(defn.type, CallableType):
# Update the return type to AwaitableGenerator (unless we already did).
# Note, this doesn't exist in typing.py, only in typing.pyi.
if not is_named_instance(defn.type.ret_type, "typing.AwaitableGenerator"):
Expand All @@ -5745,6 +5744,22 @@ def visit_decorator_inner(
with self.tscope.function_scope(e.func), self.set_recurse_into_functions():
self.check_func_item(e.func, name=e.func.name, allow_empty=allow_empty)

# For unannotated functions, defn.type is only available after check_func_item
# infers it. Apply the AwaitableGenerator wrapping now if it wasn't done above.
if defn.is_awaitable_coroutine and isinstance(defn.type, CallableType):
if not is_named_instance(defn.type.ret_type, "typing.AwaitableGenerator"):
t = defn.type.ret_type
c = defn.is_coroutine
ty = self.get_generator_yield_type(t, c)
tc = self.get_generator_receive_type(t, c)
if c:
tr = self.get_coroutine_return_type(t)
else:
tr = self.get_generator_return_type(t, c)
ret_type = self.named_generic_type("typing.AwaitableGenerator", [ty, tc, tr, t])
typ = defn.type.copy_modified(ret_type=ret_type)
defn.type = typ
Comment on lines +5747 to +5761
Comment on lines +5747 to +5761

# Process decorators from the inside out to determine decorated signature, which
# may be different from the declared signature.
sig: Type = self.function_type(e.func)
Expand Down
Loading