[await] uses the yield from implementation with an extra step of validating its argument. await only accepts an awaitable, which can be one of:

...

- A generator-based coroutine object returned from a generator decorated with types.coroutine().

If I'm understanding this correctly, type.coroutine's only purpose is to adda flag to a generator object so that await will accept it.

This raises the question of why can't await simply accept a generatorobject? There is no code change to the gen obj itself, there is nobehavior change in the gen obj, it's the exact same byte code, only aflag is different.

Search Discussions

Yury SelivanovBecause we don't want 'await' to accept random generators. It can't do anything meaningful with them, in a world where all asyncio code is written with new syntax, passing generator to 'await' is just a bug. 'types.coroutine' is something that we need to ease transition to the new syntax. Yury

[await] uses the yield from implementation with an extra step ofvalidating its argument. await only accepts an awaitable,which can be one of:

...

- A generator-based coroutine object returned from a generatordecorated with types.coroutine().

If I'm understanding this correctly, type.coroutine's only purpose is to adda flag to a generator object so that await will accept it.

This raises the question of why can't await simply accept a generatorobject? There is no code change to the gen obj itself, there is nobehavior change in the gen obj, it's the exact same byte code, only aflag is different.

Because we don't want 'await' to accept random generators.It can't do anything meaningful with them, in a world whereall asyncio code is written with new syntax, passing generatorto 'await' is just a bug.

'types.coroutine' is something that we need to ease transitionto the new syntax.

Ethan FurmanAnd yet in current asyncio code, random generators can be accepted, and not even the current asyncio.coroutine wrapper can gaurantee that the generator is a coroutine in fact. For that matter, even the new types.coroutine cannot gaurantee that the returned object is a coroutine and not a generator -- so basically it's just there to tell the compiler, "yeah, I really know what I'm doing, shut up and do what I asked." This doesn't make sense -- either the existing generators are correctly

If I'm understanding this correctly, type.coroutine's only purpose is to adda flag to a generator object so that await will accept it.

This raises the question of why can't await simply accept a generatorobject? There is no code change to the gen obj itself, there is nobehavior change in the gen obj, it's the exact same byte code, only aflag is different.

Because we don't want 'await' to accept random generators.It can't do anything meaningful with them, in a world whereall asyncio code is written with new syntax, passing generatorto 'await' is just a bug.

And yet in current asyncio code, random generators can be accepted, and noteven the current asyncio.coroutine wrapper can gaurantee that the generatoris a coroutine in fact.

For that matter, even the new types.coroutine cannot gaurantee that thereturned object is a coroutine and not a generator -- so basically it's justthere to tell the compiler, "yeah, I really know what I'm doing, shut up anddo what I asked."

'types.coroutine' is something that we need to ease transitionto the new syntax.

This doesn't make sense -- either the existing generators are correctlyreturning coroutines, in which case the decorator adds nothing, or theyare returning non-coroutines, in which case the decorator adds nothing.

So either way, nothing has been added besides a mandatory boiler-platerequirement.

Yury SelivanovThis is a flaw in the current Python that we want to fix. Well, why would you use it on some generator that is not a generator-based coroutine? It's not nothing; it's backwards compatibility. Please read https://www.python.org/dev/peps/pep-0492/#await-expression @types.coroutine marks generator function that its generator is awaitable. Yury

On 2015-05-02 1:04 PM, Ethan Furman wrote:If I'm understanding this correctly, type.coroutine's only purpose is to adda flag to a generator object so that await will accept it.

This raises the question of why can't await simply accept a generatorobject? There is no code change to the gen obj itself, there is nobehavior change in the gen obj, it's the exact same byte code, only aflag is different.

Because we don't want 'await' to accept random generators.It can't do anything meaningful with them, in a world whereall asyncio code is written with new syntax, passing generatorto 'await' is just a bug.

And yet in current asyncio code, random generators can be accepted, and noteven the current asyncio.coroutine wrapper can gaurantee that the generatoris a coroutine in fact.

This is a flaw in the current Python that we want to fix.

For that matter, even the new types.coroutine cannot gaurantee that thereturned object is a coroutine and not a generator -- so basically it's justthere to tell the compiler, "yeah, I really know what I'm doing, shut up anddo what I asked."

Well, why would you use it on some generator that is nota generator-based coroutine?

'types.coroutine' is something that we need to ease transitionto the new syntax.

This doesn't make sense -- either the existing generators are correctlyreturning coroutines, in which case the decorator adds nothing, or theyare returning non-coroutines, in which case the decorator adds nothing.

So either way, nothing has been added besides a mandatory boiler-platerequirement.

Ethan FurmanYour "fix" doesn't fix it. I can decorate a non-coroutine generator with type.coroutine and it will still be broken and a bug in my code. I wouldn't, that would be a bug; but decorating a wrong type of generator is still a bug, and type.coroutine has not fixed that bug. It's worse than mandatory typing because it can't even check that what I have declared is true. I have read it, more than once. If you lift the (brand-new) requirement that a generator must be decorated, then type.coroutine

And yet in current asyncio code, random generators can be accepted, and noteven the current asyncio.coroutine wrapper can gaurantee that the generatoris a coroutine in fact.

This is a flaw in the current Python that we want to fix.

Your "fix" doesn't fix it. I can decorate a non-coroutine generator withtype.coroutine and it will still be broken and a bug in my code.

For that matter, even the new types.coroutine cannot gaurantee that thereturned object is a coroutine and not a generator -- so basically it's justthere to tell the compiler, "yeah, I really know what I'm doing, shut up anddo what I asked."

Well, why would you use it on some generator that is nota generator-based coroutine?

I wouldn't, that would be a bug; but decorating a wrong type of generator isstill a bug, and type.coroutine has not fixed that bug.

It's worse than mandatory typing because it can't even check that what I havedeclared is true.

So either way, nothing has been added besides a mandatory boiler-platerequirement.

I have read it, more than once. If you lift the (brand-new) requirement that agenerator must be decorated, then type.coroutine becomes optional (no moreuseful, just optional). It is not a current requirement that coroutinegenerators be decorated.

I have read it, more than once. If you lift the (brand-new) requirementthat agenerator must be decorated, then type.coroutine becomes optional (no moreuseful, just optional). It is not a current requirement that coroutinegenerators be decorated.