Skip to content

Commit

Permalink
use ensure_event_loop
Browse files Browse the repository at this point in the history
  • Loading branch information
blink1073 committed Jan 6, 2024
1 parent cf7eec0 commit a8144ab
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 32 deletions.
8 changes: 4 additions & 4 deletions jupyter_client/ioloop/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import asyncio
import typing as t

from jupyter_core.utils import ensure_event_loop
from traitlets import Instance, Type

from ..manager import AsyncKernelManager, KernelManager
from ..utils import get_event_loop
from .restarter import AsyncIOLoopKernelRestarter, IOLoopKernelRestarter


Expand All @@ -17,7 +17,7 @@ class IOLoopKernelManager(KernelManager):
loop = Instance(asyncio.AbstractEventLoop)

def _loop_default(self) -> asyncio.AbstractEventLoop:
return get_event_loop()
return ensure_event_loop()

restarter_class = Type(
default_value=IOLoopKernelRestarter,
Expand Down Expand Up @@ -52,7 +52,7 @@ class AsyncIOLoopKernelManager(AsyncKernelManager):
loop = Instance(asyncio.AbstractEventLoop)

def _loop_default(self) -> asyncio.AbstractEventLoop:
return get_event_loop()
return ensure_event_loop()

restarter_class = Type(
default_value=AsyncIOLoopKernelRestarter,
Expand All @@ -73,7 +73,7 @@ def start_restarter(self) -> None:
if self.autorestart and self.has_kernel:
if self._restarter is None:
self._restarter = self.restarter_class(
kernel_manager=self, loop=self.loop, parent=self, log=self.log
kernel_manager=self, parent=self, log=self.log
)
self._restarter.start()

Expand Down
5 changes: 2 additions & 3 deletions jupyter_client/kernelapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
import uuid

from jupyter_core.application import JupyterApp, base_flags
from jupyter_core.utils import ensure_event_loop
from traitlets import Unicode

from jupyter_client.utils import get_event_loop

from . import __version__
from .kernelspec import NATIVE_KERNEL_NAME, KernelSpecManager
from .manager import KernelManager
Expand Down Expand Up @@ -41,7 +40,7 @@ def initialize(self, argv: t.Union[str, t.Sequence[str], None] = None) -> None:
"connection_file", os.path.join(self.runtime_dir, cf_basename)
)
self.km = KernelManager(kernel_name=self.kernel_name, config=self.config)
self.loop = get_event_loop()
self.loop = ensure_event_loop()
self.loop.call_soon(self._record_started)

def setup_signals(self) -> None:
Expand Down
18 changes: 0 additions & 18 deletions jupyter_client/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
"""
from __future__ import annotations

import asyncio
import os
import warnings
from typing import Sequence

from jupyter_core.utils import ensure_async, run_sync # noqa: F401 # noqa: F401
Expand Down Expand Up @@ -90,19 +88,3 @@ def _expand_path(s: str) -> str:
if os.name == "nt":
s = s.replace("IPYTHON_TEMP", "$\\")
return s


def get_event_loop() -> asyncio.AbstractEventLoop:
# Get the loop for this thread.
# In Python 3.12, a deprecation warning is raised, which
# may later turn into a RuntimeError. We handle both
# cases.
# TODO: handle loop factory, and migrate to jupyter_core
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
return loop
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ classifiers = [
requires-python = ">=3.8"
dependencies = [
"importlib_metadata>=4.8.3;python_version<\"3.10\"",
"jupyter_core>=4.12,!=5.0.*",
"jupyter_core>=5.7",
"python-dateutil>=2.8.2",
"pyzmq>=23.0",
"traitlets>=5.3",
Expand Down
9 changes: 3 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import asyncio
import gc
import os

if os.name == "nt":
# TODO: move this logic into get_event_loop?
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) # type:ignore

import pytest

# Must be set before importing from `jupyter_core`.
Expand All @@ -16,4 +12,5 @@

@pytest.fixture(autouse=True)
def setup_environ(jp_environ):
pass
yield
gc.collect()
8 changes: 8 additions & 0 deletions tests/test_kernelmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ def test_signal_kernel_subprocesses(self, name, install, expected):
expected = [expected]

assert km._shutdown_status in expected
assert km.context.closed

@pytest.mark.skipif(sys.platform == "win32", reason="Windows doesn't support signals")
@pytest.mark.parametrize(*parameters)
Expand All @@ -158,6 +159,7 @@ async def test_async_signal_kernel_subprocesses(self, name, install, expected):
expected = [expected]

assert km._shutdown_status in expected
assert km.context.closed


class TestKernelManager:
Expand Down Expand Up @@ -231,12 +233,18 @@ async def execute(cmd):
break
# verify that subprocesses were interrupted
assert reply["user_expressions"]["poll"] == [-signal.SIGINT] * N
kc.stop_channels()
await km.shutdown_kernel(now=True)
assert km.context.closed

async def test_start_new_kernel(self, install_kernel, jp_start_kernel):
km, kc = await jp_start_kernel("signaltest")
assert await km.is_alive()
assert await kc.is_alive()
assert km.context.closed is False
kc.stop_channels()
await km.shutdown_kernel(now=True)
assert km.context.closed

async def _env_test_body(self, kc):
async def execute(cmd):
Expand Down

0 comments on commit a8144ab

Please sign in to comment.