-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(test): move fixtures and testing utilities to
redux-pytest
pa…
…ckage feat(test): add `wait_for`, `store_monitor`, `event_loop` and `needs_finish` fixtures test: add tests for scheduler and fixtures refactor: `SideEffectRunnerThread` now runs async side effects in its own event-loop refactor: removed `immediate_run` from event subscriptions refactor: removed `EventSubscriptionOptions` as the only option left was `keep_ref`, it's now a parameter of `subscribe_event` feat: new `on_finish` callback for the store, it runs when all worker threads are joined and resources are freed
- Loading branch information
Showing
67 changed files
with
1,381 additions
and
443 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
# ruff: noqa: D100, D101, D102, D103, D104, D107, A003, T201 | ||
from __future__ import annotations | ||
|
||
import time | ||
|
||
from immutable import Immutable | ||
|
||
from redux import ( | ||
BaseAction, | ||
BaseCombineReducerState, | ||
CombineReducerAction, | ||
CombineReducerRegisterAction, | ||
CombineReducerUnregisterAction, | ||
InitAction, | ||
InitializationActionError, | ||
Store, | ||
combine_reducers, | ||
) | ||
from redux.basic_types import ( | ||
BaseEvent, | ||
CompleteReducerResult, | ||
FinishAction, | ||
ReducerResult, | ||
) | ||
from redux.main import CreateStoreOptions | ||
|
||
|
||
class CountAction(BaseAction): | ||
... | ||
|
||
|
||
class IncrementAction(CountAction): | ||
... | ||
|
||
|
||
class DecrementAction(CountAction): | ||
... | ||
|
||
|
||
class DoNothingAction(CountAction): | ||
... | ||
|
||
|
||
ActionType = InitAction | FinishAction | CountAction | CombineReducerAction | ||
|
||
|
||
class CountStateType(Immutable): | ||
count: int | ||
|
||
|
||
class StateType(BaseCombineReducerState): | ||
straight: CountStateType | ||
base10: CountStateType | ||
inverse: CountStateType | ||
|
||
|
||
# Reducers < | ||
def straight_reducer( | ||
state: CountStateType | None, | ||
action: ActionType, | ||
) -> CountStateType: | ||
if state is None: | ||
if isinstance(action, InitAction): | ||
return CountStateType(count=0) | ||
raise InitializationActionError(action) | ||
if isinstance(action, IncrementAction): | ||
return CountStateType(count=state.count + 1) | ||
if isinstance(action, DecrementAction): | ||
return CountStateType(count=state.count - 1) | ||
return state | ||
|
||
|
||
def base10_reducer( | ||
state: CountStateType | None, | ||
action: ActionType, | ||
) -> CountStateType: | ||
if state is None: | ||
if isinstance(action, InitAction): | ||
return CountStateType(count=10) | ||
raise InitializationActionError(action) | ||
if isinstance(action, IncrementAction): | ||
return CountStateType(count=state.count + 1) | ||
if isinstance(action, DecrementAction): | ||
return CountStateType(count=state.count - 1) | ||
return state | ||
|
||
|
||
class SleepEvent(BaseEvent): | ||
duration: int | ||
|
||
|
||
class PrintEvent(BaseEvent): | ||
message: str | ||
|
||
|
||
def inverse_reducer( | ||
state: CountStateType | None, | ||
action: ActionType, | ||
) -> ReducerResult[CountStateType, ActionType, SleepEvent]: | ||
if state is None: | ||
if isinstance(action, InitAction): | ||
return CountStateType(count=0) | ||
raise InitializationActionError(action) | ||
if isinstance(action, IncrementAction): | ||
return CountStateType(count=state.count - 1) | ||
if isinstance(action, DecrementAction): | ||
return CountStateType(count=state.count + 1) | ||
if isinstance(action, DoNothingAction): | ||
return CompleteReducerResult( | ||
state=state, | ||
actions=[IncrementAction()], | ||
events=[SleepEvent(duration=3)], | ||
) | ||
return state | ||
|
||
|
||
reducer, reducer_id = combine_reducers( | ||
state_type=StateType, | ||
action_type=ActionType, # pyright: ignore [reportArgumentType] | ||
event_type=SleepEvent | PrintEvent, # pyright: ignore [reportArgumentType] | ||
straight=straight_reducer, | ||
base10=base10_reducer, | ||
) | ||
# > | ||
|
||
|
||
def main() -> None: | ||
# Initialization < | ||
store = Store( | ||
reducer, | ||
CreateStoreOptions(auto_init=True, threads=2), | ||
) | ||
|
||
def event_handler(event: SleepEvent) -> None: | ||
time.sleep(event.duration) | ||
|
||
store.subscribe_event(SleepEvent, event_handler) | ||
# > | ||
|
||
# ----- | ||
|
||
# Subscription < | ||
store.subscribe(lambda state: print('Subscription state:', state)) | ||
# > | ||
|
||
# ----- | ||
|
||
# Autorun < | ||
@store.autorun(lambda state: state.base10) | ||
def render(base10_value: CountStateType) -> int: | ||
print('Autorun:', base10_value) | ||
return base10_value.count | ||
|
||
render.subscribe(lambda a: print(a)) | ||
|
||
print(f'Render output {render()}') | ||
|
||
store.dispatch(IncrementAction()) | ||
print(f'Render output {render()}') | ||
|
||
store.dispatch( | ||
CombineReducerRegisterAction( | ||
_id=reducer_id, | ||
key='inverse', | ||
reducer=inverse_reducer, | ||
), | ||
) | ||
|
||
store.dispatch(DoNothingAction()) | ||
print(f'Render output {render()}') | ||
|
||
store.dispatch( | ||
CombineReducerUnregisterAction( | ||
_id=reducer_id, | ||
key='straight', | ||
), | ||
) | ||
print(f'Render output {render()}') | ||
|
||
store.dispatch(DecrementAction()) | ||
print(f'Render output {render()}') | ||
|
||
store.dispatch(FinishAction()) | ||
# > |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.