Skip to content

Commit c28afa1

Browse files
authored
Use ParamSpec to improve typing for actor parameters (#388)
This allows better type-checking my mypy, and better completions for actor parameters, from pyright/LSP.
2 parents 9850338 + dc6cd2c commit c28afa1

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

src/frequenz/sdk/actor/_decorator.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
import asyncio
1313
import inspect
1414
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
1618

1719
from frequenz.sdk._internal._asyncio import cancel_and_await
1820

1921
_logger = logging.getLogger(__name__)
2022

21-
OT = TypeVar("OT")
22-
2323

2424
def _check_run_method_exists(cls: Type[Any]) -> None:
2525
"""Check if a run method exists in the given class.
@@ -57,7 +57,11 @@ class BaseActor:
5757
restart_limit: Optional[int] = None
5858

5959

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]:
6165
"""Decorate a class into a simple composable actor.
6266
6367
A actor using the `actor` decorator should define an `async def run(self)`
@@ -182,10 +186,10 @@ async def run(self) -> None:
182186

183187
_check_run_method_exists(cls)
184188

185-
class ActorClass(cls, BaseActor, Generic[OT]): # type: ignore
189+
class ActorClass(cls, BaseActor): # type: ignore
186190
"""A wrapper class to make an actor."""
187191

188-
def __init__(self, *args: Any, **kwargs: Any) -> None:
192+
def __init__(self, *args: _P.args, **kwargs: _P.kwargs) -> None:
189193
"""Create an `ActorClass` instance.
190194
191195
Also call __init__ on `cls`.

0 commit comments

Comments
 (0)