diff --git a/ipykernel/kernelbase.py b/ipykernel/kernelbase.py index d496e0c91..c44ff58dc 100644 --- a/ipykernel/kernelbase.py +++ b/ipykernel/kernelbase.py @@ -57,6 +57,14 @@ from ._version import kernel_protocol_version from .iostream import OutStream +_AWAITABLE_MESSAGE: str = ( + "For consistency across implementations, it is recommended that `{func_name}`" + " either be a coroutine function (`async def`) or return an awaitable object" + " (like an `asyncio.Future`). It might become a requirement in the future." + " Coroutine functions and awaitables have been supported since" + " ipykernel 6.0 (2021). {target} does not seem to return an awaitable" +) + def _accepts_parameters(meth, param_names): parameters = inspect.signature(meth).parameters @@ -742,6 +750,12 @@ async def execute_request(self, socket, ident, parent): if inspect.isawaitable(reply_content): reply_content = await reply_content + else: + warnings.warn( + _AWAITABLE_MESSAGE.format(func_name="do_execute", target=self.do_execute), + PendingDeprecationWarning, + stacklevel=1, + ) # Flush output before sending the reply. if sys.stdout is not None: @@ -802,6 +816,12 @@ async def complete_request(self, socket, ident, parent): matches = self.do_complete(code, cursor_pos) if inspect.isawaitable(matches): matches = await matches + else: + warnings.warn( + _AWAITABLE_MESSAGE.format(func_name="do_complete", target=self.do_complete), + PendingDeprecationWarning, + stacklevel=1, + ) matches = json_clean(matches) self.session.send(socket, "complete_reply", matches, parent, ident) @@ -830,6 +850,12 @@ async def inspect_request(self, socket, ident, parent): ) if inspect.isawaitable(reply_content): reply_content = await reply_content + else: + warnings.warn( + _AWAITABLE_MESSAGE.format(func_name="do_inspect", target=self.do_inspect), + PendingDeprecationWarning, + stacklevel=1, + ) # Before we send this object over, we scrub it for JSON usage reply_content = json_clean(reply_content) @@ -849,6 +875,12 @@ async def history_request(self, socket, ident, parent): reply_content = self.do_history(**content) if inspect.isawaitable(reply_content): reply_content = await reply_content + else: + warnings.warn( + _AWAITABLE_MESSAGE.format(func_name="do_history", target=self.do_history), + PendingDeprecationWarning, + stacklevel=1, + ) reply_content = json_clean(reply_content) msg = self.session.send(socket, "history_reply", reply_content, parent, ident) @@ -966,6 +998,12 @@ async def shutdown_request(self, socket, ident, parent): content = self.do_shutdown(parent["content"]["restart"]) if inspect.isawaitable(content): content = await content + else: + warnings.warn( + _AWAITABLE_MESSAGE.format(func_name="do_shutdown", target=self.do_shutdown), + PendingDeprecationWarning, + stacklevel=1, + ) self.session.send(socket, "shutdown_reply", content, parent, ident=ident) # same content, but different msg_id for broadcasting on IOPub self._shutdown_message = self.session.msg("shutdown_reply", content, parent) @@ -990,6 +1028,12 @@ async def is_complete_request(self, socket, ident, parent): reply_content = self.do_is_complete(code) if inspect.isawaitable(reply_content): reply_content = await reply_content + else: + warnings.warn( + _AWAITABLE_MESSAGE.format(func_name="do_is_complete", target=self.do_is_complete), + PendingDeprecationWarning, + stacklevel=1, + ) reply_content = json_clean(reply_content) reply_msg = self.session.send(socket, "is_complete_reply", reply_content, parent, ident) self.log.debug("%s", reply_msg) @@ -1006,6 +1050,14 @@ async def debug_request(self, socket, ident, parent): reply_content = self.do_debug_request(content) if inspect.isawaitable(reply_content): reply_content = await reply_content + else: + warnings.warn( + _AWAITABLE_MESSAGE.format( + func_name="do_debug_request", target=self.do_debug_request + ), + PendingDeprecationWarning, + stacklevel=1, + ) reply_content = json_clean(reply_content) reply_msg = self.session.send(socket, "debug_reply", reply_content, parent, ident) self.log.debug("%s", reply_msg) diff --git a/pyproject.toml b/pyproject.toml index 4de39428b..6103d2da8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -190,6 +190,10 @@ filterwarnings= [ # ignore unclosed sqlite in traits "ignore:unclosed database in