haiway 0.19.5__py3-none-any.whl → 0.20.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/__init__.py +2 -0
- haiway/context/__init__.py +2 -0
- haiway/context/access.py +88 -8
- haiway/context/disposables.py +63 -0
- haiway/context/identifier.py +81 -27
- haiway/context/observability.py +303 -7
- haiway/context/state.py +126 -0
- haiway/context/tasks.py +66 -0
- haiway/context/types.py +16 -0
- haiway/helpers/asynchrony.py +61 -12
- haiway/helpers/caching.py +31 -0
- haiway/helpers/concurrent.py +25 -14
- haiway/helpers/observability.py +94 -11
- haiway/helpers/retries.py +59 -18
- haiway/helpers/throttling.py +42 -15
- haiway/helpers/timeouted.py +25 -10
- haiway/helpers/tracing.py +31 -0
- haiway/opentelemetry/observability.py +346 -29
- haiway/state/attributes.py +104 -0
- haiway/state/path.py +427 -12
- haiway/state/requirement.py +196 -0
- haiway/state/structure.py +367 -1
- haiway/state/validation.py +293 -0
- haiway/types/default.py +56 -0
- haiway/types/frozen.py +18 -0
- haiway/types/missing.py +89 -0
- haiway/utils/collections.py +36 -28
- haiway/utils/env.py +145 -13
- haiway/utils/formatting.py +27 -0
- haiway/utils/freezing.py +21 -1
- haiway/utils/noop.py +34 -2
- haiway/utils/queue.py +68 -1
- haiway/utils/stream.py +83 -0
- {haiway-0.19.5.dist-info → haiway-0.20.1.dist-info}/METADATA +1 -1
- haiway-0.20.1.dist-info/RECORD +46 -0
- haiway-0.19.5.dist-info/RECORD +0 -46
- {haiway-0.19.5.dist-info → haiway-0.20.1.dist-info}/WHEEL +0 -0
- {haiway-0.19.5.dist-info → haiway-0.20.1.dist-info}/licenses/LICENSE +0 -0
haiway/state/requirement.py
CHANGED
@@ -8,6 +8,21 @@ __all__ = ("AttributeRequirement",)
|
|
8
8
|
|
9
9
|
@final
|
10
10
|
class AttributeRequirement[Root]:
|
11
|
+
"""
|
12
|
+
Represents a requirement or constraint on an attribute value.
|
13
|
+
|
14
|
+
This class provides a way to define and check constraints on attribute values
|
15
|
+
within State objects. It supports various comparison operations like equality,
|
16
|
+
containment, and logical combinations of requirements.
|
17
|
+
|
18
|
+
The class is generic over the Root type, which is the type of object that
|
19
|
+
contains the attribute being constrained.
|
20
|
+
|
21
|
+
Requirements can be combined using logical operators:
|
22
|
+
- & (AND): Both requirements must be met
|
23
|
+
- | (OR): At least one requirement must be met
|
24
|
+
"""
|
25
|
+
|
11
26
|
@classmethod
|
12
27
|
def equal[Parameter](
|
13
28
|
cls,
|
@@ -15,6 +30,26 @@ class AttributeRequirement[Root]:
|
|
15
30
|
/,
|
16
31
|
path: AttributePath[Root, Parameter] | Parameter,
|
17
32
|
) -> Self:
|
33
|
+
"""
|
34
|
+
Create a requirement that an attribute equals a specific value.
|
35
|
+
|
36
|
+
Parameters
|
37
|
+
----------
|
38
|
+
value : Parameter
|
39
|
+
The value to check equality against
|
40
|
+
path : AttributePath[Root, Parameter] | Parameter
|
41
|
+
The path to the attribute to check
|
42
|
+
|
43
|
+
Returns
|
44
|
+
-------
|
45
|
+
Self
|
46
|
+
A new requirement instance
|
47
|
+
|
48
|
+
Raises
|
49
|
+
------
|
50
|
+
AssertionError
|
51
|
+
If path is not an AttributePath
|
52
|
+
"""
|
18
53
|
assert isinstance( # nosec: B101
|
19
54
|
path, AttributePath
|
20
55
|
), "Prepare attribute path by using Self._.path.to.property or explicitly"
|
@@ -38,6 +73,26 @@ class AttributeRequirement[Root]:
|
|
38
73
|
/,
|
39
74
|
path: AttributePath[Root, Parameter] | Parameter,
|
40
75
|
) -> Self:
|
76
|
+
"""
|
77
|
+
Create a requirement that an attribute does not equal a specific value.
|
78
|
+
|
79
|
+
Parameters
|
80
|
+
----------
|
81
|
+
value : Parameter
|
82
|
+
The value to check inequality against
|
83
|
+
path : AttributePath[Root, Parameter] | Parameter
|
84
|
+
The path to the attribute to check
|
85
|
+
|
86
|
+
Returns
|
87
|
+
-------
|
88
|
+
Self
|
89
|
+
A new requirement instance
|
90
|
+
|
91
|
+
Raises
|
92
|
+
------
|
93
|
+
AssertionError
|
94
|
+
If path is not an AttributePath
|
95
|
+
"""
|
41
96
|
assert isinstance( # nosec: B101
|
42
97
|
path, AttributePath
|
43
98
|
), "Prepare attribute path by using Self._.path.to.property or explicitly"
|
@@ -68,6 +123,26 @@ class AttributeRequirement[Root]:
|
|
68
123
|
| list[Parameter]
|
69
124
|
| set[Parameter],
|
70
125
|
) -> Self:
|
126
|
+
"""
|
127
|
+
Create a requirement that a collection attribute contains a specific value.
|
128
|
+
|
129
|
+
Parameters
|
130
|
+
----------
|
131
|
+
value : Parameter
|
132
|
+
The value that should be contained in the collection
|
133
|
+
path : AttributePath[Root, Collection[Parameter] | ...] | Collection[Parameter] | ...
|
134
|
+
The path to the collection attribute to check
|
135
|
+
|
136
|
+
Returns
|
137
|
+
-------
|
138
|
+
Self
|
139
|
+
A new requirement instance
|
140
|
+
|
141
|
+
Raises
|
142
|
+
------
|
143
|
+
AssertionError
|
144
|
+
If path is not an AttributePath
|
145
|
+
"""
|
71
146
|
assert isinstance( # nosec: B101
|
72
147
|
path, AttributePath
|
73
148
|
), "Prepare attribute path by using Self._.path.to.property or explicitly"
|
@@ -98,6 +173,26 @@ class AttributeRequirement[Root]:
|
|
98
173
|
| list[Parameter]
|
99
174
|
| set[Parameter],
|
100
175
|
) -> Self:
|
176
|
+
"""
|
177
|
+
Create a requirement that a collection attribute contains any of the specified values.
|
178
|
+
|
179
|
+
Parameters
|
180
|
+
----------
|
181
|
+
value : Collection[Parameter]
|
182
|
+
The collection of values, any of which should be contained
|
183
|
+
path : AttributePath[Root, Collection[Parameter] | ...] | Collection[Parameter] | ...
|
184
|
+
The path to the collection attribute to check
|
185
|
+
|
186
|
+
Returns
|
187
|
+
-------
|
188
|
+
Self
|
189
|
+
A new requirement instance
|
190
|
+
|
191
|
+
Raises
|
192
|
+
------
|
193
|
+
AssertionError
|
194
|
+
If path is not an AttributePath
|
195
|
+
"""
|
101
196
|
assert isinstance( # nosec: B101
|
102
197
|
path, AttributePath
|
103
198
|
), "Prepare attribute path by using Self._.path.to.property or explicitly"
|
@@ -123,6 +218,26 @@ class AttributeRequirement[Root]:
|
|
123
218
|
/,
|
124
219
|
path: AttributePath[Root, Parameter] | Parameter,
|
125
220
|
) -> Self:
|
221
|
+
"""
|
222
|
+
Create a requirement that an attribute value is contained in a specific collection.
|
223
|
+
|
224
|
+
Parameters
|
225
|
+
----------
|
226
|
+
value : Collection[Parameter]
|
227
|
+
The collection that should contain the attribute value
|
228
|
+
path : AttributePath[Root, Parameter] | Parameter
|
229
|
+
The path to the attribute to check
|
230
|
+
|
231
|
+
Returns
|
232
|
+
-------
|
233
|
+
Self
|
234
|
+
A new requirement instance
|
235
|
+
|
236
|
+
Raises
|
237
|
+
------
|
238
|
+
AssertionError
|
239
|
+
If path is not an AttributePath
|
240
|
+
"""
|
126
241
|
assert isinstance( # nosec: B101
|
127
242
|
path, AttributePath
|
128
243
|
), "Prepare attribute path by using Self._.path.to.property or explicitly"
|
@@ -161,6 +276,20 @@ class AttributeRequirement[Root]:
|
|
161
276
|
rhs: Any,
|
162
277
|
check: Callable[[Root], None],
|
163
278
|
) -> None:
|
279
|
+
"""
|
280
|
+
Initialize a new attribute requirement.
|
281
|
+
|
282
|
+
Parameters
|
283
|
+
----------
|
284
|
+
lhs : Any
|
285
|
+
The left-hand side of the requirement (typically a path or value)
|
286
|
+
operator : Literal["equal", "not_equal", "contains", "contains_any", "contained_in", "and", "or"]
|
287
|
+
The operator that defines the type of requirement
|
288
|
+
rhs : Any
|
289
|
+
The right-hand side of the requirement (typically a value or path)
|
290
|
+
check : Callable[[Root], None]
|
291
|
+
A function that validates the requirement, raising ValueError if not met
|
292
|
+
""" # noqa: E501
|
164
293
|
self.lhs: Any
|
165
294
|
object.__setattr__(
|
166
295
|
self,
|
@@ -198,6 +327,23 @@ class AttributeRequirement[Root]:
|
|
198
327
|
self,
|
199
328
|
other: Self,
|
200
329
|
) -> Self:
|
330
|
+
"""
|
331
|
+
Combine this requirement with another using logical AND.
|
332
|
+
|
333
|
+
Creates a new requirement that is satisfied only if both this requirement
|
334
|
+
and the other requirement are satisfied.
|
335
|
+
|
336
|
+
Parameters
|
337
|
+
----------
|
338
|
+
other : Self
|
339
|
+
Another requirement to combine with this one
|
340
|
+
|
341
|
+
Returns
|
342
|
+
-------
|
343
|
+
Self
|
344
|
+
A new requirement representing the logical AND of both requirements
|
345
|
+
"""
|
346
|
+
|
201
347
|
def check_and(root: Root) -> None:
|
202
348
|
self.check(root)
|
203
349
|
other.check(root)
|
@@ -213,6 +359,23 @@ class AttributeRequirement[Root]:
|
|
213
359
|
self,
|
214
360
|
other: Self,
|
215
361
|
) -> Self:
|
362
|
+
"""
|
363
|
+
Combine this requirement with another using logical OR.
|
364
|
+
|
365
|
+
Creates a new requirement that is satisfied if either this requirement
|
366
|
+
or the other requirement is satisfied.
|
367
|
+
|
368
|
+
Parameters
|
369
|
+
----------
|
370
|
+
other : Self
|
371
|
+
Another requirement to combine with this one
|
372
|
+
|
373
|
+
Returns
|
374
|
+
-------
|
375
|
+
Self
|
376
|
+
A new requirement representing the logical OR of both requirements
|
377
|
+
"""
|
378
|
+
|
216
379
|
def check_or(root: Root) -> None:
|
217
380
|
try:
|
218
381
|
self.check(root)
|
@@ -233,6 +396,26 @@ class AttributeRequirement[Root]:
|
|
233
396
|
*,
|
234
397
|
raise_exception: bool = True,
|
235
398
|
) -> bool:
|
399
|
+
"""
|
400
|
+
Check if the requirement is satisfied by the given root object.
|
401
|
+
|
402
|
+
Parameters
|
403
|
+
----------
|
404
|
+
root : Root
|
405
|
+
The object to check the requirement against
|
406
|
+
raise_exception : bool, default=True
|
407
|
+
If True, raises an exception when the requirement is not met
|
408
|
+
|
409
|
+
Returns
|
410
|
+
-------
|
411
|
+
bool
|
412
|
+
True if the requirement is satisfied, False otherwise
|
413
|
+
|
414
|
+
Raises
|
415
|
+
------
|
416
|
+
ValueError
|
417
|
+
If the requirement is not satisfied and raise_exception is True
|
418
|
+
"""
|
236
419
|
try:
|
237
420
|
self._check(root)
|
238
421
|
return True
|
@@ -248,6 +431,19 @@ class AttributeRequirement[Root]:
|
|
248
431
|
self,
|
249
432
|
values: Iterable[Root],
|
250
433
|
) -> list[Root]:
|
434
|
+
"""
|
435
|
+
Filter an iterable of values, keeping only those that satisfy this requirement.
|
436
|
+
|
437
|
+
Parameters
|
438
|
+
----------
|
439
|
+
values : Iterable[Root]
|
440
|
+
The values to filter
|
441
|
+
|
442
|
+
Returns
|
443
|
+
-------
|
444
|
+
list[Root]
|
445
|
+
A list containing only the values that satisfy this requirement
|
446
|
+
"""
|
251
447
|
return [value for value in values if self.check(value, raise_exception=False)]
|
252
448
|
|
253
449
|
def __setattr__(
|