Skip to content

Commit 28d096d

Browse files
authored
Delete always skipped test, fix trio test, fix framelocal has not .clear() (#1322)
There are few chances we will ever use them again. Also a small refactor and unskip of trio test using trio nursery.
1 parent 486050f commit 28d096d

File tree

8 files changed

+52
-97
lines changed

8 files changed

+52
-97
lines changed

ipykernel/embed.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ def embed_kernel(module=None, local_ns=None, **kwargs):
4848
if module is None:
4949
module = caller_module
5050
if local_ns is None:
51-
local_ns = caller_locals
51+
local_ns = dict(**caller_locals)
5252

5353
app.kernel.user_module = module
54+
assert isinstance(local_ns, dict)
5455
app.kernel.user_ns = local_ns
5556
app.shell.set_completer_frame() # type:ignore[union-attr]
5657
app.start()

ipykernel/ipkernel.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,18 @@
1818
from IPython.core import release
1919
from IPython.utils.tokenutil import line_at_cursor, token_at_cursor
2020
from jupyter_client.session import extract_header
21-
from traitlets import Any, Bool, HasTraits, Instance, List, Type, default, observe, observe_compat
21+
from traitlets import (
22+
Any,
23+
Bool,
24+
Dict,
25+
HasTraits,
26+
Instance,
27+
List,
28+
Type,
29+
default,
30+
observe,
31+
observe_compat,
32+
)
2233

2334
from .comm.comm import BaseComm
2435
from .comm.manager import CommManager
@@ -92,7 +103,7 @@ def _user_module_changed(self, change):
92103
if self.shell is not None:
93104
self.shell.user_module = change["new"]
94105

95-
user_ns = Instance("collections.abc.Mapping", allow_none=True)
106+
user_ns = Dict(allow_none=True)
96107

97108
@default("user_ns")
98109
def _default_user_ns(self):

ipykernel/kernelapp.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ def init_pdb(self):
733733
pdb.set_trace = debugger.set_trace
734734

735735
@catch_config_error
736-
def initialize(self, argv=None):
736+
def initialize(self, argv=None) -> None:
737737
"""Initialize the application."""
738738
self._init_asyncio_patch()
739739
super().initialize(argv)
@@ -772,30 +772,37 @@ def initialize(self, argv=None):
772772
sys.stdout.flush()
773773
sys.stderr.flush()
774774

775-
def start(self) -> None:
776-
"""Start the application."""
775+
async def _start(self) -> None:
776+
"""
777+
Async version of start, when the loop is not controlled by IPykernel
778+
779+
For example to be used in test suite with @pytest.mark.trio
780+
"""
777781
if self.subapp is not None:
778782
self.subapp.start()
779783
return
780784
if self.poller is not None:
781785
self.poller.start()
786+
await self.main()
787+
788+
def start(self) -> None:
789+
"""Start the application."""
782790
backend = "trio" if self.trio_loop else "asyncio"
783-
run(self.main, backend=backend)
784-
return
791+
run(self._start, backend=backend)
785792

786-
async def _wait_to_enter_eventloop(self):
793+
async def _wait_to_enter_eventloop(self) -> None:
787794
await self.kernel._eventloop_set.wait()
788795
await self.kernel.enter_eventloop()
789796

790-
async def main(self):
797+
async def main(self) -> None:
791798
async with create_task_group() as tg:
792799
tg.start_soon(self._wait_to_enter_eventloop)
793800
tg.start_soon(self.kernel.start)
794801

795802
if self.kernel.eventloop:
796803
self.kernel._eventloop_set.set()
797804

798-
def stop(self):
805+
def stop(self) -> None:
799806
"""Stop the kernel, thread-safe."""
800807
self.kernel.stop()
801808

pyproject.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,13 @@ docs = [
5656
"trio"
5757
]
5858
test = [
59-
"pytest>=7.0,<9",
60-
"pytest-cov",
6159
"flaky",
6260
"ipyparallel",
6361
"pre-commit",
62+
"pytest-cov",
6463
"pytest-timeout",
64+
"pytest>=7.0,<9",
6565
"trio",
66-
"pytest-asyncio>=0.23.5",
6766
]
6867
cov = [
6968
"coverage[toml]",

tests/test_embed_kernel.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ def connection_file_ready(connection_file):
9393

9494
@flaky(max_runs=3)
9595
def test_embed_kernel_basic():
96-
"""IPython.embed_kernel() is basically functional"""
96+
"""ipykernel.embed.embed_kernel() is basically functional"""
9797
cmd = "\n".join(
9898
[
99-
"from IPython import embed_kernel",
99+
"from ipykernel.embed import embed_kernel",
100100
"def go():",
101101
" a=5",
102102
' b="hi there"',
@@ -129,10 +129,10 @@ def test_embed_kernel_basic():
129129

130130
@flaky(max_runs=3)
131131
def test_embed_kernel_namespace():
132-
"""IPython.embed_kernel() inherits calling namespace"""
132+
"""ipykernel.embed.embed_kernel() inherits calling namespace"""
133133
cmd = "\n".join(
134134
[
135-
"from IPython import embed_kernel",
135+
"from ipykernel.embed import embed_kernel",
136136
"def go():",
137137
" a=5",
138138
' b="hi there"',
@@ -168,10 +168,10 @@ def test_embed_kernel_namespace():
168168

169169
@flaky(max_runs=3)
170170
def test_embed_kernel_reentrant():
171-
"""IPython.embed_kernel() can be called multiple times"""
171+
"""ipykernel.embed.embed_kernel() can be called multiple times"""
172172
cmd = "\n".join(
173173
[
174-
"from IPython import embed_kernel",
174+
"from ipykernel.embed import embed_kernel",
175175
"count = 0",
176176
"def go():",
177177
" global count",

tests/test_ipkernel_direct.py

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Test IPythonKernel directly"""
22

3-
import asyncio
43
import os
54

65
import pytest
@@ -152,49 +151,12 @@ async def test_direct_clear(ipkernel):
152151
ipkernel.do_clear()
153152

154153

155-
@pytest.mark.skip("ipykernel._cancel_on_sigint doesn't exist anymore")
156-
async def test_cancel_on_sigint(ipkernel: IPythonKernel) -> None:
157-
future: asyncio.Future = asyncio.Future()
158-
# with ipkernel._cancel_on_sigint(future):
159-
# pass
160-
future.set_result(None)
161-
162-
163154
async def test_dispatch_debugpy(ipkernel: IPythonKernel) -> None:
164155
msg = ipkernel.session.msg("debug_request", {})
165156
msg_list = ipkernel.session.serialize(msg)
166157
await ipkernel.receive_debugpy_message(msg_list)
167158

168159

169-
@pytest.mark.skip("Queues don't exist anymore")
170-
async def test_start(ipkernel: IPythonKernel) -> None:
171-
shell_future: asyncio.Future = asyncio.Future()
172-
173-
async def fake_dispatch_queue():
174-
shell_future.set_result(None)
175-
176-
ipkernel.dispatch_queue = fake_dispatch_queue # type:ignore
177-
ipkernel.start()
178-
ipkernel.debugpy_stream = None
179-
ipkernel.start()
180-
await ipkernel.process_one(False)
181-
await shell_future
182-
183-
184-
@pytest.mark.skip("Queues don't exist anymore")
185-
async def test_start_no_debugpy(ipkernel: IPythonKernel) -> None:
186-
shell_future: asyncio.Future = asyncio.Future()
187-
188-
async def fake_dispatch_queue():
189-
shell_future.set_result(None)
190-
191-
ipkernel.dispatch_queue = fake_dispatch_queue # type:ignore
192-
ipkernel.debugpy_stream = None
193-
ipkernel.start()
194-
195-
await shell_future
196-
197-
198160
def test_create_comm():
199161
assert isinstance(_create_comm(), BaseComm)
200162

tests/test_kernel_direct.py

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
# Copyright (c) IPython Development Team.
44
# Distributed under the terms of the Modified BSD License.
55

6-
import asyncio
76
import os
8-
import warnings
97

108
import pytest
119

@@ -108,19 +106,6 @@ async def test_direct_debug_request(kernel):
108106
assert reply["header"]["msg_type"] == "debug_reply"
109107

110108

111-
@pytest.mark.skip("Shell streams don't exist anymore")
112-
async def test_deprecated_features(kernel):
113-
with warnings.catch_warnings():
114-
warnings.simplefilter("ignore", DeprecationWarning)
115-
header = kernel._parent_header
116-
assert isinstance(header, dict)
117-
shell_streams = kernel.shell_streams
118-
assert len(shell_streams) == 1
119-
assert shell_streams[0] == kernel.shell_stream
120-
warnings.simplefilter("ignore", RuntimeWarning)
121-
kernel.shell_streams = [kernel.shell_stream, kernel.shell_stream]
122-
123-
124109
async def test_process_control(kernel):
125110
from jupyter_client.session import DELIM
126111

@@ -142,12 +127,6 @@ async def test_dispatch_shell(kernel):
142127
await kernel.process_shell_message(msg)
143128

144129

145-
@pytest.mark.skip("kernelbase.do_one_iteration doesn't exist anymore")
146-
async def test_do_one_iteration(kernel):
147-
kernel.msg_queue = asyncio.Queue()
148-
await kernel.do_one_iteration()
149-
150-
151130
async def test_publish_debug_event(kernel):
152131
kernel._publish_debug_event({})
153132

@@ -160,7 +139,7 @@ async def test_send_interrupt_children(kernel):
160139
kernel._send_interrupt_children()
161140

162141

163-
# TODO: this causes deadlock
164-
# async def test_direct_usage_request(kernel):
165-
# reply = await kernel.test_control_message("usage_request", {})
166-
# assert reply['header']['msg_type'] == 'usage_reply'
142+
@pytest.mark.skip(reason="this causes deadlock")
143+
async def test_direct_usage_request(kernel):
144+
reply = await kernel.test_control_message("usage_request", {})
145+
assert reply["header"]["msg_type"] == "usage_reply"

tests/test_kernelapp.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@
1212
from .conftest import MockKernel
1313
from .utils import TemporaryWorkingDirectory
1414

15-
try:
16-
import trio
17-
except ImportError:
18-
trio = None
19-
2015

2116
@pytest.mark.skipif(os.name == "nt", reason="requires ipc")
2217
def test_init_ipc_socket():
@@ -118,21 +113,22 @@ def test_merge_connection_file():
118113
os.remove(cf)
119114

120115

121-
# FIXME: @pytest.mark.skipif(trio is None, reason="requires trio")
122-
@pytest.mark.skip()
123-
def test_trio_loop():
116+
@pytest.mark.skip("Something wrong with CI")
117+
@pytest.mark.parametrize("anyio_backend", ["trio"])
118+
async def test_trio_loop(anyio_backend):
119+
import trio
120+
124121
app = IPKernelApp(trio_loop=True)
125122

126-
def trigger_stop():
127-
time.sleep(1)
123+
async def trigger_stop():
124+
await trio.sleep(1)
128125
app.stop()
129126

130-
thread = threading.Thread(target=trigger_stop)
131-
thread.start()
132-
133127
app.kernel = MockKernel()
134128
app.init_sockets()
135-
app.start()
129+
async with trio.open_nursery() as nursery:
130+
nursery.start_soon(app._start)
131+
nursery.start_soon(trigger_stop)
136132
app.cleanup_connection_file()
137133
app.kernel.destroy()
138134
app.close()

0 commit comments

Comments
 (0)