Skip to content

Commit 4cd912f

Browse files
authored
Merge pull request #578 from davidbrochart/fix_inprocess
Rework wait_for_ready logic
2 parents a19319e + a6a68b6 commit 4cd912f

File tree

5 files changed

+53
-25
lines changed

5 files changed

+53
-25
lines changed

ipykernel/inprocess/blocking.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,21 @@ class BlockingInProcessKernelClient(InProcessKernelClient):
7676
def wait_for_ready(self):
7777
# Wait for kernel info reply on shell channel
7878
while True:
79-
msg = self.shell_channel.get_msg(block=True)
80-
if msg['msg_type'] == 'kernel_info_reply':
81-
self._handle_kernel_info_reply(msg)
82-
break
79+
self.kernel_info()
80+
try:
81+
msg = self.shell_channel.get_msg(block=True, timeout=1)
82+
except Empty:
83+
pass
84+
else:
85+
if msg['msg_type'] == 'kernel_info_reply':
86+
# Checking that IOPub is connected. If it is not connected, start over.
87+
try:
88+
self.iopub_channel.get_msg(block=True, timeout=0.2)
89+
except Empty:
90+
pass
91+
else:
92+
self._handle_kernel_info_reply(msg)
93+
break
8394

8495
# Flush IOPub channel
8596
while True:

ipykernel/tests/test_kernel.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from .utils import (
2323
new_kernel, kernel, TIMEOUT, assemble_output, execute,
24-
flush_channels, wait_for_idle,
24+
flush_channels, wait_for_idle, get_reply,
2525
)
2626

2727

@@ -360,9 +360,9 @@ def test_interrupt_during_input():
360360
msg_id = kc.execute("input()")
361361
time.sleep(1) # Make sure it's actually waiting for input.
362362
km.interrupt_kernel()
363-
# If we failed to interrupt interrupt, this will timeout:
364-
reply = kc.get_shell_msg(timeout=TIMEOUT)
365363
from .test_message_spec import validate_message
364+
# If we failed to interrupt interrupt, this will timeout:
365+
reply = get_reply(kc, msg_id, TIMEOUT)
366366
validate_message(reply, 'execute_reply', msg_id)
367367

368368

@@ -385,9 +385,10 @@ def test_interrupt_during_pdb_set_trace():
385385
msg_id2 = kc.execute("3 + 4")
386386
time.sleep(1) # Make sure it's actually waiting for input.
387387
km.interrupt_kernel()
388-
# If we failed to interrupt interrupt, this will timeout:
389388
from .test_message_spec import validate_message
390-
reply = kc.get_shell_msg(timeout=TIMEOUT)
389+
# If we failed to interrupt interrupt, this will timeout:
390+
reply = get_reply(kc, msg_id, TIMEOUT)
391391
validate_message(reply, 'execute_reply', msg_id)
392-
reply = kc.get_shell_msg(timeout=TIMEOUT)
392+
# If we failed to interrupt interrupt, this will timeout:
393+
reply = get_reply(kc, msg_id2, TIMEOUT)
393394
validate_message(reply, 'execute_reply', msg_id2)

ipykernel/tests/test_message_spec.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum
1616
)
1717

18-
from .utils import TIMEOUT, start_global_kernel, flush_channels, execute
18+
from .utils import (TIMEOUT, start_global_kernel, flush_channels, execute,
19+
get_reply, )
1920

2021
#-----------------------------------------------------------------------------
2122
# Globals
@@ -278,7 +279,7 @@ def test_execute():
278279
flush_channels()
279280

280281
msg_id = KC.execute(code='x=1')
281-
reply = KC.get_shell_msg(timeout=TIMEOUT)
282+
reply = get_reply(KC, msg_id, TIMEOUT)
282283
validate_message(reply, 'execute_reply', msg_id)
283284

284285

@@ -405,7 +406,7 @@ def test_oinfo():
405406
flush_channels()
406407

407408
msg_id = KC.inspect('a')
408-
reply = KC.get_shell_msg(timeout=TIMEOUT)
409+
reply = get_reply(KC, msg_id, TIMEOUT)
409410
validate_message(reply, 'inspect_reply', msg_id)
410411

411412

@@ -415,7 +416,7 @@ def test_oinfo_found():
415416
msg_id, reply = execute(code='a=5')
416417

417418
msg_id = KC.inspect('a')
418-
reply = KC.get_shell_msg(timeout=TIMEOUT)
419+
reply = get_reply(KC, msg_id, TIMEOUT)
419420
validate_message(reply, 'inspect_reply', msg_id)
420421
content = reply['content']
421422
assert content['found']
@@ -430,7 +431,7 @@ def test_oinfo_detail():
430431
msg_id, reply = execute(code='ip=get_ipython()')
431432

432433
msg_id = KC.inspect('ip.object_inspect', cursor_pos=10, detail_level=1)
433-
reply = KC.get_shell_msg(timeout=TIMEOUT)
434+
reply = get_reply(KC, msg_id, TIMEOUT)
434435
validate_message(reply, 'inspect_reply', msg_id)
435436
content = reply['content']
436437
assert content['found']
@@ -443,7 +444,7 @@ def test_oinfo_not_found():
443444
flush_channels()
444445

445446
msg_id = KC.inspect('dne')
446-
reply = KC.get_shell_msg(timeout=TIMEOUT)
447+
reply = get_reply(KC, msg_id, TIMEOUT)
447448
validate_message(reply, 'inspect_reply', msg_id)
448449
content = reply['content']
449450
assert not content['found']
@@ -455,7 +456,7 @@ def test_complete():
455456
msg_id, reply = execute(code="alpha = albert = 5")
456457

457458
msg_id = KC.complete('al', 2)
458-
reply = KC.get_shell_msg(timeout=TIMEOUT)
459+
reply = get_reply(KC, msg_id, TIMEOUT)
459460
validate_message(reply, 'complete_reply', msg_id)
460461
matches = reply['content']['matches']
461462
for name in ('alpha', 'albert'):
@@ -466,7 +467,7 @@ def test_kernel_info_request():
466467
flush_channels()
467468

468469
msg_id = KC.kernel_info()
469-
reply = KC.get_shell_msg(timeout=TIMEOUT)
470+
reply = get_reply(KC, msg_id, TIMEOUT)
470471
validate_message(reply, 'kernel_info_reply', msg_id)
471472

472473

@@ -477,7 +478,7 @@ def test_connect_request():
477478
return msg['header']['msg_id']
478479

479480
msg_id = KC.kernel_info()
480-
reply = KC.get_shell_msg(timeout=TIMEOUT)
481+
reply = get_reply(KC, msg_id, TIMEOUT)
481482
validate_message(reply, 'connect_reply', msg_id)
482483

483484

@@ -486,7 +487,7 @@ def test_comm_info_request():
486487
if not hasattr(KC, 'comm_info'):
487488
raise SkipTest()
488489
msg_id = KC.comm_info()
489-
reply = KC.get_shell_msg(timeout=TIMEOUT)
490+
reply = get_reply(KC, msg_id, TIMEOUT)
490491
validate_message(reply, 'comm_info_reply', msg_id)
491492

492493

@@ -512,7 +513,7 @@ def test_is_complete():
512513
flush_channels()
513514

514515
msg_id = KC.is_complete("a = 1")
515-
reply = KC.get_shell_msg(timeout=TIMEOUT)
516+
reply = get_reply(KC, msg_id, TIMEOUT)
516517
validate_message(reply, 'is_complete_reply', msg_id)
517518

518519
def test_history_range():
@@ -522,7 +523,7 @@ def test_history_range():
522523
reply_exec = KC.get_shell_msg(timeout=TIMEOUT)
523524

524525
msg_id = KC.history(hist_access_type = 'range', raw = True, output = True, start = 1, stop = 2, session = 0)
525-
reply = KC.get_shell_msg(timeout=TIMEOUT)
526+
reply = get_reply(KC, msg_id, TIMEOUT)
526527
validate_message(reply, 'history_reply', msg_id)
527528
content = reply['content']
528529
assert len(content['history']) == 1
@@ -534,7 +535,7 @@ def test_history_tail():
534535
reply_exec = KC.get_shell_msg(timeout=TIMEOUT)
535536

536537
msg_id = KC.history(hist_access_type = 'tail', raw = True, output = True, n = 1, session = 0)
537-
reply = KC.get_shell_msg(timeout=TIMEOUT)
538+
reply = get_reply(KC, msg_id, TIMEOUT)
538539
validate_message(reply, 'history_reply', msg_id)
539540
content = reply['content']
540541
assert len(content['history']) == 1
@@ -546,7 +547,7 @@ def test_history_search():
546547
reply_exec = KC.get_shell_msg(timeout=TIMEOUT)
547548

548549
msg_id = KC.history(hist_access_type = 'search', raw = True, output = True, n = 1, pattern = '*', session = 0)
549-
reply = KC.get_shell_msg(timeout=TIMEOUT)
550+
reply = get_reply(KC, msg_id, TIMEOUT)
550551
validate_message(reply, 'history_reply', msg_id)
551552
content = reply['content']
552553
assert len(content['history']) == 1

ipykernel/tests/utils.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import atexit
77
import os
88
import sys
9+
from time import time
910

1011
from contextlib import contextmanager
1112
from queue import Empty
@@ -52,13 +53,26 @@ def flush_channels(kc=None):
5253
validate_message(msg)
5354

5455

56+
def get_reply(kc, msg_id, timeout):
57+
timeout = TIMEOUT
58+
t0 = time()
59+
while True:
60+
reply = kc.get_shell_msg(timeout=timeout)
61+
if reply['parent_header']['msg_id'] == msg_id:
62+
break
63+
t1 = time()
64+
timeout -= t1 - t0
65+
t0 = t1
66+
return reply
67+
68+
5569
def execute(code='', kc=None, **kwargs):
5670
"""wrapper for doing common steps for validating an execution request"""
5771
from .test_message_spec import validate_message
5872
if kc is None:
5973
kc = KC
6074
msg_id = kc.execute(code=code, **kwargs)
61-
reply = kc.get_shell_msg(timeout=TIMEOUT)
75+
reply = get_reply(kc, msg_id, TIMEOUT)
6276
validate_message(reply, 'execute_reply', msg_id)
6377
busy = kc.get_iopub_msg(timeout=TIMEOUT)
6478
validate_message(busy, 'status', msg_id)

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def run(self):
9797
'pytest-cov',
9898
'flaky',
9999
'nose', # nose because there are still a few nose.tools imports hanging around
100+
'jedi<=0.17.2'
100101
],
101102
},
102103
classifiers=[

0 commit comments

Comments
 (0)