Skip to content

Commit 1939a5a

Browse files
Carreaudavidbrochart
authored andcommitted
Suggest to make implementations of some function always return awaitable (ipython#1295)
Co-authored-by: David Brochart <[email protected]>
1 parent 8cde51d commit 1939a5a

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

ipykernel/kernelbase.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@
6161
from ._version import kernel_protocol_version
6262
from .iostream import OutStream
6363

64+
_AWAITABLE_MESSAGE: str = (
65+
"For consistency across implementations, it is recommended that `{func_name}`"
66+
" either be a coroutine function (`async def`) or return an awaitable object"
67+
" (like an `asyncio.Future`). It might become a requirement in the future."
68+
" Coroutine functions and awaitables have been supported since"
69+
" ipykernel 6.0 (2021). {target} does not seem to return an awaitable"
70+
)
71+
6472

6573
def _accepts_parameters(meth, param_names):
6674
parameters = inspect.signature(meth).parameters
@@ -842,6 +850,12 @@ async def execute_request(self, stream, ident, parent):
842850

843851
if inspect.isawaitable(reply_content):
844852
reply_content = await reply_content
853+
else:
854+
warnings.warn(
855+
_AWAITABLE_MESSAGE.format(func_name="do_execute", target=self.do_execute),
856+
PendingDeprecationWarning,
857+
stacklevel=1,
858+
)
845859

846860
# Flush output before sending the reply.
847861
if sys.stdout is not None:
@@ -898,6 +912,12 @@ async def complete_request(self, stream, ident, parent):
898912
matches = self.do_complete(code, cursor_pos)
899913
if inspect.isawaitable(matches):
900914
matches = await matches
915+
else:
916+
warnings.warn(
917+
_AWAITABLE_MESSAGE.format(func_name="do_complete", target=self.do_complete),
918+
PendingDeprecationWarning,
919+
stacklevel=1,
920+
)
901921

902922
matches = json_clean(matches)
903923
self.session.send(stream, "complete_reply", matches, parent, ident)
@@ -926,6 +946,12 @@ async def inspect_request(self, stream, ident, parent):
926946
)
927947
if inspect.isawaitable(reply_content):
928948
reply_content = await reply_content
949+
else:
950+
warnings.warn(
951+
_AWAITABLE_MESSAGE.format(func_name="do_inspect", target=self.do_inspect),
952+
PendingDeprecationWarning,
953+
stacklevel=1,
954+
)
929955

930956
# Before we send this object over, we scrub it for JSON usage
931957
reply_content = json_clean(reply_content)
@@ -945,6 +971,12 @@ async def history_request(self, stream, ident, parent):
945971
reply_content = self.do_history(**content)
946972
if inspect.isawaitable(reply_content):
947973
reply_content = await reply_content
974+
else:
975+
warnings.warn(
976+
_AWAITABLE_MESSAGE.format(func_name="do_history", target=self.do_history),
977+
PendingDeprecationWarning,
978+
stacklevel=1,
979+
)
948980

949981
reply_content = json_clean(reply_content)
950982
msg = self.session.send(stream, "history_reply", reply_content, parent, ident)
@@ -1067,7 +1099,13 @@ async def shutdown_request(self, stream, ident, parent):
10671099
content = self.do_shutdown(parent["content"]["restart"])
10681100
if inspect.isawaitable(content):
10691101
content = await content
1070-
self.session.send(stream, "shutdown_reply", content, parent, ident=ident)
1102+
else:
1103+
warnings.warn(
1104+
_AWAITABLE_MESSAGE.format(func_name="do_shutdown", target=self.do_shutdown),
1105+
PendingDeprecationWarning,
1106+
stacklevel=1,
1107+
)
1108+
self.session.send(socket, "shutdown_reply", content, parent, ident=ident)
10711109
# same content, but different msg_id for broadcasting on IOPub
10721110
self._shutdown_message = self.session.msg("shutdown_reply", content, parent)
10731111

@@ -1100,6 +1138,12 @@ async def is_complete_request(self, stream, ident, parent):
11001138
reply_content = self.do_is_complete(code)
11011139
if inspect.isawaitable(reply_content):
11021140
reply_content = await reply_content
1141+
else:
1142+
warnings.warn(
1143+
_AWAITABLE_MESSAGE.format(func_name="do_is_complete", target=self.do_is_complete),
1144+
PendingDeprecationWarning,
1145+
stacklevel=1,
1146+
)
11031147
reply_content = json_clean(reply_content)
11041148
reply_msg = self.session.send(stream, "is_complete_reply", reply_content, parent, ident)
11051149
self.log.debug("%s", reply_msg)
@@ -1116,6 +1160,14 @@ async def debug_request(self, stream, ident, parent):
11161160
reply_content = self.do_debug_request(content)
11171161
if inspect.isawaitable(reply_content):
11181162
reply_content = await reply_content
1163+
else:
1164+
warnings.warn(
1165+
_AWAITABLE_MESSAGE.format(
1166+
func_name="do_debug_request", target=self.do_debug_request
1167+
),
1168+
PendingDeprecationWarning,
1169+
stacklevel=1,
1170+
)
11191171
reply_content = json_clean(reply_content)
11201172
reply_msg = self.session.send(stream, "debug_reply", reply_content, parent, ident)
11211173
self.log.debug("%s", reply_msg)

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ filterwarnings= [
188188

189189
# ignore unclosed sqlite in traits
190190
"ignore:unclosed database in <sqlite3.Connection:ResourceWarning",
191+
192+
# ignore deprecated non async during tests:
193+
"always:For consistency across implementations, it is recommended that:PendingDeprecationWarning",
194+
191195
]
192196

193197
[tool.coverage.report]

0 commit comments

Comments
 (0)