New submission from Matthias Bussonnier <bussonniermatth...@gmail.com>:

Hi, 

This is an issue, prompted by twitter 
(https://twitter.com/Mbussonn/status/1038866329971961859) and by the imminent 
release of IPython 7.0 that provides an async REPL to discuss the introducion 
of something I'll call "Async exec", the exact form can vary, but I believe the 
name si relatively self explanatory. 

The short description would be to allow something akin to `exec` but for 
asynchronous code. Typically for one to be able to write an async-repl in the 
generic sens that is not say not obviously liked to asyncio.

For example IPython 7.0 (current master branch) allow the following:

```

In [1]: import asyncio, trio, curio

In [2]: await asyncio.sleep(0)

In [3]: %autoawait trio

In [4]: await trio.sleep(0)

In [5]: %autoawait curio

In [6]: await curio.sleep(0)
Out[6]: 30980.70591396
```


Sleep is here and example, but you can play with aoihttp, asks, and other 
library and it "just works". Alternatively when using IPython via Jupyter, you 
can also schedule background tasks that will execute in the currently running 
loop. 

To reach this, we had to work around a large number of roadblock, and there is 
a number of missing pieces (or things especially prevented) in core Python we 
had to work around. To see how we did that see 
https://github.com/ipython/ipython/pull/11265

The core being if we have a block of async code like `await sleep(0)`, we need 
an asynchronous way to exec it without blocking, hence the proposal for 
async-exec.

During the development and test of the above feature of IPython here are some 
of the challenges we got with top-level async code. 

1) top-level async is invalid syntax. 

It make sens for a module for this to be invalid syntax, but not in a repl.
Since Python 3.7 we can (at least) compile it to AST, but not to bytecode.

2) It would also be extremely convenient to have a util function to tell you 
whether what you just compiled need to be ran async or not, from Source Code, 
ast tree, code object. It's surprisingly not trivial to get it always right.

So far in IPython we have to carry-over and recompute whether to actually run 
the compiled byte code in classical `exec` or our pseudo async-exec. You may 
think that `await exec()` always cover the case, but when you are already 
running under asyncio, you may want to tell user "no you can't run async code", 
and use the normal `exec` path.


3) Have  distinction in this `async exec`/`compile` between "I am compiling a 
module", currently `exec` mode for both exec and compile, and a "I'm compiling 
a _multiline_ interactive statement".

4) Not be coupled to a specific async library.

Allow new AIO library like trio/curio/... to use this.

Note that despite both using IPython, the above cover 2 use cases. 
- Terminal IPython were the loop is started/stopped between each user input. 
- Notebook kernel/Jupyter IPython where the loop is already running and 
task/user code can be process in background w/o pausing the loop. 

AFAICT, this would also be of potential use for other REPL (Xonsh, Bpython).

I'm happy to give more details, but I think that's a enough of a broad 
overview, as we should be releasing this in IPython in a few days/week, we will 
likely have further feedback from a wider range of users that can inform the 
design.

----------
components: Interpreter Core
messages: 324900
nosy: mbussonn
priority: normal
severity: normal
status: open
title: implement "Async exec"
type: enhancement
versions: Python 3.8

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue34616>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to