python-redux 0.25.2__cp314-cp314-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,87 @@
1
+ """Side effect runner thread for Redux."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import contextlib
6
+ import inspect
7
+ import threading
8
+ import weakref
9
+ from asyncio import Handle, iscoroutine
10
+ from typing import TYPE_CHECKING, Any, Generic, cast
11
+
12
+ from redux.basic_types import Event, EventHandler, TaskCreator
13
+
14
+ if TYPE_CHECKING:
15
+ import queue
16
+ from collections.abc import Callable
17
+
18
+ from redux.basic_types import EventHandler, TaskCreator
19
+
20
+
21
+ class SideEffectRunner(threading.Thread, Generic[Event]):
22
+ """Thread for running side effects."""
23
+
24
+ def __init__(
25
+ self: SideEffectRunner,
26
+ *,
27
+ task_queue: queue.Queue[tuple[EventHandler[Event], Event] | None],
28
+ create_task: TaskCreator | None,
29
+ ) -> None:
30
+ """Initialize the side effect runner thread."""
31
+ super().__init__()
32
+ self.name = 'Side Effect Runner'
33
+ self.task_queue = task_queue
34
+ self._handles: set[Handle] = set()
35
+ self.create_task = create_task
36
+
37
+ def run(self: SideEffectRunner[Event]) -> None:
38
+ """Run the side effect runner thread."""
39
+ while True:
40
+ task = self.task_queue.get()
41
+ try:
42
+ if task is None:
43
+ break
44
+ event_handler_, event = task
45
+ if isinstance(event_handler_, weakref.ref):
46
+ event_handler = event_handler_()
47
+ if event_handler is None:
48
+ continue
49
+ else:
50
+ event_handler = event_handler_
51
+ parameters = 1
52
+ with contextlib.suppress(Exception):
53
+ parameters = len(
54
+ [
55
+ param
56
+ for param in inspect.signature(
57
+ event_handler,
58
+ ).parameters.values()
59
+ if param.kind
60
+ in (param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD)
61
+ ],
62
+ )
63
+
64
+ if self.create_task:
65
+
66
+ async def _(
67
+ event_handler: EventHandler[Event],
68
+ event: Event,
69
+ parameters: int,
70
+ ) -> None:
71
+ if parameters == 1:
72
+ result = cast('Callable[[Event], Any]', event_handler)(
73
+ event,
74
+ )
75
+ else:
76
+ result = cast('Callable[[], Any]', event_handler)()
77
+ if iscoroutine(result):
78
+ await result
79
+
80
+ self.create_task(_(event_handler, event, parameters))
81
+ else: # noqa: PLR5501
82
+ if parameters == 1:
83
+ cast('Callable[[Event], Any]', event_handler)(event)
84
+ else:
85
+ cast('Callable[[], Any]', event_handler)()
86
+ finally:
87
+ self.task_queue.task_done()