From 2ff2fcb43fef172f5543a60d6d2cf9a79295630e Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 19 Oct 2022 17:06:09 -0500 Subject: [PATCH] Backport PR #858: Defer creation of ready future --- jupyter_client/manager.py | 30 ++++++++++++++++-------------- pyproject.toml | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/jupyter_client/manager.py b/jupyter_client/manager.py index 531435045..fe404eebc 100644 --- a/jupyter_client/manager.py +++ b/jupyter_client/manager.py @@ -55,6 +55,16 @@ class _ShutdownStatus(Enum): F = t.TypeVar('F', bound=t.Callable[..., t.Any]) +def _get_future() -> t.Union[Future, CFuture]: + """Get an appropriate Future object""" + try: + asyncio.get_running_loop() + return Future() + except RuntimeError: + # No event loop running, use concurrent future + return CFuture() + + def in_pending_state(method: F) -> F: """Sets the kernel to a pending state by creating a fresh Future for the KernelManager's `ready` @@ -65,12 +75,8 @@ def in_pending_state(method: F) -> F: @functools.wraps(method) async def wrapper(self, *args, **kwargs): # Create a future for the decorated method - if self._attempted_start: - try: - self._ready = Future() - except RuntimeError: - # No event loop running, use concurrent future - self._ready = CFuture() + if self._attempted_start or not self._ready: + self._ready = _get_future() try: # call wrapped method, await, and set the result or exception. out = await method(self, *args, **kwargs) @@ -92,19 +98,13 @@ class KernelManager(ConnectionFileMixin): This version starts kernels with Popen. """ - _ready: t.Union[Future, CFuture] + _ready: t.Optional[t.Union[Future, CFuture]] def __init__(self, *args, **kwargs): super().__init__(**kwargs) self._shutdown_status = _ShutdownStatus.Unset self._attempted_start = False - # Create a place holder future. - try: - asyncio.get_running_loop() - self._ready = Future() - except RuntimeError: - # No event loop running, use concurrent future - self._ready = CFuture() + self._ready = None _created_context: Bool = Bool(False) @@ -189,6 +189,8 @@ def _default_cache_ports(self) -> bool: @property def ready(self) -> t.Union[CFuture, Future]: """A future that resolves when the kernel process has started for the first time""" + if not self._ready: + self._ready = _get_future() return self._ready @property diff --git a/pyproject.toml b/pyproject.toml index 3a290bf20..dd5f93652 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ Homepage = "https://jupyter.org" test = [ "codecov", "coverage", - "ipykernel>=6.5", + "ipykernel>=6.12", "ipython", "mypy", "pre-commit",