Skip to content

Commit 684064d

Browse files
committed
Change run_blocking into run_sync
1 parent f2c2722 commit 684064d

File tree

3 files changed

+53
-46
lines changed

3 files changed

+53
-46
lines changed

nbclient/client.py

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from nbformat.v4 import output_from_msg
1717

1818
from .exceptions import CellTimeoutError, DeadKernelError, CellExecutionComplete, CellExecutionError
19+
from .util import run_sync
1920

2021

2122
def timestamp():
@@ -294,43 +295,6 @@ def __init__(self, nb, km=None, **kw):
294295
self.km = km
295296
self.reset_execution_trackers()
296297

297-
def run_blocking(self, coro):
298-
"""Runs a coroutine and blocks until it has executed.
299-
300-
An event loop is created if no one already exists. If an event loop is
301-
already running, this event loop execution is nested into the already
302-
running one if `nest_asyncio` is set to True.
303-
304-
Parameters
305-
----------
306-
coro : coroutine
307-
The coroutine to be executed.
308-
309-
Returns
310-
-------
311-
result :
312-
Whatever the coroutine returns.
313-
"""
314-
try:
315-
loop = asyncio.get_event_loop()
316-
except RuntimeError:
317-
loop = asyncio.new_event_loop()
318-
asyncio.set_event_loop(loop)
319-
if self.nest_asyncio:
320-
import nest_asyncio
321-
nest_asyncio.apply(loop)
322-
try:
323-
result = loop.run_until_complete(coro)
324-
except RuntimeError as e:
325-
if str(e) == 'This event loop is already running':
326-
raise RuntimeError(
327-
'You are trying to run nbclient in an environment where an '
328-
'event loop is already running. Please pass `nest_asyncio=True` in '
329-
'`NotebookClient.execute` and such methods.'
330-
)
331-
raise
332-
return result
333-
334298
def reset_execution_trackers(self):
335299
"""Resets any per-execution trackers.
336300
"""
@@ -417,9 +381,6 @@ async def setup_kernel(self, **kwargs):
417381
self.kc.stop_channels()
418382
self.kc = None
419383

420-
def execute(self, **kwargs):
421-
return self.run_blocking(self.async_execute(**kwargs))
422-
423384
async def async_execute(self, **kwargs):
424385
"""
425386
Executes each code cell.
@@ -445,6 +406,8 @@ async def async_execute(self, **kwargs):
445406

446407
return self.nb
447408

409+
execute = run_sync(async_execute)
410+
448411
def set_widgets_metadata(self):
449412
if self.widget_state:
450413
self.nb.metadata.widgets = {
@@ -591,11 +554,6 @@ def _check_raise_for_error(self, cell, exec_reply):
591554
if (exec_reply is not None) and exec_reply['content']['status'] == 'error':
592555
raise CellExecutionError.from_cell_and_msg(cell, exec_reply['content'])
593556

594-
def execute_cell(self, cell, cell_index, execution_count=None, store_history=True):
595-
return self.run_blocking(
596-
self.async_execute_cell(cell, cell_index, execution_count, store_history)
597-
)
598-
599557
async def async_execute_cell(self, cell, cell_index, execution_count=None, store_history=True):
600558
"""
601559
Executes a single code cell.
@@ -661,6 +619,8 @@ async def async_execute_cell(self, cell, cell_index, execution_count=None, store
661619
self.nb['cells'][cell_index] = cell
662620
return cell
663621

622+
execute_cell = run_sync(async_execute_cell)
623+
664624
def process_message(self, msg, cell, cell_index):
665625
"""
666626
Processes a kernel message, updates cell state, and returns the

nbclient/tests/test_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ def test_kernel_death(self):
492492
km = executor.start_kernel_manager()
493493

494494
with patch.object(km, "is_alive") as alive_mock:
495-
alive_mock.return_value = make_async(False)
495+
alive_mock.return_value = False
496496
# Will be a RuntimeError or subclass DeadKernelError depending
497497
# on if jupyter_client or nbconvert catches the dead client first
498498
with pytest.raises(RuntimeError):

nbclient/util.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""General utility methods"""
2+
3+
# Copyright (c) Jupyter Development Team.
4+
# Distributed under the terms of the Modified BSD License.
5+
6+
import asyncio
7+
8+
9+
def run_sync(coro):
10+
"""Runs a coroutine and blocks until it has executed.
11+
12+
An event loop is created if no one already exists. If an event loop is
13+
already running, this event loop execution is nested into the already
14+
running one if `nest_asyncio` is set to True.
15+
16+
Parameters
17+
----------
18+
coro : coroutine
19+
The coroutine to be executed.
20+
21+
Returns
22+
-------
23+
result :
24+
Whatever the coroutine returns.
25+
"""
26+
def wrapped(self, *args, **kwargs):
27+
try:
28+
loop = asyncio.get_event_loop()
29+
except RuntimeError:
30+
loop = asyncio.new_event_loop()
31+
asyncio.set_event_loop(loop)
32+
if self.nest_asyncio:
33+
import nest_asyncio
34+
nest_asyncio.apply(loop)
35+
try:
36+
result = loop.run_until_complete(coro(self, *args, **kwargs))
37+
except RuntimeError as e:
38+
if str(e) == 'This event loop is already running':
39+
raise RuntimeError(
40+
'You are trying to run nbclient in an environment where an '
41+
'event loop is already running. Please pass `nest_asyncio=True` in '
42+
'`NotebookClient.execute` and such methods.'
43+
)
44+
raise
45+
return result
46+
wrapped.__doc__ = coro.__doc__
47+
return wrapped

0 commit comments

Comments
 (0)