The types.coroutine decorator for Python 3.6 (and I suspect for Python 3.6.1 as well) simply monkey patches the function it's passed and then returns it. This results in behavior that I found somewhat surprising. def bar(): yield 5 foo = types.coroutine(bar) foo is bar And, so now both foo and bar are now awaitable. I wasn't really expecting this, and while it's minor, it also doesn't really seem like the right thing to do.
Yes, that looks wrong to me. IMO it should be returning a new function object, not updating the __code__ of the existing object. I couldn't figure when that is actually triggered, though. There are also some other oddnesses, given the definition of 'coroutine' in the 'types' module docs. type(x) returns 'coroutine' only when you actually *call* the async def function. I think that's correct, but the docs need rewording. However, if I call coroutine on the equivalent non-async-def generator, types(x()) returns generator, not coroutine. So it doesn't seem to be doing what it says on the label, at least not in all cases.