This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Async list comprehension (PEP 530) causes SyntaxError in Python 3.6.3
Type: Stage: resolved
Components: asyncio Versions: Python 3.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: cannedrag, yselivanov, zach.ware
Priority: normal Keywords:

Created on 2017-10-20 23:08 by cannedrag, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (6)
msg304688 - (view) Author: Roel van der Goot (cannedrag) * Date: 2017-10-20 23:08
$ python3
Python 3.6.3 (default, Oct  3 2017, 21:45:48) 
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> async def arange(n):
...     for i in range(n):
...         yield i
... 
>>> [i async for i in arange(10)]
  File "<stdin>", line 1
    [i async for i in arange(10)]
           ^
SyntaxError: invalid syntax
>>>
msg304689 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2017-10-20 23:31
Your async listcomp must also be defined within a coroutine to turn `async` into a keyword in 3.6.  The following is far from best practice (don't do this, I don't know what I'm doing! :), but at least it compiles and shows that it works:

async def arange(n):
    for i in range(n):
        yield i

async def alistcomp():
    return [i async for i in arange(10)]

try:
    next(alistcomp().__await__())
except StopIteration as e:
    value = e.value

print(value)
msg304690 - (view) Author: Roel van der Goot (cannedrag) * Date: 2017-10-20 23:45
Zachary,

Thank you for your response. I had the impression that async comprehensions are a bridge between async functions and non-async functions. Is there a wat to use async (and asyncio) and then go back to regular python? Or am I just wishful thinking? :-)

For example, it would be nice to start multiple processes through asyncio.create_subprocess_exec (or _shell) await twice and then process all the output in "traditional" (i.e., non-async) Python.

Cheers :),
Cannedrag
msg304692 - (view) Author: Roel van der Goot (cannedrag) * Date: 2017-10-21 00:44
I have been thinking about my previous comment a bit more. For consistency there should at least be an await somewhere to move back from async land to non-async land.

For example:

    #!/usr/bin/env python3

    import asyncio

    async def main():
        cmds = [['ssh', 'user@host', 'echo {}'.format(i)] for i in range(4)]
        creations = [asyncio.create_subprocess_exec(*cmd, 
                stdout=asyncio.subprocess.PIPE, 
                stderr=asyncio.subprocess.PIPE)
                    for cmd in cmds]
        processes = [await creation for creation in creations]
        outputs = [await process.communicate() for process in processes]
        print(outputs)
    
    if __name__ == '__main__':
        event_loop = asyncio.get_event_loop()
        event_loop.run_until_complete(main())

prints

    [(b'0\n', b''), (b'1\n', b''), (b'2\n', b''), (b'3\n', b'')]

It would be nice if you could somehow return outputs from main() and process the results in a non-async function. There are no async concepts left in outputs after all. But I am not aware of a way you can do this in Python currently.
msg304693 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2017-10-21 03:19
That's already provided, just do `return outputs` instead of `print(outputs)`, and `outputs = event_loop.run_until_complete(main())`.  See https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_until_complete
msg304694 - (view) Author: Roel van der Goot (cannedrag) * Date: 2017-10-21 03:58
Thank you!
History
Date User Action Args
2022-04-11 14:58:53adminsetgithub: 76013
2017-10-21 03:58:39cannedragsetmessages: + msg304694
2017-10-21 03:19:19zach.waresetmessages: + msg304693
2017-10-21 00:44:17cannedragsetmessages: + msg304692
2017-10-20 23:45:58cannedragsetmessages: + msg304690
2017-10-20 23:31:13zach.waresetstatus: open -> closed

nosy: + zach.ware
messages: + msg304689

resolution: not a bug
stage: resolved
2017-10-20 23:08:38cannedragcreate