anydi 0.27.0a5__py3-none-any.whl → 0.27.0a6__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.
anydi/_container.py CHANGED
@@ -11,11 +11,9 @@ from contextvars import ContextVar
11
11
  from functools import wraps
12
12
  from typing import (
13
13
  Any,
14
- AsyncContextManager,
15
14
  AsyncIterator,
16
15
  Awaitable,
17
16
  Callable,
18
- ContextManager,
19
17
  Iterable,
20
18
  Iterator,
21
19
  Mapping,
@@ -43,7 +41,7 @@ from ._context import (
43
41
  from ._logger import logger
44
42
  from ._module import Module, ModuleRegistry
45
43
  from ._scanner import Scanner
46
- from ._types import AnyInterface, Interface, Provider, Scope, is_marker
44
+ from ._types import AnyInterface, Event, Interface, Provider, Scope, is_marker
47
45
  from ._utils import (
48
46
  get_full_qualname,
49
47
  get_typed_parameters,
@@ -86,7 +84,7 @@ class Container:
86
84
  strict: Whether to enable strict mode. Defaults to False.
87
85
  """
88
86
  self._providers: dict[type[Any], Provider] = {}
89
- self._providers_cache: dict[Scope, list[type[Any]]] = defaultdict(list)
87
+ self._resource_cache: dict[Scope, list[type[Any]]] = defaultdict(list)
90
88
  self._singleton_context = SingletonContext(self)
91
89
  self._transient_context = TransientContext(self)
92
90
  self._request_context_var: ContextVar[RequestContext | None] = ContextVar(
@@ -172,7 +170,7 @@ class Container:
172
170
 
173
171
  # Create Event type
174
172
  if provider.is_resource and (interface is NoneType or interface is None):
175
- interface = type(f"Event_{uuid.uuid4().hex}", (), {})
173
+ interface = type(f"Event_{uuid.uuid4().hex}", (Event,), {})
176
174
 
177
175
  if interface in self._providers:
178
176
  if override:
@@ -286,7 +284,7 @@ class Container:
286
284
  """
287
285
  self._providers[interface] = provider
288
286
  if provider.is_resource:
289
- self._providers_cache[provider.scope].append(interface)
287
+ self._resource_cache[provider.scope].append(interface)
290
288
 
291
289
  def _delete_provider(self, interface: AnyInterface) -> None:
292
290
  """Delete a provider by interface.
@@ -296,7 +294,7 @@ class Container:
296
294
  """
297
295
  provider = self._providers.pop(interface, None)
298
296
  if provider is not None and provider.is_resource:
299
- self._providers_cache[provider.scope].remove(interface)
297
+ self._resource_cache[provider.scope].remove(interface)
300
298
 
301
299
  def _validate_provider_scope(self, provider: Provider) -> None:
302
300
  """Validate the scope of a provider.
@@ -443,20 +441,13 @@ class Container:
443
441
  """Close the singleton context."""
444
442
  self._singleton_context.close()
445
443
 
446
- def request_context(self) -> ContextManager[None]:
444
+ @contextlib.contextmanager
445
+ def request_context(self) -> Iterator[None]:
447
446
  """Obtain a context manager for the request-scoped context.
448
447
 
449
448
  Returns:
450
449
  A context manager for the request-scoped context.
451
450
  """
452
- return contextlib.contextmanager(self._request_context)()
453
-
454
- def _request_context(self) -> Iterator[None]:
455
- """Internal method that manages the request-scoped context.
456
-
457
- Yields:
458
- Yield control to the code block within the request context.
459
- """
460
451
  context = RequestContext(self)
461
452
  token = self._request_context_var.set(context)
462
453
  with context:
@@ -479,28 +470,19 @@ class Container:
479
470
 
480
471
  async def astart(self) -> None:
481
472
  """Start the singleton context asynchronously."""
482
- for interface, provider in self._providers.items():
483
- if provider.scope == "singleton":
484
- await self.aresolve(interface) # noqa
473
+ await self._singleton_context.astart()
485
474
 
486
475
  async def aclose(self) -> None:
487
476
  """Close the singleton context asynchronously."""
488
477
  await self._singleton_context.aclose()
489
478
 
490
- def arequest_context(self) -> AsyncContextManager[None]:
479
+ @contextlib.asynccontextmanager
480
+ async def arequest_context(self) -> AsyncIterator[None]:
491
481
  """Obtain an async context manager for the request-scoped context.
492
482
 
493
483
  Returns:
494
484
  An async context manager for the request-scoped context.
495
485
  """
496
- return contextlib.asynccontextmanager(self._arequest_context)()
497
-
498
- async def _arequest_context(self) -> AsyncIterator[None]:
499
- """Internal method that manages the async request-scoped context.
500
-
501
- Yields:
502
- Yield control to the code block within the request context.
503
- """
504
486
  context = RequestContext(self)
505
487
  token = self._request_context_var.set(context)
506
488
  async with context:
anydi/_context.py CHANGED
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Any, ClassVar, TypeVar, cast
7
7
 
8
8
  from typing_extensions import Self, final
9
9
 
10
- from ._types import AnyInterface, Interface, Provider, Scope
10
+ from ._types import AnyInterface, Interface, Provider, Scope, is_event_type
11
11
  from ._utils import run_async
12
12
 
13
13
  if TYPE_CHECKING:
@@ -254,9 +254,10 @@ class ResourceScopedContext(ScopedContext):
254
254
  self.close()
255
255
  return
256
256
 
257
+ @abc.abstractmethod
257
258
  def start(self) -> None:
258
259
  """Start the scoped context."""
259
- for interface in self.container._providers_cache.get(self.scope, []): # noqa
260
+ for interface in self.container._resource_cache.get(self.scope, []): # noqa
260
261
  self.container.resolve(interface)
261
262
 
262
263
  def close(self) -> None:
@@ -288,10 +289,9 @@ class ResourceScopedContext(ScopedContext):
288
289
  await self.aclose()
289
290
  return
290
291
 
292
+ @abc.abstractmethod
291
293
  async def astart(self) -> None:
292
294
  """Start the scoped context asynchronously."""
293
- for interface in self.container._providers_cache.get(self.scope, []): # noqa
294
- await self.container.aresolve(interface)
295
295
 
296
296
  async def aclose(self) -> None:
297
297
  """Close the scoped context asynchronously."""
@@ -305,6 +305,16 @@ class SingletonContext(ResourceScopedContext):
305
305
 
306
306
  scope = "singleton"
307
307
 
308
+ def start(self) -> None:
309
+ """Start the scoped context."""
310
+ for interface in self.container._resource_cache.get(self.scope, []): # noqa
311
+ self.container.resolve(interface)
312
+
313
+ async def astart(self) -> None:
314
+ """Start the scoped context asynchronously."""
315
+ for interface in self.container._resource_cache.get(self.scope, []): # noqa
316
+ await self.container.aresolve(interface)
317
+
308
318
 
309
319
  @final
310
320
  class RequestContext(ResourceScopedContext):
@@ -312,6 +322,20 @@ class RequestContext(ResourceScopedContext):
312
322
 
313
323
  scope = "request"
314
324
 
325
+ def start(self) -> None:
326
+ """Start the scoped context."""
327
+ for interface in self.container._resource_cache.get(self.scope, []): # noqa
328
+ if not is_event_type(interface):
329
+ continue
330
+ self.container.resolve(interface)
331
+
332
+ async def astart(self) -> None:
333
+ """Start the scoped context asynchronously."""
334
+ for interface in self.container._resource_cache.get(self.scope, []): # noqa
335
+ if not is_event_type(interface):
336
+ continue
337
+ await self.container.aresolve(interface)
338
+
315
339
 
316
340
  @final
317
341
  class TransientContext(ScopedContext):
anydi/_types.py CHANGED
@@ -30,6 +30,17 @@ def is_marker(obj: Any) -> bool:
30
30
  return isinstance(obj, Marker)
31
31
 
32
32
 
33
+ class Event:
34
+ """Represents an event object."""
35
+
36
+ __slots__ = ()
37
+
38
+
39
+ def is_event_type(cls: Any) -> bool:
40
+ """Checks if an object is an event type."""
41
+ return issubclass(cls, Event)
42
+
43
+
33
44
  @dataclass(frozen=True)
34
45
  class Provider:
35
46
  """Represents a provider object.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: anydi
3
- Version: 0.27.0a5
3
+ Version: 0.27.0a6
4
4
  Summary: Dependency Injection library
5
5
  Home-page: https://github.com/antonrh/anydi
6
6
  License: MIT
@@ -1,10 +1,10 @@
1
1
  anydi/__init__.py,sha256=aeaBp5vq09sG-e9sqqs9qpUtUIDNfOdFPrlAfE5Ku9E,584
2
- anydi/_container.py,sha256=iVmVlnhK3qfcSCvDZsbD23x2REBtBD26abqKJuLGyHs,29631
3
- anydi/_context.py,sha256=e0VX0fiflzW_2O9w3HvUH3YRCwXHsruQjf3Lu-zXgDw,10815
2
+ anydi/_container.py,sha256=OjzwZPiQuf9ouyhmIqlNht99pHa77hjZ0sM_n_GovW0,28947
3
+ anydi/_context.py,sha256=AVml53KyrQL4yyoJZkU2pbNzQwtg-1Jyt7m6R_0l6_8,11740
4
4
  anydi/_logger.py,sha256=UpubJUnW83kffFxkhUlObm2DmZX1Pjqoz9YFKS-JOPg,52
5
5
  anydi/_module.py,sha256=E1TfLud_Af-MPB83PxIzHVA1jlDW2FGaRP_il1a6y3Y,3675
6
6
  anydi/_scanner.py,sha256=cyEk-K2Q8ssZStq8GrxMeEcCuAZMw-RXrjlgWEevKCs,6667
7
- anydi/_types.py,sha256=vQTrFjsYhlMxfo1nOFem05x2QUJMQkVh4ZaC7W0XZJY,3434
7
+ anydi/_types.py,sha256=YGfHVyysu2qNSXaZnvl_1BwPzKub84o3e3F4rK0tGQw,3628
8
8
  anydi/_utils.py,sha256=zP4UvO1aVQJTB8pFNUWAcncvSiuhcg4xNdRU7CoLrqw,3871
9
9
  anydi/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  anydi/ext/_utils.py,sha256=2kxLPTMM9Ro3s6-knbqYzONlqRB3hMcwZFFRQGHcFUg,2691
@@ -23,8 +23,8 @@ anydi/ext/pytest_plugin.py,sha256=pFLcfxGtJfGSqtk7sPrrHFSKOaZoKZTWt5X8CT0ydmA,42
23
23
  anydi/ext/starlette/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  anydi/ext/starlette/middleware.py,sha256=Ni0BQaPjs_Ha6zcLZYYJ3-XkslTCnL9aCSa06rnRDMI,1139
25
25
  anydi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- anydi-0.27.0a5.dist-info/LICENSE,sha256=V6rU8a8fv6o2jQ-7ODHs0XfDFimot8Q6Km6CylRIDTo,1069
27
- anydi-0.27.0a5.dist-info/METADATA,sha256=GoZY2ldWbiQZtFTCMEvGfDhfKb_ZnFjV7AYD6ZwlUzo,5163
28
- anydi-0.27.0a5.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
29
- anydi-0.27.0a5.dist-info/entry_points.txt,sha256=GmQblwzxFg42zva1HyBYJJ7TvrTIcSAGBHmyi3bvsi4,42
30
- anydi-0.27.0a5.dist-info/RECORD,,
26
+ anydi-0.27.0a6.dist-info/LICENSE,sha256=V6rU8a8fv6o2jQ-7ODHs0XfDFimot8Q6Km6CylRIDTo,1069
27
+ anydi-0.27.0a6.dist-info/METADATA,sha256=G95uZ9BoMP2BLlYVARh_BWIoArTZEeuEz-eJUBi9d5g,5163
28
+ anydi-0.27.0a6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
29
+ anydi-0.27.0a6.dist-info/entry_points.txt,sha256=GmQblwzxFg42zva1HyBYJJ7TvrTIcSAGBHmyi3bvsi4,42
30
+ anydi-0.27.0a6.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.8.1
2
+ Generator: poetry-core 1.9.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any