From 44ccd8bbd7496e91e668098577567aba3281d21c Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Sun, 24 Dec 2023 13:56:58 +0100 Subject: [PATCH 1/6] Improve typing by ignoring less --- .pre-commit-config.yaml | 12 ++++++------ jupyter_client/connect.py | 2 +- jupyter_client/manager.py | 28 ++++++++++++++-------------- jupyter_client/multikernelmanager.py | 12 ++++++------ jupyter_client/runapp.py | 4 ++-- jupyter_client/ssh/tunnel.py | 4 ++-- tests/problemkernel.py | 2 +- tests/signalkernel.py | 2 +- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4e593929..e811f337 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,23 +21,23 @@ repos: - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.27.2 + rev: "0.27.2" hooks: - id: check-github-workflows - repo: https://github.com/executablebooks/mdformat - rev: 0.7.17 + rev: "0.7.17" hooks: - id: mdformat - repo: https://github.com/pre-commit/mirrors-prettier - rev: "v3.0.3" + rev: v3.0.3 hooks: - id: prettier types_or: [yaml, html, json] - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.7.1" + rev: v1.7.1 hooks: - id: mypy files: jupyter_client @@ -53,13 +53,13 @@ repos: additional_dependencies: [black==23.7.0] - repo: https://github.com/codespell-project/codespell - rev: "v2.2.6" + rev: v2.2.6 hooks: - id: codespell args: ["-L", "sur,nd"] - repo: https://github.com/pre-commit/pygrep-hooks - rev: "v1.10.0" + rev: v1.10.0 hooks: - id: rst-backticks - id: rst-directive-colons diff --git a/jupyter_client/connect.py b/jupyter_client/connect.py index a634be3d..a1907bd9 100644 --- a/jupyter_client/connect.py +++ b/jupyter_client/connect.py @@ -547,7 +547,7 @@ def load_connection_info(self, info: KernelConnectionInfo) -> None: See the connection_file spec for details. """ self.transport = info.get("transport", self.transport) - self.ip = info.get("ip", self._ip_default()) # type:ignore[assignment] + self.ip = info.get("ip", self._ip_default()) self._record_random_port_names() for name in port_names: diff --git a/jupyter_client/manager.py b/jupyter_client/manager.py index 088acd6c..9b98406d 100644 --- a/jupyter_client/manager.py +++ b/jupyter_client/manager.py @@ -733,20 +733,20 @@ def client( # type:ignore[override] """Get a client for the manager.""" return super().client(**kwargs) # type:ignore[return-value] - _launch_kernel = KernelManager._async_launch_kernel # type:ignore[assignment] - start_kernel: t.Callable[..., t.Awaitable] = KernelManager._async_start_kernel # type:ignore[assignment] - pre_start_kernel: t.Callable[..., t.Awaitable] = KernelManager._async_pre_start_kernel # type:ignore[assignment] - post_start_kernel: t.Callable[..., t.Awaitable] = KernelManager._async_post_start_kernel # type:ignore[assignment] - request_shutdown: t.Callable[..., t.Awaitable] = KernelManager._async_request_shutdown # type:ignore[assignment] - finish_shutdown: t.Callable[..., t.Awaitable] = KernelManager._async_finish_shutdown # type:ignore[assignment] - cleanup_resources: t.Callable[..., t.Awaitable] = KernelManager._async_cleanup_resources # type:ignore[assignment] - shutdown_kernel: t.Callable[..., t.Awaitable] = KernelManager._async_shutdown_kernel # type:ignore[assignment] - restart_kernel: t.Callable[..., t.Awaitable] = KernelManager._async_restart_kernel # type:ignore[assignment] - _send_kernel_sigterm = KernelManager._async_send_kernel_sigterm # type:ignore[assignment] - _kill_kernel = KernelManager._async_kill_kernel # type:ignore[assignment] - interrupt_kernel: t.Callable[..., t.Awaitable] = KernelManager._async_interrupt_kernel # type:ignore[assignment] - signal_kernel: t.Callable[..., t.Awaitable] = KernelManager._async_signal_kernel # type:ignore[assignment] - is_alive: t.Callable[..., t.Awaitable] = KernelManager._async_is_alive # type:ignore[assignment] + _launch_kernel = KernelManager._async_launch_kernel + start_kernel = KernelManager._async_start_kernel + pre_start_kernel = KernelManager._async_pre_start_kernel + post_start_kernel = KernelManager._async_post_start_kernel + request_shutdown = KernelManager._async_request_shutdown + finish_shutdown = KernelManager._async_finish_shutdown + cleanup_resources = KernelManager._async_cleanup_resources + shutdown_kernel = KernelManager._async_shutdown_kernel + restart_kernel = KernelManager._async_restart_kernel + _send_kernel_sigterm = KernelManager._async_send_kernel_sigterm + _kill_kernel = KernelManager._async_kill_kernel + interrupt_kernel = KernelManager._async_interrupt_kernel + signal_kernel = KernelManager._async_signal_kernel + is_alive = KernelManager._async_is_alive KernelManagerABC.register(KernelManager) diff --git a/jupyter_client/multikernelmanager.py b/jupyter_client/multikernelmanager.py index d14a3f84..d553a1f1 100644 --- a/jupyter_client/multikernelmanager.py +++ b/jupyter_client/multikernelmanager.py @@ -226,7 +226,7 @@ def update_env(self, *, kernel_id: str, env: t.Dict[str, str]) -> None: self._kernels[kernel_id].update_env(env=env) async def _add_kernel_when_ready( - self, kernel_id: str, km: KernelManager, kernel_awaitable: t.Awaitable + self, kernel_id: str, km: KernelManager, kernel_awaitable: t.Awaitable[t.Any] ) -> None: try: await kernel_awaitable @@ -236,7 +236,7 @@ async def _add_kernel_when_ready( self.log.exception(e) async def _remove_kernel_when_ready( - self, kernel_id: str, kernel_awaitable: t.Awaitable + self, kernel_id: str, kernel_awaitable: t.Awaitable[t.Any] ) -> None: try: await kernel_awaitable @@ -618,7 +618,7 @@ def _context_default(self) -> zmq.asyncio.Context: self._created_context = True return zmq.asyncio.Context() - start_kernel: t.Callable[..., t.Awaitable] = MultiKernelManager._async_start_kernel # type:ignore[assignment] - restart_kernel: t.Callable[..., t.Awaitable] = MultiKernelManager._async_restart_kernel # type:ignore[assignment] - shutdown_kernel: t.Callable[..., t.Awaitable] = MultiKernelManager._async_shutdown_kernel # type:ignore[assignment] - shutdown_all: t.Callable[..., t.Awaitable] = MultiKernelManager._async_shutdown_all # type:ignore[assignment] + start_kernel = MultiKernelManager._async_start_kernel + restart_kernel = MultiKernelManager._async_restart_kernel + shutdown_kernel = MultiKernelManager._async_shutdown_kernel + shutdown_all = MultiKernelManager._async_shutdown_all diff --git a/jupyter_client/runapp.py b/jupyter_client/runapp.py index 9ed4b154..2d4ef812 100644 --- a/jupyter_client/runapp.py +++ b/jupyter_client/runapp.py @@ -44,8 +44,8 @@ class RunApp(JupyterApp, JupyterConsoleApp): # type:ignore[misc] version = __version__ name = "jupyter run" description = """Run Jupyter kernel code.""" - flags = Dict(flags) # type:ignore[assignment] - aliases = Dict(aliases) # type:ignore[assignment] + flags = Dict(flags) + aliases = Dict(aliases) frontend_aliases = Any(frontend_aliases) frontend_flags = Any(frontend_flags) kernel_timeout = Float( diff --git a/jupyter_client/ssh/tunnel.py b/jupyter_client/ssh/tunnel.py index 3b1b533c..f58ee841 100644 --- a/jupyter_client/ssh/tunnel.py +++ b/jupyter_client/ssh/tunnel.py @@ -25,9 +25,9 @@ SSHException = paramiko.ssh_exception.SSHException except ImportError: - paramiko = None # type:ignore[assignment] + paramiko = None - class SSHException(Exception): # type:ignore[no-redef] # noqa + class SSHException(Exception): # noqa: N818 pass else: diff --git a/tests/problemkernel.py b/tests/problemkernel.py index a20cf708..a55648f5 100644 --- a/tests/problemkernel.py +++ b/tests/problemkernel.py @@ -18,7 +18,7 @@ class ProblemTestKernel(Kernel): class ProblemTestApp(IPKernelApp): - kernel_class = ProblemTestKernel # type:ignore[assignment] + kernel_class = ProblemTestKernel def init_io(self): # Overridden to disable stdout/stderr capture diff --git a/tests/signalkernel.py b/tests/signalkernel.py index 65fdb687..887d4d32 100644 --- a/tests/signalkernel.py +++ b/tests/signalkernel.py @@ -62,7 +62,7 @@ def do_execute( class SignalTestApp(IPKernelApp): - kernel_class = SignalTestKernel # type:ignore[assignment] + kernel_class = SignalTestKernel def init_io(self): # Overridden to disable stdout/stderr capture From 152684b8ae9a789a55dcfe021fab5347ba05a966 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Sun, 24 Dec 2023 14:03:41 +0100 Subject: [PATCH 2/6] oops --- jupyter_client/connect.py | 2 +- jupyter_client/runapp.py | 4 ++-- jupyter_client/ssh/tunnel.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jupyter_client/connect.py b/jupyter_client/connect.py index a1907bd9..a634be3d 100644 --- a/jupyter_client/connect.py +++ b/jupyter_client/connect.py @@ -547,7 +547,7 @@ def load_connection_info(self, info: KernelConnectionInfo) -> None: See the connection_file spec for details. """ self.transport = info.get("transport", self.transport) - self.ip = info.get("ip", self._ip_default()) + self.ip = info.get("ip", self._ip_default()) # type:ignore[assignment] self._record_random_port_names() for name in port_names: diff --git a/jupyter_client/runapp.py b/jupyter_client/runapp.py index 2d4ef812..9ed4b154 100644 --- a/jupyter_client/runapp.py +++ b/jupyter_client/runapp.py @@ -44,8 +44,8 @@ class RunApp(JupyterApp, JupyterConsoleApp): # type:ignore[misc] version = __version__ name = "jupyter run" description = """Run Jupyter kernel code.""" - flags = Dict(flags) - aliases = Dict(aliases) + flags = Dict(flags) # type:ignore[assignment] + aliases = Dict(aliases) # type:ignore[assignment] frontend_aliases = Any(frontend_aliases) frontend_flags = Any(frontend_flags) kernel_timeout = Float( diff --git a/jupyter_client/ssh/tunnel.py b/jupyter_client/ssh/tunnel.py index f58ee841..ac36d295 100644 --- a/jupyter_client/ssh/tunnel.py +++ b/jupyter_client/ssh/tunnel.py @@ -25,9 +25,9 @@ SSHException = paramiko.ssh_exception.SSHException except ImportError: - paramiko = None + paramiko = None # type:ignore[assignment] - class SSHException(Exception): # noqa: N818 + class SSHException(Exception): # type:ignore[assignment] # noqa: N818 pass else: From 72c6a35211fa9e0ecfe1c5b87b1b351d74061c60 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Sun, 24 Dec 2023 14:14:17 +0100 Subject: [PATCH 3/6] fix --- jupyter_client/manager.py | 77 ++++++++++++---------------- jupyter_client/multikernelmanager.py | 27 +++++----- jupyter_client/ssh/tunnel.py | 2 +- 3 files changed, 47 insertions(+), 59 deletions(-) diff --git a/jupyter_client/manager.py b/jupyter_client/manager.py index 9b98406d..955f1238 100644 --- a/jupyter_client/manager.py +++ b/jupyter_client/manager.py @@ -98,7 +98,7 @@ async def wrapper(self: t.Any, *args: t.Any, **kwargs: t.Any) -> t.Any: return t.cast(F, wrapper) -class KernelManager(ConnectionFileMixin): +class _KernelManagerBase(ConnectionFileMixin): """Manages a single kernel in a subprocess on this host. This version starts kernels with Popen. @@ -357,8 +357,6 @@ async def _async_launch_kernel(self, kernel_cmd: t.List[str], **kw: t.Any) -> No # and write the connection file, if not already done. self._reconcile_connection_info(connection_info) - _launch_kernel = run_sync(_async_launch_kernel) - # Control socket used for polite kernel shutdown def _connect_control_socket(self) -> None: @@ -401,8 +399,6 @@ async def _async_pre_start_kernel( kernel_cmd = kw.pop("cmd") return kernel_cmd, kw - pre_start_kernel = run_sync(_async_pre_start_kernel) - async def _async_post_start_kernel(self, **kw: t.Any) -> None: """Performs any post startup tasks relative to the kernel. @@ -416,8 +412,6 @@ async def _async_post_start_kernel(self, **kw: t.Any) -> None: assert self.provisioner is not None await self.provisioner.post_launch(**kw) - post_start_kernel = run_sync(_async_post_start_kernel) - @in_pending_state async def _async_start_kernel(self, **kw: t.Any) -> None: """Starts a kernel on this host in a separate process. @@ -439,8 +433,6 @@ async def _async_start_kernel(self, **kw: t.Any) -> None: await self._async_launch_kernel(kernel_cmd, **kw) await self._async_post_start_kernel(**kw) - start_kernel = run_sync(_async_start_kernel) - async def _async_request_shutdown(self, restart: bool = False) -> None: """Send a shutdown request via control channel""" content = {"restart": restart} @@ -452,8 +444,6 @@ async def _async_request_shutdown(self, restart: bool = False) -> None: await self.provisioner.shutdown_requested(restart=restart) self._shutdown_status = _ShutdownStatus.ShutdownRequest - request_shutdown = run_sync(_async_request_shutdown) - async def _async_finish_shutdown( self, waittime: t.Optional[float] = None, @@ -493,8 +483,6 @@ async def _async_finish_shutdown( assert self.provisioner is not None await self.provisioner.wait() - finish_shutdown = run_sync(_async_finish_shutdown) - async def _async_cleanup_resources(self, restart: bool = False) -> None: """Clean up resources when the kernel is shut down""" if not restart: @@ -510,8 +498,6 @@ async def _async_cleanup_resources(self, restart: bool = False) -> None: if self.provisioner: await self.provisioner.cleanup(restart=restart) - cleanup_resources = run_sync(_async_cleanup_resources) - @in_pending_state async def _async_shutdown_kernel(self, now: bool = False, restart: bool = False) -> None: """Attempts to stop the kernel process cleanly. @@ -552,8 +538,6 @@ async def _async_shutdown_kernel(self, now: bool = False, restart: bool = False) await self._async_cleanup_resources(restart=restart) - shutdown_kernel = run_sync(_async_shutdown_kernel) - async def _async_restart_kernel( self, now: bool = False, newports: bool = False, **kw: t.Any ) -> None: @@ -595,8 +579,6 @@ async def _async_restart_kernel( self._launch_args.update(kw) await self._async_start_kernel(**self._launch_args) - restart_kernel = run_sync(_async_restart_kernel) - @property def owns_kernel(self) -> bool: return self._owns_kernel @@ -612,8 +594,6 @@ async def _async_send_kernel_sigterm(self, restart: bool = False) -> None: assert self.provisioner is not None await self.provisioner.terminate(restart=restart) - _send_kernel_sigterm = run_sync(_async_send_kernel_sigterm) - async def _async_kill_kernel(self, restart: bool = False) -> None: """Kill the running kernel. @@ -635,8 +615,6 @@ async def _async_kill_kernel(self, restart: bool = False) -> None: if self.has_kernel: await self.provisioner.wait() - _kill_kernel = run_sync(_async_kill_kernel) - async def _async_interrupt_kernel(self) -> None: """Interrupts the kernel by sending it a signal. @@ -668,8 +646,6 @@ async def _async_interrupt_kernel(self) -> None: msg = "Cannot interrupt kernel. No kernel is running!" raise RuntimeError(msg) - interrupt_kernel = run_sync(_async_interrupt_kernel) - async def _async_signal_kernel(self, signum: int) -> None: """Sends a signal to the process group of the kernel (this usually includes the kernel and any subprocesses spawned by @@ -685,8 +661,6 @@ async def _async_signal_kernel(self, signum: int) -> None: msg = "Cannot signal kernel. No kernel is running!" raise RuntimeError(msg) - signal_kernel = run_sync(_async_signal_kernel) - async def _async_is_alive(self) -> bool: """Is the kernel process still running?""" if not self.owns_kernel: @@ -699,8 +673,6 @@ async def _async_is_alive(self) -> bool: return True return False - is_alive = run_sync(_async_is_alive) - async def _async_wait(self, pollinterval: float = 0.1) -> None: # Use busy loop at 100ms intervals, polling until the process is # not alive. If we find the process is no longer alive, complete @@ -710,7 +682,24 @@ async def _async_wait(self, pollinterval: float = 0.1) -> None: await asyncio.sleep(pollinterval) -class AsyncKernelManager(KernelManager): +class KernelManager(_KernelManagerBase): + _launch_kernel = run_sync(_KernelManagerBase._async_launch_kernel) + start_kernel = run_sync(_KernelManagerBase._async_start_kernel) + pre_start_kernel = run_sync(_KernelManagerBase._async_pre_start_kernel) + post_start_kernel = run_sync(_KernelManagerBase._async_post_start_kernel) + request_shutdown = run_sync(_KernelManagerBase._async_request_shutdown) + finish_shutdown = run_sync(_KernelManagerBase._async_finish_shutdown) + cleanup_resources = run_sync(_KernelManagerBase._async_cleanup_resources) + shutdown_kernel = run_sync(_KernelManagerBase._async_shutdown_kernel) + restart_kernel = run_sync(_KernelManagerBase._async_restart_kernel) + _send_kernel_sigterm = run_sync(_KernelManagerBase._async_send_kernel_sigterm) + _kill_kernel = run_sync(_KernelManagerBase._async_kill_kernel) + interrupt_kernel = run_sync(_KernelManagerBase._async_interrupt_kernel) + signal_kernel = run_sync(_KernelManagerBase._async_signal_kernel) + is_alive = run_sync(_KernelManagerBase._async_is_alive) + + +class AsyncKernelManager(_KernelManagerBase): """An async kernel manager.""" # the class to create with our `client` method @@ -733,20 +722,20 @@ def client( # type:ignore[override] """Get a client for the manager.""" return super().client(**kwargs) # type:ignore[return-value] - _launch_kernel = KernelManager._async_launch_kernel - start_kernel = KernelManager._async_start_kernel - pre_start_kernel = KernelManager._async_pre_start_kernel - post_start_kernel = KernelManager._async_post_start_kernel - request_shutdown = KernelManager._async_request_shutdown - finish_shutdown = KernelManager._async_finish_shutdown - cleanup_resources = KernelManager._async_cleanup_resources - shutdown_kernel = KernelManager._async_shutdown_kernel - restart_kernel = KernelManager._async_restart_kernel - _send_kernel_sigterm = KernelManager._async_send_kernel_sigterm - _kill_kernel = KernelManager._async_kill_kernel - interrupt_kernel = KernelManager._async_interrupt_kernel - signal_kernel = KernelManager._async_signal_kernel - is_alive = KernelManager._async_is_alive + _launch_kernel = _KernelManagerBase._async_launch_kernel + start_kernel = _KernelManagerBase._async_start_kernel + pre_start_kernel = _KernelManagerBase._async_pre_start_kernel + post_start_kernel = _KernelManagerBase._async_post_start_kernel + request_shutdown = _KernelManagerBase._async_request_shutdown + finish_shutdown = _KernelManagerBase._async_finish_shutdown + cleanup_resources = _KernelManagerBase._async_cleanup_resources + shutdown_kernel = _KernelManagerBase._async_shutdown_kernel + restart_kernel = _KernelManagerBase._async_restart_kernel + _send_kernel_sigterm = _KernelManagerBase._async_send_kernel_sigterm + _kill_kernel = _KernelManagerBase._async_kill_kernel + interrupt_kernel = _KernelManagerBase._async_interrupt_kernel + signal_kernel = _KernelManagerBase._async_signal_kernel + is_alive = _KernelManagerBase._async_is_alive KernelManagerABC.register(KernelManager) diff --git a/jupyter_client/multikernelmanager.py b/jupyter_client/multikernelmanager.py index d553a1f1..18841d2a 100644 --- a/jupyter_client/multikernelmanager.py +++ b/jupyter_client/multikernelmanager.py @@ -48,7 +48,7 @@ def wrapped( return wrapped -class MultiKernelManager(LoggingConfigurable): +class _MultiKernelManagerBase(LoggingConfigurable): """A class for managing multiple kernels.""" default_kernel_name = Unicode( @@ -284,8 +284,6 @@ async def _async_start_kernel(self, *, kernel_name: str | None = None, **kwargs: return kernel_id - start_kernel = run_sync(_async_start_kernel) - async def _async_shutdown_kernel( self, kernel_id: str, @@ -331,8 +329,6 @@ async def _async_shutdown_kernel( if km.ready.exception(): raise km.ready.exception() # type: ignore[misc] - shutdown_kernel = run_sync(_async_shutdown_kernel) - @kernel_method def request_shutdown(self, kernel_id: str, restart: bool | None = False) -> None: """Ask a kernel to shut down by its kernel uuid""" @@ -379,8 +375,6 @@ async def _async_shutdown_all(self, now: bool = False) -> None: # Will have been logged in _add_kernel_when_ready pass - shutdown_all = run_sync(_async_shutdown_all) - def interrupt_kernel(self, kernel_id: str) -> None: """Interrupt (SIGINT) the kernel by its uuid. @@ -435,8 +429,6 @@ async def _async_restart_kernel(self, kernel_id: str, now: bool = False) -> None await ensure_async(kernel.restart_kernel(now=now)) self.log.info("Kernel restarted: %s", kernel_id) - restart_kernel = run_sync(_async_restart_kernel) - @kernel_method def is_alive(self, kernel_id: str) -> bool: # type:ignore[empty-body] """Is the kernel alive. @@ -596,7 +588,14 @@ def new_kernel_id(self, **kwargs: t.Any) -> str: return str(uuid.uuid4()) -class AsyncMultiKernelManager(MultiKernelManager): +class MultiKernelManager(_MultiKernelManagerBase): + start_kernel = run_sync(_MultiKernelManagerBase._async_start_kernel) + restart_kernel = run_sync(_MultiKernelManagerBase._async_restart_kernel) + shutdown_kernel = run_sync(_MultiKernelManagerBase._async_shutdown_kernel) + shutdown_all = run_sync(_MultiKernelManagerBase._async_shutdown_all) + + +class AsyncMultiKernelManager(_MultiKernelManagerBase): kernel_manager_class = DottedObjectName( "jupyter_client.ioloop.AsyncIOLoopKernelManager", config=True, @@ -618,7 +617,7 @@ def _context_default(self) -> zmq.asyncio.Context: self._created_context = True return zmq.asyncio.Context() - start_kernel = MultiKernelManager._async_start_kernel - restart_kernel = MultiKernelManager._async_restart_kernel - shutdown_kernel = MultiKernelManager._async_shutdown_kernel - shutdown_all = MultiKernelManager._async_shutdown_all + start_kernel = _MultiKernelManagerBase._async_start_kernel + restart_kernel = _MultiKernelManagerBase._async_restart_kernel + shutdown_kernel = _MultiKernelManagerBase._async_shutdown_kernel + shutdown_all = _MultiKernelManagerBase._async_shutdown_all diff --git a/jupyter_client/ssh/tunnel.py b/jupyter_client/ssh/tunnel.py index ac36d295..c95e2790 100644 --- a/jupyter_client/ssh/tunnel.py +++ b/jupyter_client/ssh/tunnel.py @@ -27,7 +27,7 @@ except ImportError: paramiko = None # type:ignore[assignment] - class SSHException(Exception): # type:ignore[assignment] # noqa: N818 + class SSHException(Exception): # type:ignore[no-redef] # noqa: N818 pass else: From 881d050390fac7891ca3ccdeab8adb171a27b531 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 26 Dec 2023 17:02:28 +0100 Subject: [PATCH 4/6] More remaining overridden members --- jupyter_client/manager.py | 44 +++++++++++++++++++++++-------------- jupyter_client/restarter.py | 2 +- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/jupyter_client/manager.py b/jupyter_client/manager.py index 955f1238..eb98f5ee 100644 --- a/jupyter_client/manager.py +++ b/jupyter_client/manager.py @@ -36,6 +36,7 @@ from .asynchronous import AsyncKernelClient from .blocking import BlockingKernelClient from .client import KernelClient +from .clientabc import KernelClientABC from .connect import ConnectionFileMixin from .managerabc import KernelManagerABC from .provisioning import KernelProvisionerBase @@ -58,6 +59,7 @@ class _ShutdownStatus(Enum): F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +KernelClientBound = t.TypeVar("KernelClientBound", bound=KernelClientABC) def _get_future() -> t.Union[Future, CFuture]: @@ -98,7 +100,7 @@ async def wrapper(self: t.Any, *args: t.Any, **kwargs: t.Any) -> t.Any: return t.cast(F, wrapper) -class _KernelManagerBase(ConnectionFileMixin): +class _KernelManagerBase(ConnectionFileMixin, t.Generic[KernelClientBound]): """Manages a single kernel in a subprocess on this host. This version starts kernels with Popen. @@ -126,18 +128,15 @@ def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: _created_context: Bool = Bool(False) # The PyZMQ Context to use for communication with the kernel. - context: Instance = Instance(zmq.Context) + context: Instance @default("context") def _context_default(self) -> zmq.Context: - self._created_context = True - return zmq.Context() + raise NotImplementedError # the class to create with our `client` method - client_class: DottedObjectName = DottedObjectName( - "jupyter_client.blocking.BlockingKernelClient" - ) - client_factory: Type = Type(klass=KernelClient) + client_class: DottedObjectName + client_factory: Type @default("client_factory") def _client_factory_default(self) -> Type: @@ -260,7 +259,7 @@ def remove_restart_callback(self, callback: t.Callable, event: str = "restart") # create a Client connected to our Kernel # -------------------------------------------------------------------------- - def client(self, **kwargs: t.Any) -> BlockingKernelClient: + def client(self, **kwargs: t.Any) -> KernelClientBound: """Create a client configured to connect to our kernel""" kw: dict = {} kw.update(self.get_connection_info(session=True)) @@ -682,7 +681,23 @@ async def _async_wait(self, pollinterval: float = 0.1) -> None: await asyncio.sleep(pollinterval) -class KernelManager(_KernelManagerBase): +class KernelManager(_KernelManagerBase[BlockingKernelClient]): + """A blocking kernel manager.""" + + # the class to create with our `client` method + client_class: DottedObjectName = DottedObjectName( + "jupyter_client.blocking.BlockingKernelClient" + ) + client_factory: Type = Type(klass=KernelClient) + + # The PyZMQ Context to use for communication with the kernel. + context: Instance = Instance(zmq.Context) + + @default("context") + def _context_default(self) -> zmq.Context: + self._created_context = True + return zmq.Context() + _launch_kernel = run_sync(_KernelManagerBase._async_launch_kernel) start_kernel = run_sync(_KernelManagerBase._async_start_kernel) pre_start_kernel = run_sync(_KernelManagerBase._async_pre_start_kernel) @@ -699,7 +714,7 @@ class KernelManager(_KernelManagerBase): is_alive = run_sync(_KernelManagerBase._async_is_alive) -class AsyncKernelManager(_KernelManagerBase): +class AsyncKernelManager(_KernelManagerBase[AsyncKernelClient]): """An async kernel manager.""" # the class to create with our `client` method @@ -716,12 +731,6 @@ def _context_default(self) -> zmq.asyncio.Context: self._created_context = True return zmq.asyncio.Context() - def client( # type:ignore[override] - self, **kwargs: t.Any - ) -> AsyncKernelClient: - """Get a client for the manager.""" - return super().client(**kwargs) # type:ignore[return-value] - _launch_kernel = _KernelManagerBase._async_launch_kernel start_kernel = _KernelManagerBase._async_start_kernel pre_start_kernel = _KernelManagerBase._async_pre_start_kernel @@ -739,6 +748,7 @@ def client( # type:ignore[override] KernelManagerABC.register(KernelManager) +KernelManagerABC.register(AsyncKernelManager) def start_new_kernel( diff --git a/jupyter_client/restarter.py b/jupyter_client/restarter.py index d41890f6..b7230559 100644 --- a/jupyter_client/restarter.py +++ b/jupyter_client/restarter.py @@ -19,7 +19,7 @@ class KernelRestarter(LoggingConfigurable): """Monitor and autorestart a kernel.""" - kernel_manager = Instance("jupyter_client.KernelManager") + kernel_manager = Instance("jupyter_client.managerabc.KernelManagerABC") debug = Bool( False, From de1d9d5e1a05ac5a493525083ae727e4355788ab Mon Sep 17 00:00:00 2001 From: Philipp A Date: Thu, 4 Jan 2024 15:57:45 +0100 Subject: [PATCH 5/6] Discard changes to .pre-commit-config.yaml --- .pre-commit-config.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e811f337..4e593929 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,23 +21,23 @@ repos: - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: "0.27.2" + rev: 0.27.2 hooks: - id: check-github-workflows - repo: https://github.com/executablebooks/mdformat - rev: "0.7.17" + rev: 0.7.17 hooks: - id: mdformat - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.3 + rev: "v3.0.3" hooks: - id: prettier types_or: [yaml, html, json] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.7.1 + rev: "v1.7.1" hooks: - id: mypy files: jupyter_client @@ -53,13 +53,13 @@ repos: additional_dependencies: [black==23.7.0] - repo: https://github.com/codespell-project/codespell - rev: v2.2.6 + rev: "v2.2.6" hooks: - id: codespell args: ["-L", "sur,nd"] - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.10.0 + rev: "v1.10.0" hooks: - id: rst-backticks - id: rst-directive-colons From ca019c367fbd8b10b976fd48ac9726af37cf3731 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 4 Jan 2024 16:18:40 +0100 Subject: [PATCH 6/6] fix client_factory --- jupyter_client/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jupyter_client/manager.py b/jupyter_client/manager.py index eb98f5ee..2c571262 100644 --- a/jupyter_client/manager.py +++ b/jupyter_client/manager.py @@ -688,7 +688,7 @@ class KernelManager(_KernelManagerBase[BlockingKernelClient]): client_class: DottedObjectName = DottedObjectName( "jupyter_client.blocking.BlockingKernelClient" ) - client_factory: Type = Type(klass=KernelClient) + client_factory: Type = Type(klass=BlockingKernelClient) # The PyZMQ Context to use for communication with the kernel. context: Instance = Instance(zmq.Context)