haiway 0.25.0__py3-none-any.whl → 0.25.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 CHANGED
@@ -275,6 +275,94 @@ class ScopeContext(Immutable):
275
275
  )
276
276
 
277
277
 
278
+ class DisposablesContext(Immutable):
279
+ """
280
+ Immutable async context manager for managing collections of disposables.
281
+
282
+ DisposablesContext captures the current contextual state upon initialization
283
+ and provides an async context manager interface for managing disposable resources.
284
+ When entered, it prepares the disposables to collect their state, merges it with
285
+ the captured state, and creates a resolved StateContext. Upon exit, it properly
286
+ disposes of the disposables and cleans up internal references.
287
+
288
+ This class should not be instantiated directly; use the ctx.disposables() factory
289
+ method to create disposables contexts.
290
+ """
291
+
292
+ _disposables: Disposables
293
+ _captured_state: Collection[State]
294
+ _resolved_state_context: StateContext | None
295
+
296
+ def __init__(
297
+ self,
298
+ disposables: Disposables,
299
+ ) -> None:
300
+ # capture current contextual state (without new additions)
301
+ object.__setattr__(
302
+ self,
303
+ "_captured_state",
304
+ StateContext.current_state(),
305
+ )
306
+ # placeholder for temporary, resolved state context
307
+ object.__setattr__(
308
+ self,
309
+ "_resolved_state_context",
310
+ None,
311
+ )
312
+ object.__setattr__(
313
+ self,
314
+ "_disposables",
315
+ disposables,
316
+ )
317
+
318
+ async def __aenter__(self) -> None:
319
+ assert self._resolved_state_context is None # nosec: B101
320
+
321
+ # Collect all state sources in priority order (lowest to highest priority)
322
+ collected_state: list[State] = []
323
+
324
+ collected_state.extend(self._captured_state)
325
+
326
+ collected_state.extend(await self._disposables.prepare())
327
+
328
+ # Create resolved state context with all collected state
329
+ resolved_state_context: StateContext = StateContext(
330
+ _state=ScopeState(tuple(collected_state))
331
+ )
332
+
333
+ resolved_state_context.__enter__()
334
+ object.__setattr__(
335
+ self,
336
+ "_resolved_state_context",
337
+ resolved_state_context,
338
+ )
339
+
340
+ async def __aexit__(
341
+ self,
342
+ exc_type: type[BaseException] | None,
343
+ exc_val: BaseException | None,
344
+ exc_tb: TracebackType | None,
345
+ ) -> None:
346
+ assert self._resolved_state_context is not None # nosec: B101
347
+
348
+ await self._disposables.dispose(
349
+ exc_type=exc_type,
350
+ exc_val=exc_val,
351
+ exc_tb=exc_tb,
352
+ )
353
+
354
+ self._resolved_state_context.__exit__(
355
+ exc_type=exc_type,
356
+ exc_val=exc_val,
357
+ exc_tb=exc_tb,
358
+ )
359
+ object.__setattr__(
360
+ self,
361
+ "_resolved_state_context",
362
+ None,
363
+ )
364
+
365
+
278
366
  @final
279
367
  class ctx:
280
368
  """
@@ -496,7 +584,7 @@ class ctx:
496
584
  @staticmethod
497
585
  def disposables(
498
586
  *disposables: Disposable | None,
499
- ) -> Disposables:
587
+ ) -> DisposablesContext:
500
588
  """
501
589
  Create a container for managing multiple disposable resources.
502
590
 
@@ -513,9 +601,9 @@ class ctx:
513
601
 
514
602
  Returns
515
603
  -------
516
- Disposables
604
+ DisposableContext
517
605
  A container that manages the lifecycle of all provided disposables
518
- and propagates their state to the context when used with ctx.scope()
606
+ and propagates their state to the context as when used with ctx.scope()
519
607
 
520
608
  Examples
521
609
  --------
@@ -524,16 +612,19 @@ class ctx:
524
612
  >>> from haiway import ctx
525
613
  >>> async def main():
526
614
  ...
527
- ... async with ctx.scope(
528
- ... "database_work",
529
- ... disposables=(database_connection(),)
615
+ ... async with ctx.disposables(
616
+ ... database_connection(),
530
617
  ... ):
531
618
  ... # ConnectionState is now available in context
532
619
  ... conn_state = ctx.state(ConnectionState)
533
620
  ... await conn_state.connection.execute("SELECT 1")
534
621
  """
535
622
 
536
- return Disposables(*(disposable for disposable in disposables if disposable is not None))
623
+ return DisposablesContext(
624
+ disposables=Disposables(
625
+ *(disposable for disposable in disposables if disposable is not None)
626
+ )
627
+ )
537
628
 
538
629
  @staticmethod
539
630
  def spawn[Result, **Arguments](
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haiway
3
- Version: 0.25.0
3
+ Version: 0.25.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,7 +1,7 @@
1
1
  haiway/__init__.py,sha256=czgQKokK8NkHBv80HrUV5T1LIvMF301u7ZnIAneq-rg,2123
2
2
  haiway/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  haiway/context/__init__.py,sha256=5_4gad1PbSs1Swf9IyeOk6gDEDie8uTqXwm75FMyT2Q,1298
4
- haiway/context/access.py,sha256=ruzXdVTRhS9pdXy6lfVEvRxtubf7TOjE3nXGB9AHLYc,30261
4
+ haiway/context/access.py,sha256=aYEn28Zb64IbsE2MmNmLUsg4CxZfBuJX8GG65UakkAk,33029
5
5
  haiway/context/disposables.py,sha256=7Jo-5qzS3UQvZUf4yOqUgfnueMg8I65jwHDp-4g6w54,7998
6
6
  haiway/context/identifier.py,sha256=ps7YM1ZnUrj66SPVyxqMhTRMaYOMNSb82J3FfMRVHm4,4690
7
7
  haiway/context/observability.py,sha256=rZoZT7g4ZM5_OKIFV0uA0rJodHxondw8X2bMSf_W6_s,20244
@@ -41,7 +41,7 @@ haiway/utils/mimic.py,sha256=xaZiUKp096QFfdSw7cNIKEWt2UIS7vf880KF54gny38,1831
41
41
  haiway/utils/noop.py,sha256=U8ocfoCgt-pY0owJDPtrRrj53cabeIXH9qCKWMQnoRk,1336
42
42
  haiway/utils/queue.py,sha256=6v2u3pA6A44IuCCTOjmCt3yLyOcm7PCRnrIGo25j-1o,6402
43
43
  haiway/utils/stream.py,sha256=lXaeveTY0-AYG5xVzcQYaiC6SUD5fUtHoMXiQcrQAAM,5723
44
- haiway-0.25.0.dist-info/METADATA,sha256=Ua7LksWkJQNmrEanbmf-69dcxU_Z3dIH_QQTolq64vM,4919
45
- haiway-0.25.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
46
- haiway-0.25.0.dist-info/licenses/LICENSE,sha256=3phcpHVNBP8jsi77gOO0E7rgKeDeu99Pi7DSnK9YHoQ,1069
47
- haiway-0.25.0.dist-info/RECORD,,
44
+ haiway-0.25.1.dist-info/METADATA,sha256=ggU_T40b25Eqe886YvYy6VydW4iZRAzJ1U57u7QpUbU,4919
45
+ haiway-0.25.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
46
+ haiway-0.25.1.dist-info/licenses/LICENSE,sha256=3phcpHVNBP8jsi77gOO0E7rgKeDeu99Pi7DSnK9YHoQ,1069
47
+ haiway-0.25.1.dist-info/RECORD,,