11import sys
2+ import time
23import pytest
34import textwrap
5+ from _queue import Empty
46
57from .testutils import check_deterministic_pickle
68
1315ipykernel = pytest .importorskip ("ipykernel" )
1416
1517
16- def run_in_notebook (code ):
18+ def run_in_notebook (code , timeout = 10 ):
1719 km = ipykernel .connect .jupyter_client .KernelManager ()
1820 km .start_kernel ()
1921 kc = km .client ()
@@ -25,7 +27,11 @@ def run_in_notebook(code):
2527 idx = kc .execute (code )
2628 running = True
2729 while running :
28- res = kc .iopub_channel .get_msg (timeout = None )
30+ try :
31+ res = kc .iopub_channel .get_msg (timeout = timeout )
32+ except Empty :
33+ status = "timeout"
34+ break
2935 if res ['parent_header' ].get ('msg_id' ) != idx :
3036 continue
3137 content = res ['content' ]
@@ -40,11 +46,31 @@ def run_in_notebook(code):
4046 kc .stop_channels ()
4147 km .shutdown_kernel (now = True , restart = False )
4248 assert not km .is_alive ()
43- if status != "error" :
49+ if status not in [ "error" , "timeout" ] :
4450 status = "ok" if not running else "exec_error"
4551 return status , output , err
4652
4753
54+ @pytest .mark .parametrize ("code, expected" , [
55+ ("1 + 1" , "ok" ),
56+ ("raise ValueError('This is a test error')" , "error" ),
57+ ("import time; time.sleep(100)" , "timeout" )
58+
59+ ])
60+ def test_run_in_notebook (code , expected ):
61+ code = textwrap .dedent (code )
62+
63+ t_start = time .time ()
64+ status , output , err = run_in_notebook (code , timeout = 1 )
65+ duration = time .time () - t_start
66+ assert status == expected , (
67+ f"Unexpected status: { status } , output: { output } , err: { err } , duration: { duration } "
68+ )
69+ assert duration < 10 , "Timeout not enforced properly"
70+ if expected == "error" :
71+ assert "This is a test error" in err
72+
73+
4874def test_deterministic_payload_for_dynamic_func_in_notebook ():
4975 code = textwrap .dedent ("""
5076 import cloudpickle
0 commit comments