PEP 492 and types.coroutine
According to https://www.python.org/dev/peps/pep-0492/#id31: The [types.coroutine] function applies CO_COROUTINE flag to generator-function's code object, making it return a coroutine object. Further down in https://www.python.org/dev/peps/pep-0492/#id32: [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 add a flag to a generator object so that await will accept it. This raises the question of why can't await simply accept a generator object? There is no code change to the gen obj itself, there is no behavior change in the gen obj, it's the exact same byte code, only a flag is different. types.coroutine feels a lot like unnecessary boiler-plate. -- ~Ethan~
On 2015-05-02 1:04 PM, Ethan Furman wrote:
According to https://www.python.org/dev/peps/pep-0492/#id31:
The [types.coroutine] function applies CO_COROUTINE flag to generator-function's code object, making it return a coroutine object.
Further down in https://www.python.org/dev/peps/pep-0492/#id32:
[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 add a flag to a generator object so that await will accept it.
This raises the question of why can't await simply accept a generator object? There is no code change to the gen obj itself, there is no behavior change in the gen obj, it's the exact same byte code, only a flag is different.
Because 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
On 05/02, Yury Selivanov wrote:
On 2015-05-02 1:04 PM, Ethan Furman wrote:
If I'm understanding this correctly, type.coroutine's only purpose is to add a flag to a generator object so that await will accept it.
This raises the question of why can't await simply accept a generator object? There is no code change to the gen obj itself, there is no behavior change in the gen obj, it's the exact same byte code, only a flag is different.
Because 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.
And 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."
'types.coroutine' is something that we need to ease transition to the new syntax.
This doesn't make sense -- either the existing generators are correctly returning coroutines, in which case the decorator adds nothing, or they are returning non-coroutines, in which case the decorator adds nothing. So either way, nothing has been added besides a mandatory boiler-plate requirement. -- ~Ethan~
On 2015-05-02 2:14 PM, Ethan Furman wrote:
On 05/02, Yury Selivanov wrote:
On 2015-05-02 1:04 PM, Ethan Furman wrote:
If I'm understanding this correctly, type.coroutine's only purpose is to add a flag to a generator object so that await will accept it.
This raises the question of why can't await simply accept a generator object? There is no code change to the gen obj itself, there is no behavior change in the gen obj, it's the exact same byte code, only a flag is different. Because 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. And 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.
This is a flaw in the current Python that we want to fix.
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."
Well, why would you use it on some generator that is not a generator-based coroutine?
'types.coroutine' is something that we need to ease transition to the new syntax. This doesn't make sense -- either the existing generators are correctly returning coroutines, in which case the decorator adds nothing, or they are returning non-coroutines, in which case the decorator adds nothing.
So either way, nothing has been added besides a mandatory boiler-plate requirement.
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 05/02, Yury Selivanov wrote:
On 2015-05-02 2:14 PM, Ethan Furman wrote:
On 05/02, Yury Selivanov wrote:
On 2015-05-02 1:04 PM, Ethan Furman wrote:
And 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.
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 with type.coroutine and it will still be broken and a bug in my code.
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."
Well, why would you use it on some generator that is not a generator-based coroutine?
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.
So either way, nothing has been added besides a mandatory boiler-plate requirement.
It's not nothing; it's backwards compatibility. Please read https://www.python.org/dev/peps/pep-0492/#await-expression
I have read it, more than once. If you lift the (brand-new) requirement that a generator must be decorated, then type.coroutine becomes optional (no more useful, just optional). It is not a current requirement that coroutine generators be decorated. -- ~Ethan~
Ethan, at this point your continued arguing is not doing anybody anything
good. Please stop.
On Sat, May 2, 2015 at 2:31 PM, Ethan Furman
On 05/02, Yury Selivanov wrote:
On 2015-05-02 2:14 PM, Ethan Furman wrote:
On 05/02, Yury Selivanov wrote:
On 2015-05-02 1:04 PM, Ethan Furman wrote:
And 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.
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 with type.coroutine and it will still be broken and a bug in my code.
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."
Well, why would you use it on some generator that is not a generator-based coroutine?
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.
So either way, nothing has been added besides a mandatory boiler-plate requirement.
It's not nothing; it's backwards compatibility. Please read https://www.python.org/dev/peps/pep-0492/#await-expression
I have read it, more than once. If you lift the (brand-new) requirement that a generator must be decorated, then type.coroutine becomes optional (no more useful, just optional). It is not a current requirement that coroutine generators be decorated.
-- ~Ethan~ _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (python.org/~guido)
participants (3)
-
Ethan Furman
-
Guido van Rossum
-
Yury Selivanov