|
12 | 12 | import asyncio |
13 | 13 | import inspect |
14 | 14 | import logging |
15 | | -from typing import Any, Generic, Optional, Type, TypeVar |
| 15 | +from typing import Any, Callable, Optional, Type, TypeVar |
| 16 | + |
| 17 | +from typing_extensions import ParamSpec |
16 | 18 |
|
17 | 19 | from frequenz.sdk._internal._asyncio import cancel_and_await |
18 | 20 |
|
19 | 21 | _logger = logging.getLogger(__name__) |
20 | 22 |
|
21 | | -OT = TypeVar("OT") |
22 | | - |
23 | 23 |
|
24 | 24 | def _check_run_method_exists(cls: Type[Any]) -> None: |
25 | 25 | """Check if a run method exists in the given class. |
@@ -57,7 +57,11 @@ class BaseActor: |
57 | 57 | restart_limit: Optional[int] = None |
58 | 58 |
|
59 | 59 |
|
60 | | -def actor(cls: Type[Any]) -> Type[Any]: |
| 60 | +_P = ParamSpec("_P") |
| 61 | +_R = TypeVar("_R") |
| 62 | + |
| 63 | + |
| 64 | +def actor(cls: Callable[_P, _R]) -> Type[_R]: |
61 | 65 | """Decorate a class into a simple composable actor. |
62 | 66 |
|
63 | 67 | A actor using the `actor` decorator should define an `async def run(self)` |
@@ -182,10 +186,10 @@ async def run(self) -> None: |
182 | 186 |
|
183 | 187 | _check_run_method_exists(cls) |
184 | 188 |
|
185 | | - class ActorClass(cls, BaseActor, Generic[OT]): # type: ignore |
| 189 | + class ActorClass(cls, BaseActor): # type: ignore |
186 | 190 | """A wrapper class to make an actor.""" |
187 | 191 |
|
188 | | - def __init__(self, *args: Any, **kwargs: Any) -> None: |
| 192 | + def __init__(self, *args: _P.args, **kwargs: _P.kwargs) -> None: |
189 | 193 | """Create an `ActorClass` instance. |
190 | 194 |
|
191 | 195 | Also call __init__ on `cls`. |
|
0 commit comments