Skip to content

Commit 4bd8ba9

Browse files
Carreaupre-commit-ci[bot]blink1073
authored
Maint: Some more precise typing. (#326)
* Maint: Some more precise typing. Mostly make sure that ensure_async is properly typed, and not justs has "Any" * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * clean up Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Steven Silvester <[email protected]>
1 parent 7c00a1a commit 4bd8ba9

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

jupyter_core/utils/__init__.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
import threading
1111
import warnings
1212
from pathlib import Path
13-
from typing import Any, Awaitable, Callable, Optional, TypeVar, Union
13+
from types import FrameType
14+
from typing import Awaitable, Callable, List, Optional, TypeVar, Union, cast
1415

1516

1617
def ensure_dir_exists(path, mode=0o777):
@@ -29,7 +30,7 @@ def ensure_dir_exists(path, mode=0o777):
2930
raise OSError("%r exists but is not a directory" % path)
3031

3132

32-
def _get_frame(level):
33+
def _get_frame(level: int) -> Optional[FrameType]:
3334
"""Get the frame at the given stack level."""
3435
# sys._getframe is much faster than inspect.stack, but isn't guaranteed to
3536
# exist in all python implementations, so we fall back to inspect.stack()
@@ -49,7 +50,7 @@ def _get_frame(level):
4950
# added in the process. For example, with the deprecation warning in the
5051
# __init__ below, the appropriate stacklevel will change depending on how deep
5152
# the inheritance hierarchy is.
52-
def _external_stacklevel(internal):
53+
def _external_stacklevel(internal: List[str]) -> int:
5354
"""Find the stacklevel of the first frame that doesn't contain any of the given internal strings
5455
5556
The depth will be 1 at minimum in order to start checking at the caller of
@@ -71,18 +72,21 @@ def _external_stacklevel(internal):
7172
return level - 1
7273

7374

74-
def deprecation(message, internal="jupyter_core/"):
75+
def deprecation(message: str, internal: Union[str, List[str]] = "jupyter_core/") -> None:
7576
"""Generate a deprecation warning targeting the first frame that is not 'internal'
7677
7778
internal is a string or list of strings, which if they appear in filenames in the
7879
frames, the frames will be considered internal. Changing this can be useful if, for examnple,
7980
we know that our internal code is calling out to another library.
8081
"""
82+
_internal: List[str]
8183
if isinstance(internal, str):
82-
internal = [internal]
84+
_internal = [internal]
85+
else:
86+
_internal = internal
8387

8488
# stack level of the first external frame from here
85-
stacklevel = _external_stacklevel(internal)
89+
stacklevel = _external_stacklevel(_internal)
8690

8791
# The call to .warn adds one frame, so bump the stacklevel up by one
8892
warnings.warn(message, DeprecationWarning, stacklevel=stacklevel + 1)
@@ -129,7 +133,7 @@ def run(self, coro):
129133

130134

131135
def run_sync(coro: Callable[..., Awaitable[T]]) -> Callable[..., T]:
132-
"""Runs a coroutine and blocks until it has executed.
136+
"""Wraps coroutine in a function that blocks until it has executed.
133137
134138
Parameters
135139
----------
@@ -165,18 +169,22 @@ def wrapped(*args, **kwargs):
165169
return wrapped
166170

167171

168-
async def ensure_async(obj: Union[Awaitable[Any], Any]) -> Any:
172+
async def ensure_async(obj: Union[Awaitable[T], T]) -> T:
169173
"""Convert a non-awaitable object to a coroutine if needed,
170174
and await it if it was not already awaited.
175+
176+
This function is meant to be called on the result of calling a function,
177+
when that function could either be asynchronous or not.
171178
"""
172179
if inspect.isawaitable(obj):
180+
obj = cast(Awaitable[T], obj)
173181
try:
174182
result = await obj
175183
except RuntimeError as e:
176184
if str(e) == "cannot reuse already awaited coroutine":
177185
# obj is already the coroutine's result
178-
return obj
186+
return cast(T, obj)
179187
raise
180188
return result
181189
# obj doesn't need to be awaited
182-
return obj
190+
return cast(T, obj)

0 commit comments

Comments
 (0)