Show More
@@ -8,7 +8,7 b' Asynchronous in REPL: Autoawait' | |||||
8 | This feature is experimental and behavior can change between python and |
|
8 | This feature is experimental and behavior can change between python and | |
9 | IPython version without prior deprecation. |
|
9 | IPython version without prior deprecation. | |
10 |
|
10 | |||
11 |
Starting with IPython 7.0, and when us |
|
11 | Starting with IPython 7.0, and when using Python 3.6 and above, IPython offer the | |
12 | ability to run asynchronous code from the REPL. Constructs which are |
|
12 | ability to run asynchronous code from the REPL. Constructs which are | |
13 | :exc:`SyntaxError` s in the Python REPL can be used seamlessly in IPython. |
|
13 | :exc:`SyntaxError` s in the Python REPL can be used seamlessly in IPython. | |
14 |
|
14 | |||
@@ -19,7 +19,7 b' will differ between IPython, IPykernel and their versions.' | |||||
19 |
|
19 | |||
20 | When a supported library is used, IPython will automatically allow Futures and |
|
20 | When a supported library is used, IPython will automatically allow Futures and | |
21 | Coroutines in the REPL to be ``await`` ed. This will happen if an :ref:`await |
|
21 | Coroutines in the REPL to be ``await`` ed. This will happen if an :ref:`await | |
22 | <await>` (or any other async constructs like async-with, async-for) is use at |
|
22 | <await>` (or any other async constructs like async-with, async-for) is used at | |
23 | top level scope, or if any structure valid only in `async def |
|
23 | top level scope, or if any structure valid only in `async def | |
24 | <https://docs.python.org/3/reference/compound_stmts.html#async-def>`_ function |
|
24 | <https://docs.python.org/3/reference/compound_stmts.html#async-def>`_ function | |
25 | context are present. For example, the following being a syntax error in the |
|
25 | context are present. For example, the following being a syntax error in the | |
@@ -73,7 +73,7 b" By default IPython will assume integration with Python's provided" | |||||
73 | :mod:`asyncio`, but integration with other libraries is provided. In particular |
|
73 | :mod:`asyncio`, but integration with other libraries is provided. In particular | |
74 | we provide experimental integration with the ``curio`` and ``trio`` library. |
|
74 | we provide experimental integration with the ``curio`` and ``trio`` library. | |
75 |
|
75 | |||
76 | You can switch current integration by using the |
|
76 | You can switch the current integration by using the | |
77 | ``c.InteractiveShell.loop_runner`` option or the ``autoawait <name |
|
77 | ``c.InteractiveShell.loop_runner`` option or the ``autoawait <name | |
78 | integration>`` magic. |
|
78 | integration>`` magic. | |
79 |
|
79 | |||
@@ -118,7 +118,7 b' to your code.' | |||||
118 |
|
118 | |||
119 | When using command line IPython, the default loop (or runner) does not process |
|
119 | When using command line IPython, the default loop (or runner) does not process | |
120 | in the background, so top level asynchronous code must finish for the REPL to |
|
120 | in the background, so top level asynchronous code must finish for the REPL to | |
121 | allow you to enter more code. As with usual Python semantic, the awaitables are |
|
121 | allow you to enter more code. As with usual Python semantics, the awaitables are | |
122 | started only when awaited for the first time. That is to say, in first example, |
|
122 | started only when awaited for the first time. That is to say, in first example, | |
123 | no network request is done between ``In[1]`` and ``In[2]``. |
|
123 | no network request is done between ``In[1]`` and ``In[2]``. | |
124 |
|
124 | |||
@@ -131,8 +131,8 b' a loop to run. By default IPython will use a fake coroutine runner which should' | |||||
131 | allow ``IPython.embed()`` to be nested. Though this will prevent usage of the |
|
131 | allow ``IPython.embed()`` to be nested. Though this will prevent usage of the | |
132 | :magic:`%autoawait` feature when using IPython embed. |
|
132 | :magic:`%autoawait` feature when using IPython embed. | |
133 |
|
133 | |||
134 |
You can set |
|
134 | You can set a coroutine runner explicitly for ``embed()`` if you want to run | |
135 |
asynchronous code, the exact behavior is |
|
135 | asynchronous code, though the exact behavior is undefined. | |
136 |
|
136 | |||
137 | Effects on Magics |
|
137 | Effects on Magics | |
138 | ----------------- |
|
138 | ----------------- | |
@@ -140,14 +140,14 b' Effects on Magics' | |||||
140 | A couple of magics (``%%timeit``, ``%timeit``, ``%%time``, ``%%prun``) have not |
|
140 | A couple of magics (``%%timeit``, ``%timeit``, ``%%time``, ``%%prun``) have not | |
141 | yet been updated to work with asynchronous code and will raise syntax errors |
|
141 | yet been updated to work with asynchronous code and will raise syntax errors | |
142 | when trying to use top-level ``await``. We welcome any contribution to help fix |
|
142 | when trying to use top-level ``await``. We welcome any contribution to help fix | |
143 | those, and extra cases we haven't caught yet. We hope for better support in Cor |
|
143 | those, and extra cases we haven't caught yet. We hope for better support in Core | |
144 | Python for top-level Async code. |
|
144 | Python for top-level Async code. | |
145 |
|
145 | |||
146 | Internals |
|
146 | Internals | |
147 | --------- |
|
147 | --------- | |
148 |
|
148 | |||
149 | As running asynchronous code is not supported in interactive REPL (as of Python |
|
149 | As running asynchronous code is not supported in interactive REPL (as of Python | |
150 | 3.7) we have to rely to a number of complex workaround and heuristic to allow |
|
150 | 3.7) we have to rely to a number of complex workarounds and heuristics to allow | |
151 | this to happen. It is interesting to understand how this works in order to |
|
151 | this to happen. It is interesting to understand how this works in order to | |
152 | comprehend potential bugs, or provide a custom runner. |
|
152 | comprehend potential bugs, or provide a custom runner. | |
153 |
|
153 | |||
@@ -179,16 +179,16 b' significant overhead to this kind of code.' | |||||
179 | By default the generated coroutine function will be consumed by Asyncio's |
|
179 | By default the generated coroutine function will be consumed by Asyncio's | |
180 | ``loop_runner = asyncio.get_evenloop().run_until_complete()`` method if |
|
180 | ``loop_runner = asyncio.get_evenloop().run_until_complete()`` method if | |
181 | ``async`` mode is deemed necessary, otherwise the coroutine will just be |
|
181 | ``async`` mode is deemed necessary, otherwise the coroutine will just be | |
182 |
exhausted in a simple runner. It is |
|
182 | exhausted in a simple runner. It is possible, though, to change the default | |
183 | runner. |
|
183 | runner. | |
184 |
|
184 | |||
185 | A loop runner is a *synchronous* function responsible from running a coroutine |
|
185 | A loop runner is a *synchronous* function responsible from running a coroutine | |
186 | object. |
|
186 | object. | |
187 |
|
187 | |||
188 |
The runner is responsible f |
|
188 | The runner is responsible for ensuring that ``coroutine`` runs to completion, | |
189 | and should return the result of executing the coroutine. Let's write a |
|
189 | and it should return the result of executing the coroutine. Let's write a | |
190 | runner for ``trio`` that print a message when used as an exercise, ``trio`` is |
|
190 | runner for ``trio`` that print a message when used as an exercise, ``trio`` is | |
191 | special as it usually prefer to run a function object and make a coroutine by |
|
191 | special as it usually prefers to run a function object and make a coroutine by | |
192 | itself, we can get around this limitation by wrapping it in an async-def without |
|
192 | itself, we can get around this limitation by wrapping it in an async-def without | |
193 | parameters and passing this value to ``trio``:: |
|
193 | parameters and passing this value to ``trio``:: | |
194 |
|
194 | |||
@@ -246,8 +246,8 b' Difference between terminal IPython and IPykernel' | |||||
246 | The exact asynchronous code running behavior varies between Terminal IPython and |
|
246 | The exact asynchronous code running behavior varies between Terminal IPython and | |
247 | IPykernel. The root cause of this behavior is due to IPykernel having a |
|
247 | IPykernel. The root cause of this behavior is due to IPykernel having a | |
248 | *persistent* `asyncio` loop running, while Terminal IPython starts and stops a |
|
248 | *persistent* `asyncio` loop running, while Terminal IPython starts and stops a | |
249 | loop for each code block. This can lead to surprising behavior in some case if |
|
249 | loop for each code block. This can lead to surprising behavior in some cases if | |
250 |
you are used to manipulat |
|
250 | you are used to manipulating asyncio loop yourself, see for example | |
251 | :ghissue:`11303` for a longer discussion but here are some of the astonishing |
|
251 | :ghissue:`11303` for a longer discussion but here are some of the astonishing | |
252 | cases. |
|
252 | cases. | |
253 |
|
253 |
General Comments 0
You need to be logged in to leave comments.
Login now