From c349a913d34cb39e1fbb0c8caddc35e1ae38457a Mon Sep 17 00:00:00 2001
From: M Bussonnier <bussonniermatthias@gmail.com>
Date: Thu, 17 Oct 2024 10:41:35 +0200
Subject: [PATCH] Misc cleanup and types updates

---
 ipykernel/kernelapp.py  |  7 ++--
 ipykernel/kernelbase.py | 73 +++++++++++++++++++++++++++++++++--------
 2 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/ipykernel/kernelapp.py b/ipykernel/kernelapp.py
index 394f52a47..2e60695e7 100644
--- a/ipykernel/kernelapp.py
+++ b/ipykernel/kernelapp.py
@@ -16,6 +16,7 @@
 from io import FileIO, TextIOWrapper
 from logging import StreamHandler
 from pathlib import Path
+from threading import Thread
 
 import zmq
 import zmq.asyncio
@@ -142,9 +143,9 @@ class IPKernelApp(BaseIPythonApplication, InteractiveShellApp, ConnectionFileMix
     debug_shell_socket = Any()
     stdin_socket = Any()
     iopub_socket = Any()
-    iopub_thread = Any()
-    control_thread = Any()
-    shell_channel_thread = Any()
+    iopub_thread: Thread
+    control_thread: Thread
+    shell_channel_thread: Thread
 
     _ports = Dict()
 
diff --git a/ipykernel/kernelbase.py b/ipykernel/kernelbase.py
index 99358f9b6..189a198ce 100644
--- a/ipykernel/kernelbase.py
+++ b/ipykernel/kernelbase.py
@@ -17,6 +17,7 @@
 import warnings
 from datetime import datetime
 from signal import SIGINT, SIGTERM, Signals
+from threading import Thread
 
 from .thread import CONTROL_THREAD_NAME
 
@@ -95,17 +96,16 @@ class Kernel(SingletonConfigurable):
     implementation_version: str
     banner: str
 
-    _is_test = Bool(False)
+    _is_test: bool = False
 
     control_socket = Instance(zmq.asyncio.Socket, allow_none=True)
     control_tasks: t.Any = List()
 
     debug_shell_socket = Any()
+    control_thread: Thread
+    shell_channel_thread: Thread
 
-    control_thread = Any()
-    shell_channel_thread = Any()
     iopub_socket = Any()
-    iopub_thread = Any()
     stdin_socket = Any()
     log: logging.Logger = Instance(logging.Logger, allow_none=True)  # type:ignore[assignment]
 
@@ -217,6 +217,9 @@ def _parent_header(self):
         "shutdown_request",
         "is_complete_request",
         "interrupt_request",
+        # I have the impression that there is amix/match debug_request and do_debug_request
+        # former was from ipyparallel but is marked as deprecated, but now call do_debug_request
+        # "do_debug_request"
         # deprecated:
         "apply_request",
     ]
@@ -258,6 +261,17 @@ def __init__(self, **kwargs):
             self.do_execute, ["cell_meta", "cell_id"]
         )
 
+        if not inspect.iscoroutinefunction(self.do_debug_request):
+            # warning at init time, as we want to warn early enough, even if the
+            # function is not called
+            warnings.warn(
+                "`do_debug_request` will be required to be a coroutine "
+                "functions in the future. coroutine functions have ben supported "
+                "since ipykernel 6.0 (2021)",
+                DeprecationWarning,
+                stacklevel=2,
+            )
+
     async def process_control(self):
         try:
             while True:
@@ -1007,13 +1021,35 @@ def do_is_complete(self, code):
         return {"status": "unknown"}
 
     async def debug_request(self, socket, ident, parent):
-        """Handle a debug request."""
+        """Handle a debug request.
+
+        Seem Deprecated
+        """
+        # If this is incorrect, remove `debug_request` from the deprecated message types
+        # at the beginning of this class
+        warnings.warn(
+            "debug_request is deprecated in kernel_base since ipykernel 6.10"
+            " (2022). It is only part of IPython parallel. Did you mean do_debug_request ?",
+            DeprecationWarning,
+            stacklevel=2,
+        )
         if not self.session:
             return
         content = parent["content"]
-        reply_content = self.do_debug_request(content)
-        if inspect.isawaitable(reply_content):
-            reply_content = await reply_content
+        if not inspect.iscoroutinefunction(self.do_debug_request):
+            # repeat the warning at run
+            reply_content = self.do_debug_request(content)
+            warnings.warn(
+                "`do_debug_request` will be required to be a coroutine "
+                "functions in the future. coroutine functions have ben supported "
+                "since ipykernel 6.0 (2021)",
+                DeprecationWarning,
+                stacklevel=1,
+            )
+            if inspect.isawaitable(reply_content):
+                reply_content = await reply_content
+        else:
+            reply_content = await self.do_debug_request(content)
         reply_content = json_clean(reply_content)
         reply_msg = self.session.send(socket, "debug_reply", reply_content, parent, ident)
         self.log.debug("%s", reply_msg)
@@ -1132,7 +1168,12 @@ async def list_subshell_request(self, socket, ident, parent) -> None:
 
     async def apply_request(self, socket, ident, parent):  # pragma: no cover
         """Handle an apply request."""
-        self.log.warning("apply_request is deprecated in kernel_base, moving to ipyparallel.")
+        warnings.warn(
+            "apply_request is deprecated in kernel_base since"
+            " IPykernel 6.10 (2022) , moving to ipyparallel.",
+            DeprecationWarning,
+            stacklevel=2,
+        )
         try:
             content = parent["content"]
             bufs = parent["buffers"]
@@ -1174,8 +1215,11 @@ def do_apply(self, content, bufs, msg_id, reply_metadata):
 
     async def abort_request(self, socket, ident, parent):  # pragma: no cover
         """abort a specific msg by id"""
-        self.log.warning(
-            "abort_request is deprecated in kernel_base. It is only part of IPython parallel"
+        warnings.warn(
+            "abort_request is deprecated in kernel_base since ipykernel 6.10"
+            " (2022). It is only part of IPython parallel",
+            DeprecationWarning,
+            stacklevel=2,
         )
         msg_ids = parent["content"].get("msg_ids", None)
         if isinstance(msg_ids, str):
@@ -1193,8 +1237,11 @@ async def abort_request(self, socket, ident, parent):  # pragma: no cover
 
     async def clear_request(self, socket, idents, parent):  # pragma: no cover
         """Clear our namespace."""
-        self.log.warning(
-            "clear_request is deprecated in kernel_base. It is only part of IPython parallel"
+        warnings.warn(
+            "clear_request is deprecated in kernel_base since IPykernel 6.10"
+            " (2022). It is only part of IPython parallel",
+            DeprecationWarning,
+            stacklevel=2,
         )
         content = self.do_clear()
         if self.session: