|
28 | 28 | Type,
|
29 | 29 | TypeVar,
|
30 | 30 | Union,
|
31 |
| - cast, |
32 | 31 | )
|
33 | 32 |
|
34 | 33 | from prometheus_client import Metric
|
35 | 34 | from prometheus_client.core import REGISTRY, Counter, Gauge
|
| 35 | +from typing_extensions import ParamSpec |
36 | 36 |
|
37 | 37 | from twisted.internet import defer
|
38 | 38 |
|
@@ -256,24 +256,48 @@ async def run() -> Optional[R]:
|
256 | 256 | return defer.ensureDeferred(run())
|
257 | 257 |
|
258 | 258 |
|
259 |
| -F = TypeVar("F", bound=Callable[..., Awaitable[Optional[Any]]]) |
| 259 | +P = ParamSpec("P") |
260 | 260 |
|
261 | 261 |
|
262 |
| -def wrap_as_background_process(desc: str) -> Callable[[F], F]: |
263 |
| - """Decorator that wraps a function that gets called as a background |
264 |
| - process. |
| 262 | +def wrap_as_background_process( |
| 263 | + desc: str, |
| 264 | +) -> Callable[ |
| 265 | + [Callable[P, Awaitable[Optional[R]]]], |
| 266 | + Callable[P, "defer.Deferred[Optional[R]]"], |
| 267 | +]: |
| 268 | + """Decorator that wraps an asynchronous function `func`, returning a synchronous |
| 269 | + decorated function. Calling the decorated version runs `func` as a background |
| 270 | + process, forwarding all arguments verbatim. |
| 271 | +
|
| 272 | + That is, |
| 273 | +
|
| 274 | + @wrap_as_background_process |
| 275 | + def func(*args): ... |
| 276 | + func(1, 2, third=3) |
| 277 | +
|
| 278 | + is equivalent to: |
| 279 | +
|
| 280 | + def func(*args): ... |
| 281 | + run_as_background_process(func, 1, 2, third=3) |
265 | 282 |
|
266 |
| - Equivalent to calling the function with `run_as_background_process` |
| 283 | + The former can be convenient if `func` needs to be run as a background process in |
| 284 | + multiple places. |
267 | 285 | """
|
268 | 286 |
|
269 |
| - def wrap_as_background_process_inner(func: F) -> F: |
| 287 | + def wrap_as_background_process_inner( |
| 288 | + func: Callable[P, Awaitable[Optional[R]]] |
| 289 | + ) -> Callable[P, "defer.Deferred[Optional[R]]"]: |
270 | 290 | @wraps(func)
|
271 | 291 | def wrap_as_background_process_inner_2(
|
272 |
| - *args: Any, **kwargs: Any |
| 292 | + *args: P.args, **kwargs: P.kwargs |
273 | 293 | ) -> "defer.Deferred[Optional[R]]":
|
274 |
| - return run_as_background_process(desc, func, *args, **kwargs) |
| 294 | + # type-ignore: mypy is confusing kwargs with the bg_start_span kwarg. |
| 295 | + # Argument 4 to "run_as_background_process" has incompatible type |
| 296 | + # "**P.kwargs"; expected "bool" |
| 297 | + # See https://github.com/python/mypy/issues/8862 |
| 298 | + return run_as_background_process(desc, func, *args, **kwargs) # type: ignore[arg-type] |
275 | 299 |
|
276 |
| - return cast(F, wrap_as_background_process_inner_2) |
| 300 | + return wrap_as_background_process_inner_2 |
277 | 301 |
|
278 | 302 | return wrap_as_background_process_inner
|
279 | 303 |
|
|
0 commit comments