haiway 0.22.0__py3-none-any.whl → 0.22.1__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/context/access.py +9 -1
- haiway/context/disposables.py +32 -5
- haiway/context/state.py +17 -2
- haiway/helpers/__init__.py +1 -1
- haiway/state/structure.py +16 -6
- haiway/utils/__init__.py +0 -2
- {haiway-0.22.0.dist-info → haiway-0.22.1.dist-info}/METADATA +1 -1
- {haiway-0.22.0.dist-info → haiway-0.22.1.dist-info}/RECORD +11 -12
- haiway/utils/freezing.py +0 -46
- /haiway/helpers/{timeouted.py → timeouting.py} +0 -0
- {haiway-0.22.0.dist-info → haiway-0.22.1.dist-info}/WHEEL +0 -0
- {haiway-0.22.0.dist-info → haiway-0.22.1.dist-info}/licenses/LICENSE +0 -0
haiway/context/access.py
CHANGED
@@ -539,6 +539,8 @@ class ctx:
|
|
539
539
|
def check_state[StateType: State](
|
540
540
|
state: type[StateType],
|
541
541
|
/,
|
542
|
+
*,
|
543
|
+
instantiate_defaults: bool = False,
|
542
544
|
) -> bool:
|
543
545
|
"""
|
544
546
|
Check if state object is available in the current context.
|
@@ -551,12 +553,18 @@ class ctx:
|
|
551
553
|
state: type[StateType]
|
552
554
|
The type of state to check
|
553
555
|
|
556
|
+
instantiate_defaults: bool = False
|
557
|
+
Control if default value should be instantiated during check.
|
558
|
+
|
554
559
|
Returns
|
555
560
|
-------
|
556
561
|
bool
|
557
562
|
True if state is available, otherwise False.
|
558
563
|
"""
|
559
|
-
return StateContext.check_state(
|
564
|
+
return StateContext.check_state(
|
565
|
+
state,
|
566
|
+
instantiate_defaults=instantiate_defaults,
|
567
|
+
)
|
560
568
|
|
561
569
|
@staticmethod
|
562
570
|
def state[StateType: State](
|
haiway/context/disposables.py
CHANGED
@@ -12,7 +12,7 @@ from itertools import chain
|
|
12
12
|
from types import TracebackType
|
13
13
|
from typing import Any, final
|
14
14
|
|
15
|
-
from haiway.context.state import
|
15
|
+
from haiway.context.state import StateContext
|
16
16
|
from haiway.state import State
|
17
17
|
from haiway.utils.mimic import mimic_function
|
18
18
|
|
@@ -195,19 +195,25 @@ class Disposables:
|
|
195
195
|
return multiple
|
196
196
|
|
197
197
|
async def prepare(self) -> Iterable[State]:
|
198
|
+
"""
|
199
|
+
Enter all contained disposables asynchronously.
|
200
|
+
|
201
|
+
Enters all disposables in parallel and collects any State objects they return.
|
202
|
+
"""
|
198
203
|
assert self._loop is None # nosec: B101
|
199
204
|
object.__setattr__(
|
200
205
|
self,
|
201
206
|
"_loop",
|
202
207
|
get_running_loop(),
|
203
208
|
)
|
204
|
-
|
205
|
-
|
209
|
+
|
210
|
+
return tuple(
|
211
|
+
chain.from_iterable(
|
206
212
|
await gather(
|
207
213
|
*[self._setup(disposable) for disposable in self._disposables],
|
208
214
|
)
|
209
215
|
)
|
210
|
-
|
216
|
+
)
|
211
217
|
|
212
218
|
async def __aenter__(self) -> None:
|
213
219
|
"""
|
@@ -218,7 +224,7 @@ class Disposables:
|
|
218
224
|
"""
|
219
225
|
|
220
226
|
assert self._state_context is None, "Context reentrance is not allowed" # nosec: B101
|
221
|
-
state_context = StateContext(
|
227
|
+
state_context = StateContext.updated(await self.prepare())
|
222
228
|
state_context.__enter__()
|
223
229
|
object.__setattr__(
|
224
230
|
self,
|
@@ -252,6 +258,26 @@ class Disposables:
|
|
252
258
|
exc_val: BaseException | None = None,
|
253
259
|
exc_tb: TracebackType | None = None,
|
254
260
|
) -> None:
|
261
|
+
"""
|
262
|
+
Exit all contained disposables asynchronously.
|
263
|
+
|
264
|
+
Properly disposes of all resources by calling their __aexit__ methods in parallel.
|
265
|
+
If multiple disposables raise exceptions, they are collected into a BaseExceptionGroup.
|
266
|
+
|
267
|
+
Parameters
|
268
|
+
----------
|
269
|
+
exc_type: type[BaseException] | None
|
270
|
+
The type of exception that caused the context to be exited
|
271
|
+
exc_val: BaseException | None
|
272
|
+
The exception that caused the context to be exited
|
273
|
+
exc_tb: TracebackType | None
|
274
|
+
The traceback for the exception that caused the context to be exited
|
275
|
+
|
276
|
+
Raises
|
277
|
+
------
|
278
|
+
BaseExceptionGroup
|
279
|
+
If multiple disposables raise exceptions during exit
|
280
|
+
"""
|
255
281
|
assert self._loop is not None # nosec: B101
|
256
282
|
results: list[bool | BaseException | None]
|
257
283
|
|
@@ -306,6 +332,7 @@ class Disposables:
|
|
306
332
|
|
307
333
|
Properly disposes of all resources by calling their __aexit__ methods in parallel.
|
308
334
|
If multiple disposables raise exceptions, they are collected into a BaseExceptionGroup.
|
335
|
+
Additionally, produced state context will be also exited resetting state to previous.
|
309
336
|
|
310
337
|
Parameters
|
311
338
|
----------
|
haiway/context/state.py
CHANGED
@@ -67,6 +67,8 @@ class ScopeState:
|
|
67
67
|
self,
|
68
68
|
state: type[StateType],
|
69
69
|
/,
|
70
|
+
*,
|
71
|
+
instantiate_defaults: bool = False,
|
70
72
|
) -> bool:
|
71
73
|
"""
|
72
74
|
Check state object availability by its type.
|
@@ -79,6 +81,9 @@ class ScopeState:
|
|
79
81
|
state: type[StateType]
|
80
82
|
The type of state to check
|
81
83
|
|
84
|
+
instantiate_defaults: bool = False
|
85
|
+
Control if default value should be instantiated during check.
|
86
|
+
|
82
87
|
Returns
|
83
88
|
-------
|
84
89
|
bool
|
@@ -87,7 +92,7 @@ class ScopeState:
|
|
87
92
|
if state in self._state:
|
88
93
|
return True
|
89
94
|
|
90
|
-
|
95
|
+
elif instantiate_defaults:
|
91
96
|
with self._lock:
|
92
97
|
if state in self._state:
|
93
98
|
return True
|
@@ -100,6 +105,9 @@ class ScopeState:
|
|
100
105
|
except BaseException:
|
101
106
|
return False # unavailable, we don't care the exception
|
102
107
|
|
108
|
+
else:
|
109
|
+
return False
|
110
|
+
|
103
111
|
def state[StateType: State](
|
104
112
|
self,
|
105
113
|
state: type[StateType],
|
@@ -201,6 +209,7 @@ class StateContext:
|
|
201
209
|
cls,
|
202
210
|
state: type[StateType],
|
203
211
|
/,
|
212
|
+
instantiate_defaults: bool = False,
|
204
213
|
) -> bool:
|
205
214
|
"""
|
206
215
|
Check if state object is available in the current context.
|
@@ -212,13 +221,19 @@ class StateContext:
|
|
212
221
|
state: type[StateType]
|
213
222
|
The type of state to check
|
214
223
|
|
224
|
+
instantiate_defaults: bool = False
|
225
|
+
Control if default value should be instantiated during check.
|
226
|
+
|
215
227
|
Returns
|
216
228
|
-------
|
217
229
|
bool
|
218
230
|
True if state is available, otherwise False.
|
219
231
|
"""
|
220
232
|
try:
|
221
|
-
return cls._context.get().check_state(
|
233
|
+
return cls._context.get().check_state(
|
234
|
+
state,
|
235
|
+
instantiate_defaults=instantiate_defaults,
|
236
|
+
)
|
222
237
|
|
223
238
|
except LookupError:
|
224
239
|
return False # no context no state
|
haiway/helpers/__init__.py
CHANGED
@@ -5,7 +5,7 @@ from haiway.helpers.files import File, FileAccess
|
|
5
5
|
from haiway.helpers.observability import LoggerObservability
|
6
6
|
from haiway.helpers.retries import retry
|
7
7
|
from haiway.helpers.throttling import throttle
|
8
|
-
from haiway.helpers.
|
8
|
+
from haiway.helpers.timeouting import timeout
|
9
9
|
from haiway.helpers.tracing import traced
|
10
10
|
|
11
11
|
__all__ = (
|
haiway/state/structure.py
CHANGED
@@ -729,12 +729,22 @@ class State(metaclass=StateMeta):
|
|
729
729
|
)
|
730
730
|
|
731
731
|
def __hash__(self) -> int:
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
732
|
+
hash_values: list[int] = []
|
733
|
+
for key in self.__ATTRIBUTES__.keys():
|
734
|
+
value: Any = getattr(self, key, MISSING)
|
735
|
+
|
736
|
+
# Skip MISSING values to ensure consistent hashing
|
737
|
+
if value is MISSING:
|
738
|
+
continue
|
739
|
+
|
740
|
+
# Convert to hashable representation
|
741
|
+
try:
|
742
|
+
hash_values.append(hash(value))
|
743
|
+
|
744
|
+
except TypeError:
|
745
|
+
continue # skip unhashable
|
746
|
+
|
747
|
+
return hash((self.__class__, tuple(hash_values)))
|
738
748
|
|
739
749
|
def __setattr__(
|
740
750
|
self,
|
haiway/utils/__init__.py
CHANGED
@@ -9,7 +9,6 @@ from haiway.utils.env import (
|
|
9
9
|
load_env,
|
10
10
|
)
|
11
11
|
from haiway.utils.formatting import format_str
|
12
|
-
from haiway.utils.freezing import freeze
|
13
12
|
from haiway.utils.logs import setup_logging
|
14
13
|
from haiway.utils.mimic import mimic_function
|
15
14
|
from haiway.utils.noop import async_noop, noop
|
@@ -27,7 +26,6 @@ __all__ = (
|
|
27
26
|
"async_always",
|
28
27
|
"async_noop",
|
29
28
|
"format_str",
|
30
|
-
"freeze",
|
31
29
|
"getenv_base64",
|
32
30
|
"getenv_bool",
|
33
31
|
"getenv_float",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: haiway
|
3
|
-
Version: 0.22.
|
3
|
+
Version: 0.22.1
|
4
4
|
Summary: Framework for dependency injection and state management within structured concurrency model.
|
5
5
|
Project-URL: Homepage, https://miquido.com
|
6
6
|
Project-URL: Repository, https://github.com/miquido/haiway.git
|
@@ -1,14 +1,14 @@
|
|
1
1
|
haiway/__init__.py,sha256=FiOAMHHawyGk9FfZU-1UflT8nmwu9J0CrG2QwrJGccw,1917
|
2
2
|
haiway/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
haiway/context/__init__.py,sha256=1N_SvdPkTfIZDZybm3y0rY2dGrDLWTm0ryzUz2XD4f8,1174
|
4
|
-
haiway/context/access.py,sha256=
|
5
|
-
haiway/context/disposables.py,sha256=
|
4
|
+
haiway/context/access.py,sha256=QCabyZtqqJjGTgAod1ZC3Fz3IfPsyurLo_i68RnCm4Q,25736
|
5
|
+
haiway/context/disposables.py,sha256=AP9eZ0BPHJZfjrrfrjSzr4jONMKkR6YmhjOfnBp37so,11504
|
6
6
|
haiway/context/identifier.py,sha256=dCCwLneXJzH__ZWFlGRUHvoCmbT4lM0QVbyokYIbUHg,5255
|
7
7
|
haiway/context/observability.py,sha256=gLKbMPNvt5ozrfyc4TGahN8A_dFFtyCjUIMZu9_wZHA,23722
|
8
|
-
haiway/context/state.py,sha256=
|
8
|
+
haiway/context/state.py,sha256=DuCtI0rMLWYbnBGXxpkbQgrX4aAftGkuK8XSd1JtdVc,11912
|
9
9
|
haiway/context/tasks.py,sha256=pScFgeiyrXSJRDFZiYbBLi3k_DHkSlhB8rgAnYtgyrU,4925
|
10
10
|
haiway/context/types.py,sha256=VDWXJySihfvSSPzY09PaGk6j5S9HgmAUboBGCZ8o_4k,766
|
11
|
-
haiway/helpers/__init__.py,sha256=
|
11
|
+
haiway/helpers/__init__.py,sha256=PTWpavAveEB2V9Au1QuaRZwh3Rkb1bQSNvo_mxuGqlE,721
|
12
12
|
haiway/helpers/asynchrony.py,sha256=Ddj8UdXhVczAbAC-rLpyhWa4RJ_W2Eolo45Veorq7_4,5362
|
13
13
|
haiway/helpers/caching.py,sha256=BqgcUGQSAmXsuLi5V8EwlZzuGyutHOn1V4k7BHsGKeg,14347
|
14
14
|
haiway/helpers/concurrent.py,sha256=xGMcan_tiETAHQs1YFmgYpA4YMFo6rIbFKvNeMlRFG8,2551
|
@@ -16,7 +16,7 @@ haiway/helpers/files.py,sha256=L6vXd8gdgWx5jPL8azloU8IGoFq2xnxjMc4ufz-gdl4,11650
|
|
16
16
|
haiway/helpers/observability.py,sha256=3G0eRE1WYTGRujS0mxzYbLR4MlKnoYllE8cu2Eb_23w,11073
|
17
17
|
haiway/helpers/retries.py,sha256=52LA85HejTiSmCmTMAA9c8oUqD_VnhbTn1b3kwlU52c,9032
|
18
18
|
haiway/helpers/throttling.py,sha256=KBWUSHdKVMC5_nRMmmoPNwfp-3AcerQ6OczJa9gNLM0,5796
|
19
|
-
haiway/helpers/
|
19
|
+
haiway/helpers/timeouting.py,sha256=GQ8-btb36f0Jq7TnorAPYXyKScNmf0nxHXCYxqGl-o8,3949
|
20
20
|
haiway/helpers/tracing.py,sha256=NHipA5UlngwFcAaKhXg1jTuJ-ti6AqSNxE7u7-92vWo,5409
|
21
21
|
haiway/opentelemetry/__init__.py,sha256=TV-1C14mDAtcHhFZ29ActFQdrGH6x5KuGV9w-JlKYJg,91
|
22
22
|
haiway/opentelemetry/observability.py,sha256=5fsHsFgjcxUcA0hIOM18lVvVdYSRO91ER52PticyzyU,25734
|
@@ -24,23 +24,22 @@ haiway/state/__init__.py,sha256=AaMqlMhO4zKS_XNevy3A7BHh5PxmguA-Sk_FnaNDY1Q,355
|
|
24
24
|
haiway/state/attributes.py,sha256=sububiFP23aBB8RGk6OvTUp7BEY6S0kER_uHC09yins,26733
|
25
25
|
haiway/state/path.py,sha256=bv5MI3HmUyku78k0Sz5lc7Q_Bay53iom1l3AL5KZs-4,32143
|
26
26
|
haiway/state/requirement.py,sha256=zNTx7s8FiMZKu9EV3T6f1SOJpR4SC9X5hhL--PVWPCY,15641
|
27
|
-
haiway/state/structure.py,sha256=
|
27
|
+
haiway/state/structure.py,sha256=CTf1l0TyKA7vkVDqA9RMdxaOVNSHwQduN2jb6H015hg,23798
|
28
28
|
haiway/state/validation.py,sha256=eDOZKRrfd-dmdbqoHcLacdCVKmVCEpwt239EG6ljNF8,23557
|
29
29
|
haiway/types/__init__.py,sha256=jFr5kf36SvVGdgngvik6_HzG8YNa3NVsdDDSqxVuGm4,281
|
30
30
|
haiway/types/default.py,sha256=59chcOaoGqI2to08RamCCLluimfYbJp5xbYl3fWaLrM,4153
|
31
31
|
haiway/types/missing.py,sha256=OfiyYUnzTk3arKWu8S6ORCEYGvcRu_mdL4j1ExdSvgI,4256
|
32
|
-
haiway/utils/__init__.py,sha256=
|
32
|
+
haiway/utils/__init__.py,sha256=Zs4mJnoRL_4ssGSZqvCFuhllxMDww_8-McsI2xB0mug,917
|
33
33
|
haiway/utils/always.py,sha256=dd6jDQ1j4DpJjTKO1J2Tv5xS8X1LnMC4kQ0D7DtKUvw,1230
|
34
34
|
haiway/utils/collections.py,sha256=gF5tC1EaEzBfPpXrHqR0mZh8e4pRwEPSVactvfN-30M,4737
|
35
35
|
haiway/utils/env.py,sha256=Z0uHJDFegvgzy-gM-f0uPMha9_1ldUglrD5SKNJsvYE,9445
|
36
36
|
haiway/utils/formatting.py,sha256=jgSIGalGUBZVo2ziiNC5Y7vBYbAEwPugOiwEOrNFTcI,4039
|
37
|
-
haiway/utils/freezing.py,sha256=HJH0SOgPCreb9o0wPeaMPMxhS9JDuzzey6UsKhuvUJU,1292
|
38
37
|
haiway/utils/logs.py,sha256=NuwoqKQnMNi1FMIA91cVFnAPefUFeg3UIT50IOl3sJk,1571
|
39
38
|
haiway/utils/mimic.py,sha256=xaZiUKp096QFfdSw7cNIKEWt2UIS7vf880KF54gny38,1831
|
40
39
|
haiway/utils/noop.py,sha256=U8ocfoCgt-pY0owJDPtrRrj53cabeIXH9qCKWMQnoRk,1336
|
41
40
|
haiway/utils/queue.py,sha256=6v2u3pA6A44IuCCTOjmCt3yLyOcm7PCRnrIGo25j-1o,6402
|
42
41
|
haiway/utils/stream.py,sha256=lXaeveTY0-AYG5xVzcQYaiC6SUD5fUtHoMXiQcrQAAM,5723
|
43
|
-
haiway-0.22.
|
44
|
-
haiway-0.22.
|
45
|
-
haiway-0.22.
|
46
|
-
haiway-0.22.
|
42
|
+
haiway-0.22.1.dist-info/METADATA,sha256=5M6G9KRMDiidXN6qWibXcpns40x11JTHCHNx5WOdD2U,4919
|
43
|
+
haiway-0.22.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
44
|
+
haiway-0.22.1.dist-info/licenses/LICENSE,sha256=3phcpHVNBP8jsi77gOO0E7rgKeDeu99Pi7DSnK9YHoQ,1069
|
45
|
+
haiway-0.22.1.dist-info/RECORD,,
|
haiway/utils/freezing.py
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
from typing import Any
|
2
|
-
|
3
|
-
__all__ = ("freeze",)
|
4
|
-
|
5
|
-
|
6
|
-
def freeze(
|
7
|
-
instance: object,
|
8
|
-
/,
|
9
|
-
) -> None:
|
10
|
-
"""
|
11
|
-
Make an object instance immutable by preventing attribute modification.
|
12
|
-
|
13
|
-
This function modifies the given object to prevent further changes to its attributes.
|
14
|
-
It replaces the object's __setattr__ and __delattr__ methods with ones that raise
|
15
|
-
exceptions, effectively making the object immutable after this function is called.
|
16
|
-
|
17
|
-
Parameters
|
18
|
-
----------
|
19
|
-
instance : object
|
20
|
-
The object instance to make immutable
|
21
|
-
|
22
|
-
Returns
|
23
|
-
-------
|
24
|
-
None
|
25
|
-
The object is modified in-place
|
26
|
-
|
27
|
-
Notes
|
28
|
-
-----
|
29
|
-
- This only affects direct attribute assignments and deletions
|
30
|
-
- Mutable objects contained within the instance can still be modified internally
|
31
|
-
- The object's class remains unchanged, only the specific instance is affected
|
32
|
-
"""
|
33
|
-
|
34
|
-
def frozen_set(
|
35
|
-
__name: str,
|
36
|
-
__value: Any,
|
37
|
-
) -> None:
|
38
|
-
raise RuntimeError(f"{instance.__class__.__qualname__} is frozen and can't be modified")
|
39
|
-
|
40
|
-
def frozen_del(
|
41
|
-
__name: str,
|
42
|
-
) -> None:
|
43
|
-
raise RuntimeError(f"{instance.__class__.__qualname__} is frozen and can't be modified")
|
44
|
-
|
45
|
-
instance.__delattr__ = frozen_del
|
46
|
-
instance.__setattr__ = frozen_set
|
File without changes
|
File without changes
|
File without changes
|