Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggest to make implementations of some function always return awaitable #1295

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ipykernel/ipkernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ async def run(execution: Execution) -> None:

return reply_content

def do_complete(self, code, cursor_pos):
async def do_complete(self, code, cursor_pos):
"""Handle code completion."""
if _use_experimental_60_completion and self.use_experimental_completions:
return self._experimental_do_complete(code, cursor_pos)
Expand Down Expand Up @@ -625,7 +625,7 @@ def do_history(
"history": list(hist),
}

def do_shutdown(self, restart):
async def do_shutdown(self, restart):
"""Handle kernel shutdown."""
if self.shell:
self.shell.exit_now = True
Expand Down
54 changes: 52 additions & 2 deletions ipykernel/kernelbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 a Future). It might become a requirement in the future."
" Coroutine functions and awaitables have been supported since"
" ipykernel 6.0 (2021)."
)


def _accepts_parameters(meth, param_names):
parameters = inspect.signature(meth).parameters
Expand Down Expand Up @@ -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="execute_request"),
PendingDeprecationWarning,
stacklevel=1,
)

# Flush output before sending the reply.
if sys.stdout is not None:
Expand Down Expand Up @@ -802,11 +816,17 @@ 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"),
PendingDeprecationWarning,
stacklevel=1,
)

matches = json_clean(matches)
self.session.send(socket, "complete_reply", matches, parent, ident)

def do_complete(self, code, cursor_pos):
async def do_complete(self, code, cursor_pos):
"""Override in subclasses to find completions."""
return {
"matches": [],
Expand All @@ -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="inspect_request"),
PendingDeprecationWarning,
stacklevel=1,
)

# Before we send this object over, we scrub it for JSON usage
reply_content = json_clean(reply_content)
Expand All @@ -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="history_request"),
PendingDeprecationWarning,
stacklevel=1,
)

reply_content = json_clean(reply_content)
msg = self.session.send(socket, "history_reply", reply_content, parent, ident)
Expand Down Expand Up @@ -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"),
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)
Expand All @@ -974,7 +1012,7 @@ async def shutdown_request(self, socket, ident, parent):

self.stop()

def do_shutdown(self, restart):
async def do_shutdown(self, restart):
"""Override in subclasses to do things when the frontend shuts down the
kernel.
"""
Expand All @@ -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_execute"),
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)
Expand All @@ -1006,6 +1050,12 @@ 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="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)
Expand Down
Loading