From a4385923da79570d58b769e04d073dc18b94171e Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 19 Oct 2022 17:06:09 -0500 Subject: [PATCH] Defer creation of ready future (#858) --- 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 4aa18bba8..c8b062b04 100644 --- a/jupyter_client/manager.py +++ b/jupyter_client/manager.py @@ -54,6 +54,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` @@ -64,12 +74,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) @@ -91,19 +97,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) @@ -188,6 +188,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 df40855ac..4ffa86315 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,7 @@ Homepage = "https://jupyter.org" test = [ "codecov", "coverage", - "ipykernel>=6.5", + "ipykernel>=6.12", "ipython", "mypy", "pre-commit",