Skip to content

Commit 36ea6eb

Browse files
committed
feat: improve decorator
1 parent c026ab4 commit 36ea6eb

4 files changed

Lines changed: 43 additions & 11 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ future-annotations = true
4848

4949
[tool.ruff.lint.flake8-type-checking]
5050
runtime-evaluated-base-classes = ["typing_extensions.TypedDict"]
51-
runtime-evaluated-decorators = ["duron.fn", "duron.host"]
51+
runtime-evaluated-decorators = ["duron.fn", "duron.effect"]
5252

5353
[tool.ruff.lint.flake8-tidy-imports.banned-api]
5454
"typing.TypedDict".msg = "Use typing_extensions.TypedDict instead."

src/duron/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from .config import set_config as set_config
22
from .context import Context as Context
3+
from .fn import effect as effect
34
from .fn import fn as fn
4-
from .fn import host as host
55
from .stream import EndOfStream as EndOfStream
66
from .stream import Sink as Sink
77
from .stream import Stream as Stream

src/duron/fn.py

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
Generic,
99
ParamSpec,
1010
TypeVar,
11+
overload,
1112
)
1213

1314
from duron.config import config
@@ -39,12 +40,28 @@ def create_task(self, log: LogStorage) -> TaskGuard[_P, _T_co]:
3940
return TaskGuard(Task(self, log))
4041

4142

43+
@overload
44+
def fn(
45+
_fn: Callable[Concatenate[Context, _P], Coroutine[Any, Any, _T_co]],
46+
) -> Fn[_P, _T_co]: ...
47+
@overload
4248
def fn(
4349
*, codec: Codec | None = None
4450
) -> Callable[
4551
[Callable[Concatenate[Context, _P], Coroutine[Any, Any, _T_co]]],
4652
Fn[_P, _T_co],
47-
]:
53+
]: ...
54+
def fn(
55+
_fn: Callable[Concatenate[Context, _P], Coroutine[Any, Any, _T_co]] | None = None,
56+
*,
57+
codec: Codec | None = None,
58+
) -> (
59+
Fn[_P, _T_co]
60+
| Callable[
61+
[Callable[Concatenate[Context, _P], Coroutine[Any, Any, _T_co]]],
62+
Fn[_P, _T_co],
63+
]
64+
):
4865
"""
4966
Mark a function as durable, meaning its execution can be recorded and
5067
replayed.
@@ -55,8 +72,23 @@ def decorate(
5572
) -> Fn[_P, _T_co]:
5673
return Fn(codec=codec or config.codec, fn=fn)
5774

58-
return decorate
59-
60-
61-
def host(fn: Callable[_P, _T_co]) -> Callable[_P, _T_co]:
62-
return fn
75+
if _fn is not None:
76+
return decorate(_fn)
77+
else:
78+
return decorate
79+
80+
81+
@overload
82+
def effect(_fn: Callable[_P, _T_co]) -> Callable[_P, _T_co]: ...
83+
@overload
84+
def effect() -> Callable[[Callable[_P, _T_co]], Callable[_P, _T_co]]: ...
85+
def effect(
86+
_fn: Callable[_P, _T_co] | None = None,
87+
) -> Callable[_P, _T_co] | Callable[[Callable[_P, _T_co]], Callable[_P, _T_co]]:
88+
def decorate(fn: Callable[_P, _T_co]) -> Callable[_P, _T_co]:
89+
return fn
90+
91+
if _fn is not None:
92+
return decorate(_fn)
93+
else:
94+
return decorate

tests/test_stream.py

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

77
import pytest
88

9-
from duron import EndOfStream, Sink, fn, host
9+
from duron import EndOfStream, Sink, effect, fn
1010
from duron.context import Context
1111
from duron.contrib.storage import MemoryLogStorage
1212

@@ -48,7 +48,7 @@ async def test_stream_host():
4848
async def activity(ctx: Context) -> None:
4949
stream, handle = await ctx.create_stream(int)
5050

51-
@host
51+
@effect
5252
async def task(stream: Sink[int]):
5353
for i in range(50):
5454
await stream.send(i)
@@ -70,7 +70,7 @@ async def test_run():
7070

7171
@fn()
7272
async def activity(ctx: Context) -> None:
73-
@host
73+
@effect
7474
async def f(s: str) -> AsyncGenerator[str, str]:
7575
while len(s) < 100:
7676
if len(s) == sleep_idx:

0 commit comments

Comments
 (0)