haiway 0.1.0__py3-none-any.whl → 0.2.0__py3-none-any.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.
haiway/__init__.py CHANGED
@@ -1,20 +1,11 @@
1
1
  from haiway.context import (
2
- Dependencies,
3
- Dependency,
4
2
  MissingContext,
5
- MissingDependency,
6
3
  MissingState,
7
4
  ScopeMetrics,
8
5
  ctx,
9
6
  )
10
- from haiway.helpers import (
11
- asynchronous,
12
- auto_retry,
13
- cached,
14
- throttle,
15
- with_timeout,
16
- )
17
- from haiway.state import Structure
7
+ from haiway.helpers import Disposable, Disposables, asynchronous, cache, retry, throttle, timeout
8
+ from haiway.state import State
18
9
  from haiway.types import (
19
10
  MISSING,
20
11
  Missing,
@@ -45,11 +36,10 @@ __all__ = [
45
36
  "async_noop",
46
37
  "asynchronous",
47
38
  "AsyncQueue",
48
- "auto_retry",
49
- "cached",
39
+ "cache",
50
40
  "ctx",
51
- "Dependencies",
52
- "Dependency",
41
+ "Disposable",
42
+ "Disposables",
53
43
  "freeze",
54
44
  "frozenlist",
55
45
  "getenv_bool",
@@ -62,14 +52,14 @@ __all__ = [
62
52
  "Missing",
63
53
  "MISSING",
64
54
  "MissingContext",
65
- "MissingDependency",
66
55
  "MissingState",
67
56
  "noop",
68
57
  "not_missing",
58
+ "retry",
69
59
  "ScopeMetrics",
70
60
  "setup_logging",
71
- "Structure",
61
+ "State",
72
62
  "throttle",
63
+ "timeout",
73
64
  "when_missing",
74
- "with_timeout",
75
65
  ]
@@ -1,14 +1,10 @@
1
1
  from haiway.context.access import ctx
2
- from haiway.context.dependencies import Dependencies, Dependency
3
2
  from haiway.context.metrics import ScopeMetrics
4
- from haiway.context.types import MissingContext, MissingDependency, MissingState
3
+ from haiway.context.types import MissingContext, MissingState
5
4
 
6
5
  __all__ = [
7
6
  "ctx",
8
- "Dependencies",
9
- "Dependency",
10
7
  "MissingContext",
11
- "MissingDependency",
12
8
  "MissingState",
13
9
  "ScopeMetrics",
14
10
  ]
haiway/context/access.py CHANGED
@@ -10,11 +10,10 @@ from logging import Logger
10
10
  from types import TracebackType
11
11
  from typing import Any, final
12
12
 
13
- from haiway.context.dependencies import Dependencies, Dependency
14
13
  from haiway.context.metrics import MetricsContext, ScopeMetrics
15
14
  from haiway.context.state import StateContext
16
15
  from haiway.context.tasks import TaskGroupContext
17
- from haiway.state import Structure
16
+ from haiway.state import State
18
17
  from haiway.utils import freeze
19
18
 
20
19
  __all__ = [
@@ -101,7 +100,7 @@ class ctx:
101
100
  def scope(
102
101
  name: str,
103
102
  /,
104
- *state: Structure,
103
+ *state: State,
105
104
  logger: Logger | None = None,
106
105
  trace_id: str | None = None,
107
106
  completion: Callable[[ScopeMetrics], Coroutine[None, None, None]] | None = None,
@@ -115,7 +114,7 @@ class ctx:
115
114
  name: Value
116
115
  name of the scope context
117
116
 
118
- *state: Structure
117
+ *state: State
119
118
  state propagated within the scope context, will be merged with current if any\
120
119
  by replacing current with provided on conflict
121
120
 
@@ -152,7 +151,7 @@ class ctx:
152
151
 
153
152
  @staticmethod
154
153
  def updated(
155
- *state: Structure,
154
+ *state: State,
156
155
  ) -> StateContext:
157
156
  """
158
157
  Update scope context with given state. When called within an existing context\
@@ -160,7 +159,7 @@ class ctx:
160
159
 
161
160
  Parameters
162
161
  ----------
163
- *state: Structure
162
+ *state: State
164
163
  state propagated within the updated scope context, will be merged with current if any\
165
164
  by replacing current with provided on conflict
166
165
 
@@ -215,28 +214,7 @@ class ctx:
215
214
  raise RuntimeError("Attempting to cancel context out of asyncio task")
216
215
 
217
216
  @staticmethod
218
- async def dependency[DependencyType: Dependency](
219
- dependency: type[DependencyType],
220
- /,
221
- ) -> DependencyType:
222
- """
223
- Access current dependency by its type.
224
-
225
- Parameters
226
- ----------
227
- dependency: type[DependencyType]
228
- type of requested dependency
229
-
230
- Returns
231
- -------
232
- DependencyType
233
- resolved dependency instance
234
- """
235
-
236
- return await Dependencies.dependency(dependency)
237
-
238
- @staticmethod
239
- def state[StateType: Structure](
217
+ def state[StateType: State](
240
218
  state: type[StateType],
241
219
  /,
242
220
  default: StateType | None = None,
@@ -261,7 +239,7 @@ class ctx:
261
239
  )
262
240
 
263
241
  @staticmethod
264
- def record[Metric: Structure](
242
+ def record[Metric: State](
265
243
  metric: Metric,
266
244
  /,
267
245
  merge: Callable[[Metric, Metric], Metric] = lambda lhs, rhs: rhs,
haiway/context/metrics.py CHANGED
@@ -9,7 +9,7 @@ from types import TracebackType
9
9
  from typing import Any, Self, cast, final, overload
10
10
  from uuid import uuid4
11
11
 
12
- from haiway.state import Structure
12
+ from haiway.state import State
13
13
  from haiway.utils import freeze
14
14
 
15
15
  __all__ = [
@@ -30,7 +30,7 @@ class ScopeMetrics:
30
30
  self.trace_id: str = trace_id or uuid4().hex
31
31
  self._label: str = f"{self.trace_id}|{scope}" if scope else self.trace_id
32
32
  self._logger: Logger = logger or getLogger(name=scope)
33
- self._metrics: dict[type[Structure], Structure] = {}
33
+ self._metrics: dict[type[State], State] = {}
34
34
  self._nested: list[ScopeMetrics] = []
35
35
  self._timestamp: float = monotonic()
36
36
  self._completed: Future[float] = get_event_loop().create_future()
@@ -46,11 +46,11 @@ class ScopeMetrics:
46
46
  def metrics(
47
47
  self,
48
48
  *,
49
- merge: Callable[[Structure, Structure], Structure] = lambda lhs, rhs: lhs,
50
- ) -> list[Structure]:
51
- metrics: dict[type[Structure], Structure] = copy(self._metrics)
49
+ merge: Callable[[State, State], State] = lambda lhs, rhs: lhs,
50
+ ) -> list[State]:
51
+ metrics: dict[type[State], State] = copy(self._metrics)
52
52
  for metric in chain.from_iterable(nested.metrics(merge=merge) for nested in self._nested):
53
- metric_type: type[Structure] = type(metric)
53
+ metric_type: type[State] = type(metric)
54
54
  if current := metrics.get(metric_type):
55
55
  metrics[metric_type] = merge(current, metric)
56
56
 
@@ -60,21 +60,21 @@ class ScopeMetrics:
60
60
  return list(metrics.values())
61
61
 
62
62
  @overload
63
- def read[Metric: Structure](
63
+ def read[Metric: State](
64
64
  self,
65
65
  metric: type[Metric],
66
66
  /,
67
67
  ) -> Metric | None: ...
68
68
 
69
69
  @overload
70
- def read[Metric: Structure](
70
+ def read[Metric: State](
71
71
  self,
72
72
  metric: type[Metric],
73
73
  /,
74
74
  default: Metric,
75
75
  ) -> Metric: ...
76
76
 
77
- def read[Metric: Structure](
77
+ def read[Metric: State](
78
78
  self,
79
79
  metric: type[Metric],
80
80
  /,
@@ -82,7 +82,7 @@ class ScopeMetrics:
82
82
  ) -> Metric | None:
83
83
  return cast(Metric | None, self._metrics.get(metric, default))
84
84
 
85
- def record[Metric: Structure](
85
+ def record[Metric: State](
86
86
  self,
87
87
  metric: Metric,
88
88
  /,
@@ -187,7 +187,7 @@ class MetricsContext:
187
187
  )
188
188
 
189
189
  @classmethod
190
- def record[Metric: Structure](
190
+ def record[Metric: State](
191
191
  cls,
192
192
  metric: Metric,
193
193
  /,
haiway/context/state.py CHANGED
@@ -4,7 +4,7 @@ from types import TracebackType
4
4
  from typing import Self, cast, final
5
5
 
6
6
  from haiway.context.types import MissingContext, MissingState
7
- from haiway.state import Structure
7
+ from haiway.state import State
8
8
  from haiway.utils import freeze
9
9
 
10
10
  __all__ = [
@@ -17,28 +17,26 @@ __all__ = [
17
17
  class ScopeState:
18
18
  def __init__(
19
19
  self,
20
- state: Iterable[Structure],
20
+ state: Iterable[State],
21
21
  ) -> None:
22
- self._state: dict[type[Structure], Structure] = {
23
- type(element): element for element in state
24
- }
22
+ self._state: dict[type[State], State] = {type(element): element for element in state}
25
23
  freeze(self)
26
24
 
27
- def state[State: Structure](
25
+ def state[StateType: State](
28
26
  self,
29
- state: type[State],
27
+ state: type[StateType],
30
28
  /,
31
- default: State | None = None,
32
- ) -> State:
29
+ default: StateType | None = None,
30
+ ) -> StateType:
33
31
  if state in self._state:
34
- return cast(State, self._state[state])
32
+ return cast(StateType, self._state[state])
35
33
 
36
34
  elif default is not None:
37
35
  return default
38
36
 
39
37
  else:
40
38
  try:
41
- initialized: State = state()
39
+ initialized: StateType = state()
42
40
  self._state[state] = initialized
43
41
  return initialized
44
42
 
@@ -50,7 +48,7 @@ class ScopeState:
50
48
 
51
49
  def updated(
52
50
  self,
53
- state: Iterable[Structure],
51
+ state: Iterable[State],
54
52
  ) -> Self:
55
53
  if state:
56
54
  return self.__class__(
@@ -69,12 +67,12 @@ class StateContext:
69
67
  _context = ContextVar[ScopeState]("StateContext")
70
68
 
71
69
  @classmethod
72
- def current[State: Structure](
70
+ def current[StateType: State](
73
71
  cls,
74
- state: type[State],
72
+ state: type[StateType],
75
73
  /,
76
- default: State | None = None,
77
- ) -> State:
74
+ default: StateType | None = None,
75
+ ) -> StateType:
78
76
  try:
79
77
  return cls._context.get().state(state, default=default)
80
78
 
@@ -84,7 +82,7 @@ class StateContext:
84
82
  @classmethod
85
83
  def updated(
86
84
  cls,
87
- state: Iterable[Structure],
85
+ state: Iterable[State],
88
86
  /,
89
87
  ) -> Self:
90
88
  try:
haiway/context/types.py CHANGED
@@ -1,6 +1,5 @@
1
1
  __all__ = [
2
2
  "MissingContext",
3
- "MissingDependency",
4
3
  "MissingState",
5
4
  ]
6
5
 
@@ -9,9 +8,5 @@ class MissingContext(Exception):
9
8
  pass
10
9
 
11
10
 
12
- class MissingDependency(Exception):
13
- pass
14
-
15
-
16
11
  class MissingState(Exception):
17
12
  pass
@@ -1,13 +1,16 @@
1
1
  from haiway.helpers.asynchronous import asynchronous
2
- from haiway.helpers.cache import cached
3
- from haiway.helpers.retry import auto_retry
2
+ from haiway.helpers.cached import cache
3
+ from haiway.helpers.disposables import Disposable, Disposables
4
+ from haiway.helpers.retries import retry
4
5
  from haiway.helpers.throttling import throttle
5
- from haiway.helpers.timeout import with_timeout
6
+ from haiway.helpers.timeouted import timeout
6
7
 
7
8
  __all__ = [
8
9
  "asynchronous",
9
- "auto_retry",
10
- "cached",
10
+ "cache",
11
+ "Disposable",
12
+ "Disposables",
13
+ "retry",
11
14
  "throttle",
12
- "with_timeout",
15
+ "timeout",
13
16
  ]
@@ -9,26 +9,26 @@ from weakref import ref
9
9
  from haiway.utils.mimic import mimic_function
10
10
 
11
11
  __all__ = [
12
- "cached",
12
+ "cache",
13
13
  ]
14
14
 
15
15
 
16
16
  @overload
17
- def cached[**Args, Result](
17
+ def cache[**Args, Result](
18
18
  function: Callable[Args, Result],
19
19
  /,
20
20
  ) -> Callable[Args, Result]: ...
21
21
 
22
22
 
23
23
  @overload
24
- def cached[**Args, Result](
24
+ def cache[**Args, Result](
25
25
  *,
26
26
  limit: int = 1,
27
27
  expiration: float | None = None,
28
28
  ) -> Callable[[Callable[Args, Result]], Callable[Args, Result]]: ...
29
29
 
30
30
 
31
- def cached[**Args, Result](
31
+ def cache[**Args, Result](
32
32
  function: Callable[Args, Result] | None = None,
33
33
  *,
34
34
  limit: int = 1,
@@ -0,0 +1,65 @@
1
+ from asyncio import gather, shield
2
+ from collections.abc import Iterable
3
+ from types import TracebackType
4
+ from typing import Protocol, final, runtime_checkable
5
+
6
+ from haiway.state import State
7
+
8
+ __all__ = [
9
+ "Disposable",
10
+ "Disposables",
11
+ ]
12
+
13
+
14
+ @runtime_checkable
15
+ class Disposable(Protocol):
16
+ async def initialize(self) -> State | None: ...
17
+ async def dispose(self) -> None: ...
18
+
19
+
20
+ @final
21
+ class Disposables:
22
+ def __init__(
23
+ self,
24
+ *disposables: Disposable,
25
+ ) -> None:
26
+ self._disposables: tuple[Disposable, ...] = disposables
27
+
28
+ async def initialize(self) -> Iterable[State]:
29
+ return [
30
+ state
31
+ for state in await gather(
32
+ *[disposable.initialize() for disposable in self._disposables],
33
+ )
34
+ if state is not None
35
+ ]
36
+
37
+ async def dispose(self) -> None:
38
+ results: list[BaseException | None] = await shield(
39
+ gather(
40
+ *[disposable.dispose() for disposable in self._disposables],
41
+ return_exceptions=True,
42
+ ),
43
+ )
44
+
45
+ self._disposables = ()
46
+ exceptions: list[BaseException] = [
47
+ exception for exception in results if exception is not None
48
+ ]
49
+
50
+ if len(exceptions) > 1:
51
+ raise BaseExceptionGroup("Disposing errors", exceptions)
52
+
53
+ elif exceptions:
54
+ raise exceptions[0]
55
+
56
+ async def __aenter__(self) -> Iterable[State]:
57
+ return await self.initialize()
58
+
59
+ async def __aexit__(
60
+ self,
61
+ exc_type: type[BaseException] | None,
62
+ exc_val: BaseException | None,
63
+ exc_tb: TracebackType | None,
64
+ ) -> None:
65
+ await self.dispose()
@@ -1,17 +1,18 @@
1
1
  from asyncio import CancelledError, iscoroutinefunction, sleep
2
2
  from collections.abc import Callable, Coroutine
3
+ from time import sleep as sleep_sync
3
4
  from typing import cast, overload
4
5
 
5
6
  from haiway.context import ctx
6
7
  from haiway.utils import mimic_function
7
8
 
8
9
  __all__ = [
9
- "auto_retry",
10
+ "retry",
10
11
  ]
11
12
 
12
13
 
13
14
  @overload
14
- def auto_retry[**Args, Result](
15
+ def retry[**Args, Result](
15
16
  function: Callable[Args, Result],
16
17
  /,
17
18
  ) -> Callable[Args, Result]:
@@ -34,7 +35,7 @@ def auto_retry[**Args, Result](
34
35
 
35
36
 
36
37
  @overload
37
- def auto_retry[**Args, Result](
38
+ def retry[**Args, Result](
38
39
  *,
39
40
  limit: int = 1,
40
41
  delay: Callable[[int, Exception], float] | float | None = None,
@@ -66,7 +67,7 @@ def auto_retry[**Args, Result](
66
67
  """
67
68
 
68
69
 
69
- def auto_retry[**Args, Result](
70
+ def retry[**Args, Result](
70
71
  function: Callable[Args, Result] | None = None,
71
72
  *,
72
73
  limit: int = 1,
@@ -115,11 +116,12 @@ def auto_retry[**Args, Result](
115
116
  catching=catching if isinstance(catching, set | tuple) else {catching},
116
117
  ),
117
118
  )
119
+
118
120
  else:
119
- assert delay is None, "Delay is not supported in sync wrapper" # nosec: B101
120
121
  return _wrap_sync(
121
122
  function,
122
123
  limit=limit,
124
+ delay=delay,
123
125
  catching=catching if isinstance(catching, set | tuple) else {catching},
124
126
  )
125
127
 
@@ -133,6 +135,7 @@ def _wrap_sync[**Args, Result](
133
135
  function: Callable[Args, Result],
134
136
  *,
135
137
  limit: int,
138
+ delay: Callable[[int, Exception], float] | float | None,
136
139
  catching: set[type[Exception]] | tuple[type[Exception], ...],
137
140
  ) -> Callable[Args, Result]:
138
141
  assert limit > 0, "Limit has to be greater than zero" # nosec: B101
@@ -158,6 +161,16 @@ def _wrap_sync[**Args, Result](
158
161
  exc,
159
162
  )
160
163
 
164
+ match delay:
165
+ case None:
166
+ continue
167
+
168
+ case float(strict):
169
+ sleep_sync(strict)
170
+
171
+ case make_delay: # type: Callable[[], float]
172
+ sleep_sync(make_delay(attempt, exc)) # pyright: ignore[reportCallIssue, reportUnknownArgumentType]
173
+
161
174
  else:
162
175
  raise exc
163
176
 
@@ -199,10 +212,10 @@ def _wrap_async[**Args, Result](
199
212
  continue
200
213
 
201
214
  case float(strict):
202
- await sleep(delay=strict)
215
+ await sleep(strict)
203
216
 
204
217
  case make_delay: # type: Callable[[], float]
205
- await sleep(delay=make_delay(attempt, exc)) # pyright: ignore[reportCallIssue, reportUnknownArgumentType]
218
+ await sleep(make_delay(attempt, exc)) # pyright: ignore[reportCallIssue, reportUnknownArgumentType]
206
219
 
207
220
  else:
208
221
  raise exc
@@ -4,11 +4,11 @@ from collections.abc import Callable, Coroutine
4
4
  from haiway.utils.mimic import mimic_function
5
5
 
6
6
  __all__ = [
7
- "with_timeout",
7
+ "timeout",
8
8
  ]
9
9
 
10
10
 
11
- def with_timeout[**Args, Result](
11
+ def timeout[**Args, Result](
12
12
  timeout: float,
13
13
  /,
14
14
  ) -> Callable[
haiway/state/__init__.py CHANGED
@@ -1,8 +1,8 @@
1
1
  from haiway.state.attributes import AttributeAnnotation, attribute_annotations
2
- from haiway.state.structure import Structure
2
+ from haiway.state.structure import State
3
3
 
4
4
  __all__ = [
5
5
  "attribute_annotations",
6
6
  "AttributeAnnotation",
7
- "Structure",
7
+ "State",
8
8
  ]
@@ -52,7 +52,7 @@ def attribute_annotations(
52
52
 
53
53
  self_annotation = AttributeAnnotation(
54
54
  origin=cls,
55
- arguments=[], # ignore self arguments here, Structure will have them resolved at this stage
55
+ arguments=[], # ignore self arguments here, State will have them resolved at this stage
56
56
  )
57
57
  localns: dict[str, Any] = {cls.__name__: cls}
58
58
  recursion_guard: dict[Any, AttributeAnnotation] = {cls: self_annotation}
haiway/state/structure.py CHANGED
@@ -19,12 +19,12 @@ from haiway.state.validation import attribute_type_validator
19
19
  from haiway.types.missing import MISSING, Missing
20
20
 
21
21
  __all__ = [
22
- "Structure",
22
+ "State",
23
23
  ]
24
24
 
25
25
 
26
26
  @final
27
- class StructureAttribute[Value]:
27
+ class StateAttribute[Value]:
28
28
  def __init__(
29
29
  self,
30
30
  annotation: AttributeAnnotation,
@@ -48,7 +48,7 @@ class StructureAttribute[Value]:
48
48
  frozen_default=True,
49
49
  field_specifiers=(),
50
50
  )
51
- class StructureMeta(type):
51
+ class StateMeta(type):
52
52
  def __new__(
53
53
  cls,
54
54
  /,
@@ -58,7 +58,7 @@ class StructureMeta(type):
58
58
  type_parameters: dict[str, Any] | None = None,
59
59
  **kwargs: Any,
60
60
  ) -> Any:
61
- structure_type = type.__new__(
61
+ state_type = type.__new__(
62
62
  cls,
63
63
  name,
64
64
  bases,
@@ -66,28 +66,28 @@ class StructureMeta(type):
66
66
  **kwargs,
67
67
  )
68
68
 
69
- attributes: dict[str, StructureAttribute[Any]] = {}
69
+ attributes: dict[str, StateAttribute[Any]] = {}
70
70
 
71
71
  if bases: # handle base class
72
72
  for key, annotation in attribute_annotations(
73
- structure_type,
73
+ state_type,
74
74
  type_parameters=type_parameters,
75
75
  ).items():
76
76
  # do not include ClassVars and dunder items
77
77
  if ((get_origin(annotation) or annotation) is ClassVar) or key.startswith("__"):
78
78
  continue
79
79
 
80
- attributes[key] = StructureAttribute(
80
+ attributes[key] = StateAttribute(
81
81
  annotation=annotation,
82
- default=getattr(structure_type, key, MISSING),
82
+ default=getattr(state_type, key, MISSING),
83
83
  validator=attribute_type_validator(annotation),
84
84
  )
85
85
 
86
- structure_type.__ATTRIBUTES__ = attributes # pyright: ignore[reportAttributeAccessIssue]
87
- structure_type.__slots__ = frozenset(attributes.keys()) # pyright: ignore[reportAttributeAccessIssue]
88
- structure_type.__match_args__ = structure_type.__slots__ # pyright: ignore[reportAttributeAccessIssue]
86
+ state_type.__ATTRIBUTES__ = attributes # pyright: ignore[reportAttributeAccessIssue]
87
+ state_type.__slots__ = frozenset(attributes.keys()) # pyright: ignore[reportAttributeAccessIssue]
88
+ state_type.__match_args__ = state_type.__slots__ # pyright: ignore[reportAttributeAccessIssue]
89
89
 
90
- return structure_type
90
+ return state_type
91
91
 
92
92
 
93
93
  _types_cache: WeakValueDictionary[
@@ -99,12 +99,12 @@ _types_cache: WeakValueDictionary[
99
99
  ] = WeakValueDictionary()
100
100
 
101
101
 
102
- class Structure(metaclass=StructureMeta):
102
+ class State(metaclass=StateMeta):
103
103
  """
104
104
  Base class for immutable data structures.
105
105
  """
106
106
 
107
- __ATTRIBUTES__: ClassVar[dict[str, StructureAttribute[Any]]]
107
+ __ATTRIBUTES__: ClassVar[dict[str, StateAttribute[Any]]]
108
108
 
109
109
  def __class_getitem__(
110
110
  cls,
@@ -151,7 +151,7 @@ class Structure(metaclass=StructureMeta):
151
151
  name: str = f"{cls.__name__}[{parameter_names}]"
152
152
  bases: tuple[type[Self]] = (cls,)
153
153
 
154
- parametrized_type: type[Self] = StructureMeta.__new__(
154
+ parametrized_type: type[Self] = StateMeta.__new__(
155
155
  cls.__class__,
156
156
  name=name,
157
157
  bases=bases,
@@ -211,7 +211,7 @@ class Structure(metaclass=StructureMeta):
211
211
  value: Any,
212
212
  ) -> Any:
213
213
  raise AttributeError(
214
- f"Can't modify immutable structure {self.__class__.__qualname__},"
214
+ f"Can't modify immutable state {self.__class__.__qualname__},"
215
215
  f" attribute - '{name}' cannot be modified"
216
216
  )
217
217
 
@@ -220,7 +220,7 @@ class Structure(metaclass=StructureMeta):
220
220
  name: str,
221
221
  ) -> None:
222
222
  raise AttributeError(
223
- f"Can't modify immutable structure {self.__class__.__qualname__},"
223
+ f"Can't modify immutable state {self.__class__.__qualname__},"
224
224
  f" attribute - '{name}' cannot be deleted"
225
225
  )
226
226
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: haiway
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Framework for dependency injection and state management within structured concurrency model.
5
5
  Maintainer-email: Kacper Kaliński <kacper.kalinski@miquido.com>
6
6
  License: MIT License
@@ -0,0 +1,35 @@
1
+ haiway/__init__.py,sha256=Yw4Oh1N-xv2R9C-caH91DxB5I5tWLMuqYefIWxwpCX0,1130
2
+ haiway/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ haiway/context/__init__.py,sha256=8a2aiE9fmBBmkLL7_QzRKYdCac1ttt_KoPB62dWDDI8,236
4
+ haiway/context/access.py,sha256=gVDUGvdX6yBUQjgVNotg7DugtqH1rE-efddEENBB16E,10672
5
+ haiway/context/metrics.py,sha256=upkqUp47NymDJE8UQznr99AgaE9yw6i28l_cdCE1IeM,8612
6
+ haiway/context/state.py,sha256=GxGwPQTK8FdSprBd83lQbA9veubp0o93_1Yk3gb7HMc,3000
7
+ haiway/context/tasks.py,sha256=xXtXIUwXOra0EePTdkcEbMOmpWwFcO3hCRfR_IfvAHk,1978
8
+ haiway/context/types.py,sha256=VvJA7wAPZ3ISpgyThVguioYUXqhHf0XkPfRd0M1ERiQ,142
9
+ haiway/helpers/__init__.py,sha256=cZzbOjdodz4-CjCu2WqrTSJL5MqgaY10YRiWBizVZKA,418
10
+ haiway/helpers/asynchronous.py,sha256=FYcV_ERrGy7f47y18oKeUk7fcbk-i_SOuPQ7lHhX5iI,6119
11
+ haiway/helpers/cached.py,sha256=Ok_WE5Whe7XqnIuLZo4rNNBFeWap-aUWX799s4b1JAQ,9536
12
+ haiway/helpers/disposables.py,sha256=zygeghLaQF77orawLpOjUOKKCsN1S5CwwVrNtS7A5G0,1696
13
+ haiway/helpers/retries.py,sha256=gIkyUlqJLDYaxIZd3qzeqGFY9y5Gp8dgZLlZ6hs8hoc,7538
14
+ haiway/helpers/throttling.py,sha256=zo0OwFq64si5KUwhd58cFHLmGAmYwRbFRJMbv9suhPs,3844
15
+ haiway/helpers/timeouted.py,sha256=1xU09hQnFdj6p48BwZl5xUvtIr3zC0ZUXehkdrduCjs,3074
16
+ haiway/state/__init__.py,sha256=dh7l_ZImy0uHHDGD-fzMhQFmz_ej8WU8WEE2OmIoyVM,204
17
+ haiway/state/attributes.py,sha256=kkIYNlvWCM1NkgiCbE6gZDwgBVOk_TkmqWv67MmU0to,13399
18
+ haiway/state/structure.py,sha256=G-Ln72hoQtE0FmKHeZdNmXf_FA3f5-e5AGbmJ2yMNb4,7003
19
+ haiway/state/validation.py,sha256=V4Q94Ik4p9t7f-7EIwK3Q9Zki8VkLOjPIGWGwLRVCoc,2873
20
+ haiway/types/__init__.py,sha256=cAJQzDgFi8AKRqpzY3HWrutaPR69tnJqeJK_mQVtYUk,252
21
+ haiway/types/frozen.py,sha256=CZhFCXnWAKEhuWSfILxA8smfdpMd5Ku694ycfLh98R8,76
22
+ haiway/types/missing.py,sha256=3t2bcZuw5fAKiycP-0Aly2TDUWtM3xyHy3KDCT91TLs,1660
23
+ haiway/utils/__init__.py,sha256=UA9h8YDvYI5rYujvsIS9t5Q-SWYImmk30uhR_42flqs,608
24
+ haiway/utils/always.py,sha256=2abp8Lm9rQkrfS3rm1Iqhb-IcWyVfH1BULab3KMxgOw,1234
25
+ haiway/utils/env.py,sha256=lKPOBZWyRD_gQariDGBjVLYTm0740nytPCSQpK2oRyE,3136
26
+ haiway/utils/immutable.py,sha256=K34ZIMzbkpgkHKH-KF73plEbXExsajNRkRTYp9nJEf4,620
27
+ haiway/utils/logs.py,sha256=oDsc1ZdqKDjlTlctLbDcp9iX98Acr-1tdw-Pyg3DElo,1577
28
+ haiway/utils/mimic.py,sha256=BkVjTVP2TxxC8GChPGyDV6UXVwJmiRiSWeOYZNZFHxs,1828
29
+ haiway/utils/noop.py,sha256=qgbZlOKWY6_23Zs43OLukK2HagIQKRyR04zrFVm5rWI,344
30
+ haiway/utils/queue.py,sha256=WGW8kSusIwRYHsYRIKD2CaqhhC1pUtVgtNHFDXDtYrw,2443
31
+ haiway-0.2.0.dist-info/LICENSE,sha256=GehQEW_I1pkmxkkj3NEa7rCTQKYBn7vTPabpDYJlRuo,1063
32
+ haiway-0.2.0.dist-info/METADATA,sha256=mKWhetnV8FpSXvtJra92P5bZHLo_UDZb2PjF-xf-2Kk,3872
33
+ haiway-0.2.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
34
+ haiway-0.2.0.dist-info/top_level.txt,sha256=_LdXVLzUzgkvAGQnQJj5kQfoFhpPW6EF4Kj9NapniLg,7
35
+ haiway-0.2.0.dist-info/RECORD,,
@@ -1,61 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from asyncio import Lock, gather, shield
3
- from typing import ClassVar, Self, cast, final
4
-
5
- __all__ = [
6
- "Dependencies",
7
- "Dependency",
8
- ]
9
-
10
-
11
- class Dependency(ABC):
12
- @classmethod
13
- @abstractmethod
14
- async def prepare(cls) -> Self: ...
15
-
16
- async def dispose(self) -> None: # noqa: B027
17
- pass
18
-
19
-
20
- @final
21
- class Dependencies:
22
- _lock: ClassVar[Lock] = Lock()
23
- _dependencies: ClassVar[dict[type[Dependency], Dependency]] = {}
24
-
25
- def __init__(self) -> None:
26
- raise NotImplementedError("Can't instantiate Dependencies")
27
-
28
- @classmethod
29
- async def dependency[Requested: Dependency](
30
- cls,
31
- dependency: type[Requested],
32
- /,
33
- ) -> Requested:
34
- async with cls._lock:
35
- if dependency not in cls._dependencies:
36
- cls._dependencies[dependency] = await dependency.prepare()
37
-
38
- return cast(Requested, cls._dependencies[dependency])
39
-
40
- @classmethod
41
- async def register(
42
- cls,
43
- dependency: Dependency,
44
- /,
45
- ) -> None:
46
- async with cls._lock:
47
- if current := cls._dependencies.get(dependency.__class__):
48
- await current.dispose()
49
-
50
- cls._dependencies[dependency.__class__] = dependency
51
-
52
- @classmethod
53
- async def dispose(cls) -> None:
54
- async with cls._lock:
55
- await shield(
56
- gather(
57
- *[dependency.dispose() for dependency in cls._dependencies.values()],
58
- return_exceptions=False,
59
- )
60
- )
61
- cls._dependencies.clear()
@@ -1,35 +0,0 @@
1
- haiway/__init__.py,sha256=20WZqVGbImtVKnZLFw1CU1usQbXjLSEHcu1J07OTEhA,1243
2
- haiway/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- haiway/context/__init__.py,sha256=iD_AjgtyJthrkF0Ys2vHxSDLDK54GkcLk-h33HyD4P0,383
4
- haiway/context/access.py,sha256=pdc0pZIwQlW24hDcojoE3lUrpC2zvyH-PtoOOGS7D9g,11263
5
- haiway/context/dependencies.py,sha256=US1TYM78AHujat9SxLKrP7Ow1dctdLN-OqEx3grBv0Y,1609
6
- haiway/context/metrics.py,sha256=OF06T9Er62SJPCZmQF9SnMW8lO9HGxDP3qUkvk6mXUo,8672
7
- haiway/context/state.py,sha256=aQgUE3tAWPEYgGv4P16Yk9RkOouY8UpkEpjhzv0AwkA,3014
8
- haiway/context/tasks.py,sha256=xXtXIUwXOra0EePTdkcEbMOmpWwFcO3hCRfR_IfvAHk,1978
9
- haiway/context/types.py,sha256=OS3d2A0F2CbOpz_hxAhBitSH2_Bs8Aw-kIL6mEBmZdw,214
10
- haiway/helpers/__init__.py,sha256=WBGQ3pF6EhCjEQLpMfpW7LwF5u-iR26fr9q6l7xTEJE,335
11
- haiway/helpers/asynchronous.py,sha256=FYcV_ERrGy7f47y18oKeUk7fcbk-i_SOuPQ7lHhX5iI,6119
12
- haiway/helpers/cache.py,sha256=oONE0xKIfhvPA_wnY8JV_2CtOeSrHAoNpu5n7t-jd8w,9540
13
- haiway/helpers/retry.py,sha256=qFeLvOiqAktF-awkh-hTdhyT2zf6kGV0VxAIBrUVdn0,7135
14
- haiway/helpers/throttling.py,sha256=zo0OwFq64si5KUwhd58cFHLmGAmYwRbFRJMbv9suhPs,3844
15
- haiway/helpers/timeout.py,sha256=iNfDotZ4G9rb_zEuEgzaZP37QqkkXQyEFHClA4Eckl0,3084
16
- haiway/state/__init__.py,sha256=sFEo9tWwMK5r6RR_D6d2xRL2Tcb7NgWIEUHx-FCbvbI,212
17
- haiway/state/attributes.py,sha256=DIjr8NAhabJJiHHiNc_t7-t9AncobiXg_JRZ3lJ-_G0,13403
18
- haiway/state/structure.py,sha256=AQIVz-DUBMFMgBHXbOvLrplmdSCmL3xRjCDwNhFTLV8,7079
19
- haiway/state/validation.py,sha256=V4Q94Ik4p9t7f-7EIwK3Q9Zki8VkLOjPIGWGwLRVCoc,2873
20
- haiway/types/__init__.py,sha256=cAJQzDgFi8AKRqpzY3HWrutaPR69tnJqeJK_mQVtYUk,252
21
- haiway/types/frozen.py,sha256=CZhFCXnWAKEhuWSfILxA8smfdpMd5Ku694ycfLh98R8,76
22
- haiway/types/missing.py,sha256=3t2bcZuw5fAKiycP-0Aly2TDUWtM3xyHy3KDCT91TLs,1660
23
- haiway/utils/__init__.py,sha256=UA9h8YDvYI5rYujvsIS9t5Q-SWYImmk30uhR_42flqs,608
24
- haiway/utils/always.py,sha256=2abp8Lm9rQkrfS3rm1Iqhb-IcWyVfH1BULab3KMxgOw,1234
25
- haiway/utils/env.py,sha256=lKPOBZWyRD_gQariDGBjVLYTm0740nytPCSQpK2oRyE,3136
26
- haiway/utils/immutable.py,sha256=K34ZIMzbkpgkHKH-KF73plEbXExsajNRkRTYp9nJEf4,620
27
- haiway/utils/logs.py,sha256=oDsc1ZdqKDjlTlctLbDcp9iX98Acr-1tdw-Pyg3DElo,1577
28
- haiway/utils/mimic.py,sha256=BkVjTVP2TxxC8GChPGyDV6UXVwJmiRiSWeOYZNZFHxs,1828
29
- haiway/utils/noop.py,sha256=qgbZlOKWY6_23Zs43OLukK2HagIQKRyR04zrFVm5rWI,344
30
- haiway/utils/queue.py,sha256=WGW8kSusIwRYHsYRIKD2CaqhhC1pUtVgtNHFDXDtYrw,2443
31
- haiway-0.1.0.dist-info/LICENSE,sha256=GehQEW_I1pkmxkkj3NEa7rCTQKYBn7vTPabpDYJlRuo,1063
32
- haiway-0.1.0.dist-info/METADATA,sha256=ZHdNdTn7cjJQUK6pK8onjkNS0QmOhjpFCWLsQyqQE0o,3872
33
- haiway-0.1.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
34
- haiway-0.1.0.dist-info/top_level.txt,sha256=_LdXVLzUzgkvAGQnQJj5kQfoFhpPW6EF4Kj9NapniLg,7
35
- haiway-0.1.0.dist-info/RECORD,,
File without changes