Skip to content

Commit 44b1317

Browse files
committed
refactor: make dispatch accept a with_state(store) function as parameter, if provided it will dispatch return value of this function
1 parent 663dcd2 commit 44b1317

File tree

4 files changed

+97
-79
lines changed

4 files changed

+97
-79
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## Version 0.9.16
4+
5+
- refactor: make `dispatch` accept a `with_state(store)` function as parameter, if
6+
provided it will dispatch return value of this function
7+
38
## Version 0.9.15
49

510
- refactor: improve typing of `SideEffectRunnerThread`

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "python-redux"
3-
version = "0.9.15"
3+
version = "0.9.16"
44
description = "Redux implementation for Python"
55
authors = ["Sassan Haradji <sassanh@gmail.com>"]
66
license = "Apache-2.0"

redux/basic_types.py

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# ruff: noqa: A003, D100, D101, D102, D103, D104, D105, D107
22
from __future__ import annotations
33

4-
from typing import Any, Callable, Generic, Sequence, TypeGuard
4+
from typing import Any, Callable, Generic, Protocol, Sequence, TypeAlias, TypeGuard
55

66
from immutable import Immutable
77
from typing_extensions import TypeVar
@@ -41,11 +41,6 @@ class CompleteReducerResult(Immutable, Generic[State, Action, Event]):
4141

4242
AutorunOriginalReturnType = TypeVar('AutorunOriginalReturnType', infer_variance=True)
4343

44-
EventSubscriber = Callable[
45-
[Event, Callable[[Event], Any], EventSubscriptionOptions | None],
46-
Callable[[], None],
47-
]
48-
4944

5045
class InitializationActionError(Exception):
5146
def __init__(self: InitializationActionError, action: BaseAction) -> None:
@@ -75,3 +70,79 @@ def is_reducer_result(
7570

7671
def is_state(result: ReducerResult[State, Action, Event]) -> TypeGuard[State]:
7772
return not isinstance(result, CompleteReducerResult)
73+
74+
75+
class Scheduler(Protocol):
76+
def __call__(self: Scheduler, callback: Callable, *, interval: bool) -> None:
77+
...
78+
79+
80+
class CreateStoreOptions(Immutable):
81+
auto_init: bool = False
82+
threads: int = 5
83+
autorun_initial_run: bool = True
84+
scheduler: Scheduler | None = None
85+
action_middleware: Callable[[BaseAction], Any] | None = None
86+
event_middleware: Callable[[BaseEvent], Any] | None = None
87+
88+
89+
class AutorunType(Protocol, Generic[State]):
90+
def __call__(
91+
self: AutorunType,
92+
selector: Callable[[State], SelectorOutput],
93+
comparator: Callable[[State], Any] | None = None,
94+
) -> AutorunDecorator[State, SelectorOutput]:
95+
...
96+
97+
98+
class AutorunDecorator(Protocol, Generic[State, SelectorOutput]):
99+
def __call__(
100+
self: AutorunDecorator,
101+
func: Callable[[SelectorOutput], AutorunOriginalReturnType]
102+
| Callable[[SelectorOutput, SelectorOutput], AutorunOriginalReturnType],
103+
) -> AutorunReturnType[AutorunOriginalReturnType]:
104+
...
105+
106+
107+
class AutorunReturnType(Protocol, Generic[AutorunOriginalReturnType]):
108+
def __call__(self: AutorunReturnType) -> AutorunOriginalReturnType:
109+
...
110+
111+
@property
112+
def value(self: AutorunReturnType) -> AutorunOriginalReturnType:
113+
...
114+
115+
def subscribe(
116+
self: AutorunReturnType,
117+
callback: Callable[[AutorunOriginalReturnType], Any],
118+
) -> Callable[[], None]:
119+
...
120+
121+
122+
class EventSubscriber(Protocol):
123+
def __call__(
124+
self: EventSubscriber,
125+
event_type: type[Event],
126+
handler: EventHandler[Event],
127+
options: EventSubscriptionOptions | None = None,
128+
) -> Callable[[], None]:
129+
...
130+
131+
132+
DispatchParameters: TypeAlias = Action | Event | list[Action | Event]
133+
134+
135+
class Dispatch(Protocol, Generic[State, Action, Event]):
136+
def __call__(
137+
self: Dispatch,
138+
*items: Action | Event | list[Action | Event],
139+
with_state: Callable[[State | None], Action | Event | list[Action | Event]],
140+
) -> None:
141+
...
142+
143+
144+
class InitializeStateReturnValue(Immutable, Generic[State, Action, Event]):
145+
dispatch: Dispatch[State, Action, Event]
146+
subscribe: Callable[[Callable[[State], Any]], Callable[[], None]]
147+
subscribe_event: EventSubscriber
148+
autorun: AutorunType[State]

redux/main.py

Lines changed: 14 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,26 @@
66
from collections import defaultdict
77
from inspect import signature
88
from threading import Lock
9-
from typing import Any, Callable, Generic, Protocol, cast
9+
from typing import Any, Callable, Generic, cast
1010

1111
from .basic_types import (
1212
Action,
13+
AutorunDecorator,
1314
AutorunOriginalReturnType,
15+
AutorunReturnType,
1416
BaseAction,
1517
BaseEvent,
1618
ComparatorOutput,
19+
CreateStoreOptions,
20+
DispatchParameters,
1721
Event,
1822
Event2,
1923
EventHandler,
2024
EventSubscriptionOptions,
2125
FinishAction,
2226
FinishEvent,
23-
Immutable,
2427
InitAction,
28+
InitializeStateReturnValue,
2529
ReducerType,
2630
SelectorOutput,
2731
State,
@@ -30,75 +34,6 @@
3034
)
3135

3236

33-
class Scheduler(Protocol):
34-
def __call__(self: Scheduler, callback: Callable, *, interval: bool) -> None:
35-
...
36-
37-
38-
class CreateStoreOptions(Immutable):
39-
auto_init: bool = False
40-
threads: int = 5
41-
autorun_initial_run: bool = True
42-
scheduler: Scheduler | None = None
43-
action_middleware: Callable[[BaseAction], Any] | None = None
44-
event_middleware: Callable[[BaseEvent], Any] | None = None
45-
46-
47-
class AutorunType(Protocol, Generic[State]):
48-
def __call__(
49-
self: AutorunType,
50-
selector: Callable[[State], SelectorOutput],
51-
comparator: Callable[[State], Any] | None = None,
52-
) -> AutorunDecorator[State, SelectorOutput]:
53-
...
54-
55-
56-
class AutorunDecorator(Protocol, Generic[State, SelectorOutput]):
57-
def __call__(
58-
self: AutorunDecorator,
59-
func: Callable[[SelectorOutput], AutorunOriginalReturnType]
60-
| Callable[[SelectorOutput, SelectorOutput], AutorunOriginalReturnType],
61-
) -> AutorunReturnType[AutorunOriginalReturnType]:
62-
...
63-
64-
65-
class AutorunReturnType(Protocol, Generic[AutorunOriginalReturnType]):
66-
def __call__(self: AutorunReturnType) -> AutorunOriginalReturnType:
67-
...
68-
69-
@property
70-
def value(self: AutorunReturnType) -> AutorunOriginalReturnType:
71-
...
72-
73-
def subscribe(
74-
self: AutorunReturnType,
75-
callback: Callable[[AutorunOriginalReturnType], Any],
76-
) -> Callable[[], None]:
77-
...
78-
79-
80-
class EventSubscriber(Protocol):
81-
def __call__(
82-
self: EventSubscriber,
83-
event_type: type[Event],
84-
handler: EventHandler[Event],
85-
options: EventSubscriptionOptions | None = None,
86-
) -> Callable[[], None]: # pyright: ignore[reportGeneralTypeIssues]
87-
...
88-
89-
90-
class Dispatch(Protocol, Generic[Action, Event]):
91-
def __call__(self: Dispatch, *items: Action | Event | list[Action | Event]) -> None:
92-
...
93-
94-
95-
class InitializeStateReturnValue(Immutable, Generic[State, Action, Event]):
96-
dispatch: Dispatch[Action, Event]
97-
subscribe: Callable[[Callable[[State], Any]], Callable[[], None]]
98-
subscribe_event: EventSubscriber
99-
autorun: AutorunType[State]
100-
101-
10237
class SideEffectRunnerThread(threading.Thread, Generic[Event]):
10338
def __init__(
10439
self: SideEffectRunnerThread[Event],
@@ -177,7 +112,14 @@ def run() -> None:
177112
else:
178113
cast(Callable[[], Any], event_handler)()
179114

180-
def dispatch(*parameters: Action | Event | list[Action | Event]) -> None:
115+
def dispatch(
116+
*parameters: DispatchParameters[Action, Event],
117+
with_state: Callable[[State | None], DispatchParameters[Action, Event]]
118+
| None = None,
119+
) -> None:
120+
if with_state is not None:
121+
dispatch(with_state(state))
122+
181123
items = [
182124
item
183125
for items in parameters

0 commit comments

Comments
 (0)