Skip to content

Commit 6e04067

Browse files
committed
More tweaks for type completion
1 parent 203bad5 commit 6e04067

File tree

5 files changed

+49
-107
lines changed

5 files changed

+49
-107
lines changed

src/async_utils/_internal_types.py

Lines changed: 0 additions & 86 deletions
This file was deleted.

src/async_utils/_typings.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@
3030
if TYPE_CHECKING:
3131
from typing import Any, Concatenate, Literal, Never, Protocol, Self
3232
else:
33+
Protocol = object
3334

3435
def __getattr__(name: str):
35-
if name in {"Any", "Concatenate", "Literal", "Never", "Protocol", "Self"}:
36+
if name in {"Any", "Concatenate", "Literal", "Never", "Self"}:
3637
import typing
3738

3839
return getattr(typing, name)

src/async_utils/corofunc_cache.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,29 @@
1616

1717
import asyncio
1818
import concurrent.futures as cf
19-
from collections.abc import Hashable
19+
from collections.abc import Awaitable, Callable, Coroutine, Hashable
2020
from functools import partial, wraps
2121

22-
from . import _internal_types as i_types
2322
from . import _typings as t
2423
from ._paramkey import make_key
2524
from .lru import LRU
2625

2726
__all__ = ("corocache", "lrucorocache")
2827

28+
type CoroFunc[**P, R] = Callable[P, Coroutine[t.Any, t.Any, R]]
29+
type CoroLike[**P, R] = Callable[P, Awaitable[R]]
30+
31+
#: Note CacheTransformers recieve a tuple (args) and dict(kwargs)
32+
#: rather than a ParamSpec of the decorated function.
33+
#: Warning: Mutations will impact callsite, return new objects as needed.
34+
type CacheTransformer = Callable[
35+
[tuple[t.Any, ...], dict[str, t.Any]], tuple[tuple[t.Any, ...], dict[str, t.Any]]
36+
]
37+
38+
39+
class CoroCacheDeco(t.Protocol):
40+
def __call__[**P, R](self, c: CoroLike[P, R], /) -> CoroFunc[P, R]: ...
41+
2942

3043
def _chain_fut[R](c_fut: cf.Future[R], a_fut: asyncio.Future[R]) -> None:
3144
if a_fut.cancelled():
@@ -39,8 +52,8 @@ def _chain_fut[R](c_fut: cf.Future[R], a_fut: asyncio.Future[R]) -> None:
3952
def corocache(
4053
ttl: float | None = None,
4154
*,
42-
cache_transform: i_types.CacheTransformer | None = None,
43-
) -> i_types.CoroCacheDeco:
55+
cache_transform: CacheTransformer | None = None,
56+
) -> CoroCacheDeco:
4457
"""Cache the results of the decorated coroutine.
4558
4659
This is less powerful than the version in task_cache.py but may work better
@@ -73,7 +86,7 @@ def corocache(
7386
def key_func(args: tuple[t.Any, ...], kwds: dict[t.Any, t.Any], /) -> Hashable:
7487
return make_key(*cache_transform(args, kwds))
7588

76-
def wrapper[**P, R](coro: i_types.CoroLike[P, R], /) -> i_types.CoroFunc[P, R]:
89+
def wrapper[**P, R](coro: CoroLike[P, R], /) -> CoroFunc[P, R]:
7790
internal_cache: dict[Hashable, cf.Future[R]] = {}
7891
internal_taskset: set[asyncio.Task[R]] = set()
7992

@@ -112,8 +125,8 @@ def lrucorocache(
112125
ttl: float | None = None,
113126
maxsize: int = 1024,
114127
*,
115-
cache_transform: i_types.CacheTransformer | None = None,
116-
) -> i_types.CoroCacheDeco:
128+
cache_transform: CacheTransformer | None = None,
129+
) -> CoroCacheDeco:
117130
"""Cache the results of the decorated coroutine.
118131
119132
This is less powerful than the version in task_cache.py but may work better
@@ -152,7 +165,7 @@ def lrucorocache(
152165
def key_func(args: tuple[t.Any, ...], kwds: dict[t.Any, t.Any], /) -> Hashable:
153166
return make_key(*cache_transform(args, kwds))
154167

155-
def wrapper[**P, R](coro: i_types.CoroLike[P, R], /) -> i_types.CoroFunc[P, R]:
168+
def wrapper[**P, R](coro: CoroLike[P, R], /) -> CoroFunc[P, R]:
156169
internal_cache: LRU[Hashable, cf.Future[R]] = LRU(maxsize)
157170
internal_taskset: set[asyncio.Task[R]] = set()
158171

src/async_utils/task_cache.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,30 @@
1616

1717
import asyncio
1818
import concurrent.futures as cf
19-
from collections.abc import Callable, Hashable
19+
from collections.abc import Callable, Coroutine, Hashable
2020
from functools import partial, wraps
2121

22-
from . import _internal_types as i_types
2322
from . import _typings as t
2423
from ._paramkey import make_key
2524
from .lru import LRU
2625

2726
__all__ = ("lrutaskcache", "taskcache")
2827

28+
type CoroFunc[**P, R] = Callable[P, Coroutine[t.Any, t.Any, R]]
29+
type TaskFunc[**P, R] = Callable[P, asyncio.Task[R]]
30+
type TaskCoroFunc[**P, R] = CoroFunc[P, R] | TaskFunc[P, R]
31+
32+
#: Note CacheTransformers recieve a tuple (args) and dict(kwargs)
33+
#: rather than a ParamSpec of the decorated function.
34+
#: Warning: Mutations will impact callsite, return new objects as needed.
35+
type CacheTransformer = Callable[
36+
[tuple[t.Any, ...], dict[str, t.Any]], tuple[tuple[t.Any, ...], dict[str, t.Any]]
37+
]
38+
39+
40+
class TaskCacheDeco(t.Protocol):
41+
def __call__[**P, R](self, c: TaskCoroFunc[P, R], /) -> TaskFunc[P, R]: ...
42+
2943

3044
# Non-annotation assignments for transformed functions
3145
_WRAP_ASSIGN = ("__module__", "__name__", "__qualname__", "__doc__")
@@ -44,7 +58,7 @@ class _WrappedSignature[**P, R]:
4458
#: PYUPGRADE: Ensure inspect.signature still accepts this
4559
# as func.__signature__
4660
# Known working: py 3.12.0 - py3.14a6 range inclusive
47-
def __init__(self, f: i_types.TaskCoroFunc[P, R], w: i_types.TaskFunc[P, R]) -> None:
61+
def __init__(self, f: TaskCoroFunc[P, R], w: TaskFunc[P, R]) -> None:
4862
self._f: Callable[..., t.Any] = f # anotation needed for inspect use below....
4963
self._w = w
5064
self._sig: t.Any | None = None
@@ -92,8 +106,8 @@ async def _await[R](fut: asyncio.Future[R]) -> R:
92106
def taskcache(
93107
ttl: float | None = None,
94108
*,
95-
cache_transform: i_types.CacheTransformer | None = None,
96-
) -> i_types.TaskCacheDeco:
109+
cache_transform: CacheTransformer | None = None,
110+
) -> TaskCacheDeco:
97111
"""Cache the results of the decorated coroutine.
98112
99113
Decorator to modify coroutine functions to instead act as functions
@@ -132,7 +146,7 @@ def taskcache(
132146
def key_func(args: tuple[t.Any, ...], kwds: dict[t.Any, t.Any], /) -> Hashable:
133147
return make_key(*cache_transform(args, kwds))
134148

135-
def wrapper[**P, R](coro: i_types.TaskCoroFunc[P, R], /) -> i_types.TaskFunc[P, R]:
149+
def wrapper[**P, R](coro: TaskCoroFunc[P, R], /) -> TaskFunc[P, R]:
136150
internal_cache: dict[Hashable, cf.Future[R]] = {}
137151

138152
def _internal_cache_evict(key: Hashable, _ignored_task: object) -> None:
@@ -171,8 +185,8 @@ def lrutaskcache(
171185
ttl: float | None = None,
172186
maxsize: int = 1024,
173187
*,
174-
cache_transform: i_types.CacheTransformer | None = None,
175-
) -> i_types.TaskCacheDeco:
188+
cache_transform: CacheTransformer | None = None,
189+
) -> TaskCacheDeco:
176190
"""Cache the results of the decorated coroutine.
177191
178192
Decorator to modify coroutine functions to instead act as functions
@@ -218,7 +232,7 @@ def lrutaskcache(
218232
def key_func(args: tuple[t.Any, ...], kwds: dict[t.Any, t.Any], /) -> Hashable:
219233
return make_key(*cache_transform(args, kwds))
220234

221-
def wrapper[**P, R](coro: i_types.TaskCoroFunc[P, R], /) -> i_types.TaskFunc[P, R]:
235+
def wrapper[**P, R](coro: TaskCoroFunc[P, R], /) -> TaskFunc[P, R]:
222236
internal_cache: LRU[Hashable, cf.Future[R]] = LRU(maxsize)
223237

224238
def _internal_cache_evict(key: Hashable, _ignored_task: object) -> None:

src/async_utils/waterfall.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
from . import _typings as t
2525

26-
log = logging.getLogger(__name__)
26+
_log = logging.getLogger(__name__)
2727

2828
__all__ = ("Waterfall",)
2929

@@ -117,9 +117,9 @@ def put(self, item: T) -> None:
117117

118118
def _user_done_callback(self, num: int, future: asyncio.Future[t.Any]) -> None:
119119
if future.cancelled():
120-
log.warning("Callback cancelled due to timeout")
120+
_log.warning("Callback cancelled due to timeout")
121121
elif exc := future.exception():
122-
log.error("Exception in user callback", exc_info=exc)
122+
_log.error("Exception in user callback", exc_info=exc)
123123

124124
for _ in range(num):
125125
self.queue.task_done()

0 commit comments

Comments
 (0)