1
1
import asyncio
2
2
import sys
3
3
import time
4
+ from inspect import iscoroutinefunction
4
5
5
6
import zmq
6
7
from IPython import get_ipython
@@ -18,17 +19,30 @@ def __init__(self, shell, loop) -> None:
18
19
self ._shell = shell
19
20
self ._kernel = kernel
20
21
self ._loop = loop
21
- self ._original_parent = (kernel ._parent_ident , kernel .get_parent ())
22
+ self ._original_parent = (
23
+ kernel ._parent_ident ,
24
+ kernel .get_parent () # ipykernel 6+
25
+ if hasattr (kernel , "get_parent" )
26
+ else kernel ._parent_header , # ipykernel < 6
27
+ )
22
28
self ._events = []
23
29
self ._backup_execute_request = kernel .shell_handlers ["execute_request" ]
24
30
self ._aproc = None
31
+ self ._kernel_is_async = iscoroutinefunction (self ._backup_execute_request )
32
+
33
+ if self ._kernel_is_async : # ipykernel 6+
34
+ kernel .shell_handlers ["execute_request" ] = self ._execute_request_async
35
+ else :
36
+ # ipykernel < 6
37
+ kernel .shell_handlers ["execute_request" ] = self ._execute_request
25
38
26
39
shell .events .register ("post_run_cell" , self ._post_run_cell_hook )
27
- kernel .shell_handlers ["execute_request" ] = self ._execute_request_async
28
40
29
41
def restore (self ):
30
42
if self ._backup_execute_request is not None :
31
- self ._kernel .shell_handlers ["execute_request" ] = self ._backup_execute_request
43
+ self ._kernel .shell_handlers [
44
+ "execute_request"
45
+ ] = self ._backup_execute_request
32
46
self ._backup_execute_request = None
33
47
34
48
def _reset_output (self ):
@@ -48,17 +62,27 @@ async def replay(self):
48
62
49
63
sys .stdout .flush ()
50
64
sys .stderr .flush ()
65
+ shell_stream = getattr (
66
+ kernel , "shell_stream" , None
67
+ ) # ipykernel 6 vs 5 differences
68
+
51
69
for stream , ident , parent in self ._events :
52
70
kernel .set_parent (ident , parent )
53
71
if kernel ._aborting :
54
72
kernel ._send_abort_reply (stream , parent , ident )
55
73
else :
56
- await kernel .execute_request (stream , ident , parent )
74
+ rr = kernel .execute_request (stream , ident , parent )
75
+ if self ._kernel_is_async :
76
+ await rr
77
+
57
78
# replicate shell_dispatch behaviour
58
79
sys .stdout .flush ()
59
80
sys .stderr .flush ()
60
- kernel ._publish_status ('idle' , 'shell' )
61
- kernel .shell_stream .flush (zmq .POLLOUT )
81
+ if shell_stream is not None : # 6+
82
+ kernel ._publish_status ("idle" , "shell" )
83
+ shell_stream .flush (zmq .POLLOUT )
84
+ else :
85
+ kernel ._publish_status ("idle" )
62
86
63
87
async def do_one_iteration (self ):
64
88
try :
@@ -100,7 +124,9 @@ def wrap_iterator(self, its, n: int = 1):
100
124
@staticmethod
101
125
def get ():
102
126
if KernelWrapper ._current is None :
103
- KernelWrapper ._current = KernelWrapper (get_ipython (), asyncio .get_event_loop ())
127
+ KernelWrapper ._current = KernelWrapper (
128
+ get_ipython (), asyncio .get_event_loop ()
129
+ )
104
130
return KernelWrapper ._current
105
131
106
132
@@ -130,6 +156,7 @@ async def _loop(kernel, its, n):
130
156
for x in its :
131
157
await poll (n )
132
158
yield x
159
+
133
160
return _loop (self ._kernel , self ._its , self ._n )
134
161
135
162
0 commit comments