... | ... |
@@ -1,50 +1,64 @@ |
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 |
import asyncio |
3 |
+from pkg_resources import parse_version |
|
4 |
+import warnings |
|
3 | 5 |
|
4 | 6 |
from IPython import get_ipython |
7 |
+import ipykernel |
|
5 | 8 |
from ipykernel.eventloops import register_integration |
6 | 9 |
|
7 | 10 |
|
8 |
-# IPython event loop integraion |
|
9 |
- |
|
10 |
-@register_integration('asyncio') |
|
11 |
-def _loop_asyncio(kernel): |
|
12 |
- '''Start a kernel with asyncio event loop support.''' |
|
13 |
- loop = asyncio.get_event_loop() |
|
14 |
- |
|
15 |
- def kernel_handler(): |
|
16 |
- loop.call_soon(kernel.do_one_iteration) |
|
17 |
- loop.call_later(kernel._poll_interval, kernel_handler) |
|
18 |
- |
|
19 |
- loop.call_soon(kernel_handler) |
|
20 |
- # loop is already running (e.g. tornado 5), nothing left to do |
|
21 |
- if loop.is_running(): |
|
22 |
- return |
|
23 |
- while True: |
|
24 |
- error = None |
|
25 |
- try: |
|
26 |
- loop.run_forever() |
|
27 |
- except KeyboardInterrupt: |
|
28 |
- continue |
|
29 |
- except Exception as e: |
|
30 |
- error = e |
|
31 |
- loop.run_until_complete(loop.shutdown_asyncgens()) |
|
32 |
- loop.close() |
|
33 |
- if error is not None: |
|
34 |
- raise error |
|
35 |
- break |
|
11 |
+# IPython event loop integration |
|
12 |
+ |
|
13 |
+if parse_version(ipykernel.__version__) < parse_version('4.7.0'): |
|
14 |
+ # XXX: remove this function when we depend on ipykernel>=4.7.0 |
|
15 |
+ @register_integration('asyncio') |
|
16 |
+ def _loop_asyncio(kernel): |
|
17 |
+ """Start a kernel with asyncio event loop support. |
|
18 |
+ Taken from https://github.com/ipython/ipykernel/blob/fa814da201bdebd5b16110597604f7dabafec58d/ipykernel/eventloops.py#L294""" |
|
19 |
+ loop = asyncio.get_event_loop() |
|
20 |
+ |
|
21 |
+ def kernel_handler(): |
|
22 |
+ loop.call_soon(kernel.do_one_iteration) |
|
23 |
+ loop.call_later(kernel._poll_interval, kernel_handler) |
|
24 |
+ |
|
25 |
+ loop.call_soon(kernel_handler) |
|
26 |
+ # loop is already running (e.g. tornado 5), nothing left to do |
|
27 |
+ if loop.is_running(): |
|
28 |
+ return |
|
29 |
+ while True: |
|
30 |
+ error = None |
|
31 |
+ try: |
|
32 |
+ loop.run_forever() |
|
33 |
+ except KeyboardInterrupt: |
|
34 |
+ continue |
|
35 |
+ except Exception as e: |
|
36 |
+ error = e |
|
37 |
+ loop.run_until_complete(loop.shutdown_asyncgens()) |
|
38 |
+ loop.close() |
|
39 |
+ if error is not None: |
|
40 |
+ raise error |
|
41 |
+ break |
|
36 | 42 |
|
37 | 43 |
|
38 | 44 |
def notebook_extension(): |
39 |
- import holoviews |
|
40 | 45 |
get_ipython().magic('gui asyncio') |
41 |
- return holoviews.notebook_extension('bokeh') |
|
46 |
+ try: |
|
47 |
+ import holoviews as hv |
|
48 |
+ return hv.notebook_extension('bokeh') |
|
49 |
+ except ModuleNotFoundError: |
|
50 |
+ warnings.warn("The holoviews package is not installed so plotting" |
|
51 |
+ "will not work.", RuntimeWarning) |
|
42 | 52 |
|
43 | 53 |
|
44 | 54 |
# Plotting |
45 | 55 |
|
46 | 56 |
def live_plot(runner, *, plotter=None, update_interval=2): |
47 |
- import holoviews as hv |
|
57 |
+ try: |
|
58 |
+ import holoviews as hv |
|
59 |
+ except ModuleNotFoundError: |
|
60 |
+ raise RuntimeError('Plotting requires the holoviews Python package' |
|
61 |
+ ' which is not installed.') |
|
48 | 62 |
|
49 | 63 |
def plot_generator(): |
50 | 64 |
while True: |