|
32 | 32 | TypeVar,
|
33 | 33 | )
|
34 | 34 |
|
| 35 | +try: |
| 36 | + from typing import ParamSpec |
| 37 | +except ImportError: |
| 38 | + from typing_extensions import ParamSpec # type: ignore[assignment] |
| 39 | + |
35 | 40 | import duet.impl as impl
|
36 | 41 | from duet.aitertools import aenumerate, aiter, AnyIterable, AsyncCollector
|
37 | 42 | from duet.futuretools import AwaitableFuture
|
38 | 43 |
|
| 44 | +P = ParamSpec("P") |
39 | 45 | T = TypeVar("T")
|
40 | 46 | U = TypeVar("U")
|
41 | 47 |
|
42 | 48 |
|
43 |
| -def run(func: Callable[..., Awaitable[T]], *args, **kwds) -> T: |
| 49 | +def run(func: Callable[P, Awaitable[T]], *args: P.args, **kwds: P.kwargs) -> T: |
44 | 50 | """Run an async function to completion.
|
45 | 51 |
|
46 | 52 | Args:
|
@@ -72,7 +78,7 @@ def run(func: Callable[..., Awaitable[T]], *args, **kwds) -> T:
|
72 | 78 | scheduler.cleanup_signals()
|
73 | 79 |
|
74 | 80 |
|
75 |
| -def sync(f: Callable[..., Awaitable[T]]) -> Callable[..., T]: |
| 81 | +def sync(f: Callable[P, Awaitable[T]]) -> Callable[P, T]: |
76 | 82 | """Decorator that adds a sync version of async function or method."""
|
77 | 83 | if isinstance(f, classmethod):
|
78 | 84 | raise TypeError(f"duet.sync cannot be applied to classmethod {f.__func__}")
|
@@ -113,7 +119,7 @@ def wrapped(self, *args, **kw):
|
113 | 119 | def wrapped(*args, **kw):
|
114 | 120 | return run(f, *args, **kw)
|
115 | 121 |
|
116 |
| - return wrapped |
| 122 | + return wrapped # type: ignore[return-value] |
117 | 123 |
|
118 | 124 |
|
119 | 125 | def awaitable(value):
|
@@ -375,12 +381,14 @@ def __init__(
|
375 | 381 | def cancel(self) -> None:
|
376 | 382 | self._main_task.interrupt(self._main_task, CancelledError())
|
377 | 383 |
|
378 |
| - def spawn(self, func: Callable[..., Awaitable[Any]], *args, **kwds) -> None: |
| 384 | + def spawn(self, func: Callable[P, Awaitable[Any]], *args: P.args, **kwds: P.kwargs) -> None: |
379 | 385 | """Starts a background task that will run the given function."""
|
380 | 386 | task = self._scheduler.spawn(self._run(func, *args, **kwds), main_task=self._main_task)
|
381 | 387 | self._tasks.add(task)
|
382 | 388 |
|
383 |
| - async def _run(self, func: Callable[..., Awaitable[Any]], *args, **kwds) -> None: |
| 389 | + async def _run( |
| 390 | + self, func: Callable[P, Awaitable[Any]], *args: P.args, **kwds: P.kwargs |
| 391 | + ) -> None: |
384 | 392 | task = impl.current_task()
|
385 | 393 | try:
|
386 | 394 | await func(*args, **kwds)
|
@@ -513,7 +521,7 @@ def scope(self) -> Scope:
|
513 | 521 | def limiter(self) -> Limiter:
|
514 | 522 | pass
|
515 | 523 |
|
516 |
| - def spawn(self, func: Callable[..., Awaitable[Any]], *args, **kwds) -> None: |
| 524 | + def spawn(self, func: Callable[P, Awaitable[Any]], *args: P.args, **kwds: P.kwargs) -> None: |
517 | 525 | """Starts a background task that will run the given function."""
|
518 | 526 | self.scope.spawn(func, *args, **kwds)
|
519 | 527 |
|
|
0 commit comments