Skip to content

Commit 160c27d

Browse files
authored
Merge pull request #6221 from dleen/master
Fix asyncio error when opening notebooks
2 parents a9a31c0 + 751c7eb commit 160c27d

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

notebook/notebookapp.py

+27
Original file line numberDiff line numberDiff line change
@@ -2092,7 +2092,34 @@ def _init_asyncio_patch(self):
20922092
20932093
FIXME: if/when tornado supports the defaults in asyncio,
20942094
remove and bump tornado requirement for py38
2095+
2096+
With the introduction of the async kernel, the existing sync kernel
2097+
requires the use of nested loops in order to run code synchronously.
2098+
This is done in `jupyter_client` using the helper util `run_sync`:
2099+
2100+
ref: https://github.com/jupyter/jupyter_client/blob/f453b51eeeff9e905c583b7da3905c0e35cfbdf0/jupyter_client/utils.py#L11
2101+
2102+
which creates a new event loop and relies on `nest_asyncio` patching
2103+
to allow nested loops. This requires that *all* potential tasks are
2104+
patched before executing. When only some tasks are patched it leads to
2105+
the following issue:
2106+
2107+
ref: https://github.com/jupyter/notebook/issues/6164
2108+
2109+
So we must call `nest_asyncio.apply()` method as early as possible. It
2110+
is preferable to do this in the consuming application rather than the
2111+
`jupyter_client` as it is a global patch and would impact all consumers
2112+
rather than just the ones that rely on synchronous kernel behavior.
20952113
"""
2114+
import nest_asyncio
2115+
2116+
try:
2117+
nest_asyncio.apply()
2118+
except RuntimeError:
2119+
# nest_asyncio requires a running loop in order to patch.
2120+
# In tests the loop may not have been created yet.
2121+
pass
2122+
20962123
if sys.platform.startswith("win") and sys.version_info >= (3, 8):
20972124
import asyncio
20982125
try:

notebook/tests/launchnotebook.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,16 @@ def start_thread():
167167
token=cls.token,
168168
**bind_args
169169
)
170-
if 'asyncio' in sys.modules:
171-
app._init_asyncio_patch()
172-
import asyncio
173-
asyncio.set_event_loop(asyncio.new_event_loop())
170+
if "asyncio" in sys.modules:
171+
app._init_asyncio_patch()
172+
import asyncio
173+
174+
asyncio.set_event_loop(asyncio.new_event_loop())
175+
# Patch the current loop in order to match production
176+
# behavior
177+
import nest_asyncio
178+
179+
nest_asyncio.apply()
174180
# don't register signal handler during tests
175181
app.init_signal = lambda : None
176182
# clear log handlers and propagate to root for nose to capture it

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
'jupyter_client>=5.3.4',
122122
'nbformat',
123123
'nbconvert',
124+
'nest-asyncio>=1.5',
124125
'ipykernel', # bless IPython kernel for now
125126
'Send2Trash>=1.8.0',
126127
'terminado>=0.8.3',

0 commit comments

Comments
 (0)