python-injection 0.7.4__py3-none-any.whl → 0.8.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.

Potentially problematic release.


This version of python-injection might be problematic. Click here for more details.

injection/_pkg.pyi CHANGED
@@ -39,19 +39,11 @@ class Module:
39
39
 
40
40
  def __init__(self, name: str = ...): ...
41
41
  def __contains__(self, cls: type | UnionType, /) -> bool: ...
42
- def inject(
43
- self,
44
- wrapped: Callable[..., Any] = ...,
45
- /,
46
- *,
47
- force: bool = ...,
48
- ):
42
+ def inject(self, wrapped: Callable[..., Any] = ..., /):
49
43
  """
50
44
  Decorator applicable to a class or function. Inject function dependencies using
51
45
  parameter type annotations. If applied to a class, the dependencies resolved
52
46
  will be those of the `__init__` method.
53
-
54
- With `force=True`, parameters passed to replace dependencies will be ignored.
55
47
  """
56
48
 
57
49
  def injectable(
injection/common/event.py CHANGED
@@ -4,6 +4,8 @@ from dataclasses import dataclass, field
4
4
  from typing import ContextManager
5
5
  from weakref import WeakSet
6
6
 
7
+ from injection.common.tools.threading import frozen_collection
8
+
7
9
  __all__ = ("Event", "EventChannel", "EventListener")
8
10
 
9
11
 
@@ -26,7 +28,7 @@ class EventChannel:
26
28
  @contextmanager
27
29
  def dispatch(self, event: Event) -> ContextManager | ContextDecorator:
28
30
  with ExitStack() as stack:
29
- for listener in tuple(self.__listeners):
31
+ for listener in frozen_collection(self.__listeners):
30
32
  context_manager = listener.on_event(event)
31
33
 
32
34
  if context_manager is None:
injection/common/lazy.py CHANGED
@@ -1,12 +1,10 @@
1
1
  from collections.abc import Callable, Iterator, Mapping
2
- from threading import RLock
3
2
  from types import MappingProxyType
4
- from typing import Any, Generic, TypeVar
3
+ from typing import Generic, TypeVar
5
4
 
6
- __all__ = ("Lazy", "LazyMapping")
5
+ from injection.common.tools.threading import thread_lock
7
6
 
8
- _sentinel = object()
9
- _thread_lock = RLock()
7
+ __all__ = ("Lazy", "LazyMapping")
10
8
 
11
9
  _T = TypeVar("_T")
12
10
  _K = TypeVar("_K")
@@ -14,39 +12,37 @@ _V = TypeVar("_V")
14
12
 
15
13
 
16
14
  class Lazy(Generic[_T]):
17
- __slots__ = ("__factory", "__value")
15
+ __slots__ = ("__cache", "__is_set")
18
16
 
19
17
  def __init__(self, factory: Callable[[], _T]):
20
- self.__factory = factory
21
- self.__value = _sentinel
18
+ self.__setup_cache(factory)
22
19
 
23
20
  def __invert__(self) -> _T:
24
- if not self.is_set:
25
- with _thread_lock:
26
- self.__value = self.__factory()
27
- self.__factory = _sentinel
21
+ return next(self.__cache)
28
22
 
29
- return self.__value
23
+ @property
24
+ def is_set(self) -> bool:
25
+ return self.__is_set
30
26
 
31
- def __setattr__(self, name: str, value: Any, /):
32
- if self.is_set:
33
- raise TypeError(f"`{self}` is frozen.")
27
+ def __setup_cache(self, factory: Callable[[], _T]):
28
+ def new_cache() -> Iterator[_T]:
29
+ with thread_lock:
30
+ self.__is_set = True
34
31
 
35
- return super().__setattr__(name, value)
32
+ nonlocal factory
33
+ cached = factory()
34
+ del factory
36
35
 
37
- @property
38
- def is_set(self) -> bool:
39
- try:
40
- return self.__factory is _sentinel
41
- except AttributeError:
42
- return False
36
+ while True:
37
+ yield cached
38
+
39
+ self.__cache = new_cache()
40
+ self.__is_set = False
43
41
 
44
42
 
45
43
  class LazyMapping(Mapping[_K, _V]):
46
44
  __slots__ = ("__lazy",)
47
45
 
48
- __lazy: Lazy[MappingProxyType[_K, _V]]
49
-
50
46
  def __init__(self, iterator: Iterator[tuple[_K, _V]]):
51
47
  self.__lazy = Lazy(lambda: MappingProxyType(dict(iterator)))
52
48
 
@@ -58,3 +54,7 @@ class LazyMapping(Mapping[_K, _V]):
58
54
 
59
55
  def __len__(self) -> int:
60
56
  return len(~self.__lazy)
57
+
58
+ @property
59
+ def is_set(self) -> bool:
60
+ return self.__lazy.is_set
@@ -0,0 +1,68 @@
1
+ from abc import abstractmethod
2
+ from collections import deque
3
+ from collections.abc import Iterator
4
+ from dataclasses import dataclass, field
5
+ from typing import NoReturn, Protocol, TypeVar
6
+
7
+ from injection.common.tools.threading import thread_lock
8
+
9
+ __all__ = ("LimitedQueue",)
10
+
11
+ _T = TypeVar("_T")
12
+
13
+
14
+ class Queue(Iterator[_T], Protocol):
15
+ __slots__ = ()
16
+
17
+ @abstractmethod
18
+ def add(self, item: _T):
19
+ raise NotImplementedError
20
+
21
+
22
+ @dataclass(repr=False, frozen=True, slots=True)
23
+ class SimpleQueue(Queue[_T]):
24
+ __items: deque[_T] = field(default_factory=deque, init=False)
25
+
26
+ def __next__(self) -> _T:
27
+ try:
28
+ return self.__items.popleft()
29
+ except IndexError as exc:
30
+ raise StopIteration from exc
31
+
32
+ def add(self, item: _T):
33
+ self.__items.append(item)
34
+ return self
35
+
36
+
37
+ class NoQueue(Queue[_T]):
38
+ __slots__ = ()
39
+
40
+ def __bool__(self) -> bool:
41
+ return False
42
+
43
+ def __next__(self) -> NoReturn:
44
+ raise StopIteration
45
+
46
+ def add(self, item: _T) -> NoReturn:
47
+ raise TypeError("Queue doesn't exist.")
48
+
49
+
50
+ @dataclass(repr=False, slots=True)
51
+ class LimitedQueue(Queue[_T]):
52
+ __queue: Queue[_T] = field(default_factory=SimpleQueue)
53
+
54
+ def __next__(self) -> _T:
55
+ if not self.__queue:
56
+ raise StopIteration
57
+
58
+ try:
59
+ return next(self.__queue)
60
+ except StopIteration as exc:
61
+ with thread_lock:
62
+ self.__queue = NoQueue()
63
+
64
+ raise exc
65
+
66
+ def add(self, item: _T):
67
+ self.__queue.add(item)
68
+ return self
@@ -1 +0,0 @@
1
- from ._type import *
@@ -0,0 +1,28 @@
1
+ from collections.abc import Callable, Collection, Iterator
2
+ from functools import wraps
3
+ from threading import RLock
4
+ from typing import Any, TypeVar
5
+
6
+ __all__ = ("frozen_collection", "synchronized", "thread_lock")
7
+
8
+ _T = TypeVar("_T")
9
+ thread_lock = RLock()
10
+
11
+
12
+ def synchronized(function: Callable[..., Any] = None, /):
13
+ def decorator(fn):
14
+ @wraps(fn)
15
+ def wrapper(*args, **kwargs):
16
+ with thread_lock:
17
+ return fn(*args, **kwargs)
18
+
19
+ return wrapper
20
+
21
+ return decorator(function) if function else decorator
22
+
23
+
24
+ def frozen_collection(collection: Collection[_T]) -> Iterator[_T]:
25
+ with thread_lock:
26
+ t = tuple(collection)
27
+
28
+ yield from t
injection/core/module.py CHANGED
@@ -16,12 +16,17 @@ from collections.abc import (
16
16
  from contextlib import ContextDecorator, contextmanager, suppress
17
17
  from dataclasses import dataclass, field
18
18
  from enum import Enum, auto
19
- from functools import partialmethod, singledispatchmethod, wraps
19
+ from functools import (
20
+ partialmethod,
21
+ singledispatchmethod,
22
+ update_wrapper,
23
+ wraps,
24
+ )
20
25
  from inspect import Signature, isclass
21
- from threading import RLock
22
- from types import MappingProxyType, UnionType
26
+ from types import UnionType
23
27
  from typing import (
24
28
  Any,
29
+ ClassVar,
25
30
  ContextManager,
26
31
  NamedTuple,
27
32
  NoReturn,
@@ -33,7 +38,13 @@ from typing import (
33
38
 
34
39
  from injection.common.event import Event, EventChannel, EventListener
35
40
  from injection.common.lazy import Lazy, LazyMapping
36
- from injection.common.tools import find_types, format_type, get_origins
41
+ from injection.common.queue import LimitedQueue
42
+ from injection.common.tools.threading import (
43
+ frozen_collection,
44
+ synchronized,
45
+ thread_lock,
46
+ )
47
+ from injection.common.tools.type import find_types, format_type, get_origins
37
48
  from injection.exceptions import (
38
49
  InjectionError,
39
50
  ModuleError,
@@ -45,7 +56,6 @@ from injection.exceptions import (
45
56
  __all__ = ("Injectable", "Module", "ModulePriority")
46
57
 
47
58
  _logger = logging.getLogger(__name__)
48
- _thread_lock = RLock()
49
59
 
50
60
  _T = TypeVar("_T")
51
61
  Types = Iterable[type] | UnionType
@@ -166,7 +176,7 @@ class NewInjectable(BaseInjectable[_T]):
166
176
  class SingletonInjectable(BaseInjectable[_T]):
167
177
  __slots__ = ("__dict__",)
168
178
 
169
- __INSTANCE_KEY = "$instance"
179
+ __INSTANCE_KEY: ClassVar[str] = "$instance"
170
180
 
171
181
  @property
172
182
  def cache(self) -> MutableMapping[str, Any]:
@@ -183,7 +193,7 @@ class SingletonInjectable(BaseInjectable[_T]):
183
193
  with suppress(KeyError):
184
194
  return self.cache[self.__INSTANCE_KEY]
185
195
 
186
- with _thread_lock:
196
+ with thread_lock:
187
197
  instance = self.factory()
188
198
  self.cache[self.__INSTANCE_KEY] = instance
189
199
 
@@ -263,7 +273,7 @@ class Container(Broker):
263
273
  def update(self, classes: Iterable[type], injectable: Injectable, override: bool):
264
274
  classes = frozenset(get_origins(*classes))
265
275
 
266
- with _thread_lock:
276
+ with thread_lock:
267
277
  if not injectable:
268
278
  classes -= self.__classes
269
279
  override = True
@@ -279,6 +289,7 @@ class Container(Broker):
279
289
 
280
290
  return self
281
291
 
292
+ @synchronized
282
293
  def unlock(self):
283
294
  for injectable in self.__injectables:
284
295
  injectable.unlock()
@@ -349,7 +360,7 @@ class Module(EventListener, Broker):
349
360
 
350
361
  @property
351
362
  def __brokers(self) -> Iterator[Broker]:
352
- yield from tuple(self.__modules)
363
+ yield from frozen_collection(self.__modules)
353
364
  yield self.__container
354
365
 
355
366
  def injectable(
@@ -401,22 +412,21 @@ class Module(EventListener, Broker):
401
412
  wrapped: Callable[..., Any] = None,
402
413
  /,
403
414
  *,
404
- force: bool = False,
405
415
  return_factory: bool = False,
406
416
  ):
407
417
  def decorator(wp):
408
418
  if not return_factory and isclass(wp):
409
- wp.__init__ = self.inject(wp.__init__, force=force)
419
+ wp.__init__ = self.inject(wp.__init__)
410
420
  return wp
411
421
 
412
- lazy_binder = Lazy[Binder](lambda: self.__new_binder(wp))
422
+ function = InjectedFunction(wp)
413
423
 
414
- @wraps(wp)
415
- def wrapper(*args, **kwargs):
416
- arguments = (~lazy_binder).bind(args, kwargs, force)
417
- return wp(*arguments.args, **arguments.kwargs)
424
+ @function.setup
425
+ def listen():
426
+ function.update(self)
427
+ self.add_listener(function)
418
428
 
419
- return wrapper
429
+ return function
420
430
 
421
431
  return decorator(wrapped) if wrapped else decorator
422
432
 
@@ -492,6 +502,7 @@ class Module(EventListener, Broker):
492
502
 
493
503
  return self
494
504
 
505
+ @synchronized
495
506
  def unlock(self):
496
507
  for broker in self.__brokers:
497
508
  broker.unlock()
@@ -530,44 +541,45 @@ class Module(EventListener, Broker):
530
541
  f"`{module}` can't be found in the modules used by `{self}`."
531
542
  ) from exc
532
543
 
533
- def __new_binder(self, target: Callable[..., Any]) -> Binder:
534
- signature = inspect.signature(target, eval_str=True)
535
- binder = Binder(signature).update(self)
536
- self.add_listener(binder)
537
- return binder
538
-
539
544
 
540
545
  """
541
- Binder
546
+ InjectedFunction
542
547
  """
543
548
 
544
549
 
545
550
  @dataclass(repr=False, frozen=True, slots=True)
546
551
  class Dependencies:
547
- __mapping: MappingProxyType[str, Injectable]
552
+ mapping: Mapping[str, Injectable]
548
553
 
549
554
  def __bool__(self) -> bool:
550
- return bool(self.__mapping)
555
+ return bool(self.mapping)
551
556
 
552
557
  def __iter__(self) -> Iterator[tuple[str, Any]]:
553
- for name, injectable in self.__mapping.items():
558
+ for name, injectable in self.mapping.items():
554
559
  yield name, injectable.get_instance()
555
560
 
561
+ @property
562
+ def are_resolved(self) -> bool:
563
+ if isinstance(self.mapping, LazyMapping) and not self.mapping.is_set:
564
+ return False
565
+
566
+ return bool(self)
567
+
556
568
  @property
557
569
  def arguments(self) -> OrderedDict[str, Any]:
558
570
  return OrderedDict(self)
559
571
 
560
572
  @classmethod
561
573
  def from_mapping(cls, mapping: Mapping[str, Injectable]):
562
- return cls(MappingProxyType(mapping))
574
+ return cls(mapping=mapping)
563
575
 
564
576
  @classmethod
565
577
  def empty(cls):
566
578
  return cls.from_mapping({})
567
579
 
568
580
  @classmethod
569
- def resolve(cls, signature: Signature, module: Module):
570
- dependencies = LazyMapping(cls.__resolver(signature, module))
581
+ def resolve(cls, signature: Signature, module: Module, owner: type = None):
582
+ dependencies = LazyMapping(cls.__resolver(signature, module, owner))
571
583
  return cls.from_mapping(dependencies)
572
584
 
573
585
  @classmethod
@@ -575,33 +587,102 @@ class Dependencies:
575
587
  cls,
576
588
  signature: Signature,
577
589
  module: Module,
590
+ owner: type = None,
578
591
  ) -> Iterator[tuple[str, Injectable]]:
579
- for name, parameter in signature.parameters.items():
592
+ for name, annotation in cls.__get_annotations(signature, owner):
580
593
  try:
581
- injectable = module[parameter.annotation]
594
+ injectable = module[annotation]
582
595
  except KeyError:
583
596
  continue
584
597
 
585
598
  yield name, injectable
586
599
 
600
+ @staticmethod
601
+ def __get_annotations(
602
+ signature: Signature,
603
+ owner: type = None,
604
+ ) -> Iterator[tuple[str, type | Any]]:
605
+ parameters = iter(signature.parameters.items())
606
+
607
+ if owner:
608
+ name, _ = next(parameters)
609
+ yield name, owner
610
+
611
+ for name, parameter in parameters:
612
+ yield name, parameter.annotation
613
+
587
614
 
588
615
  class Arguments(NamedTuple):
589
616
  args: Iterable[Any]
590
617
  kwargs: Mapping[str, Any]
591
618
 
592
619
 
593
- class Binder(EventListener):
594
- __slots__ = ("__signature", "__dependencies")
620
+ class InjectedFunction(EventListener):
621
+ __slots__ = (
622
+ "__dict__",
623
+ "__signature__",
624
+ "__dependencies",
625
+ "__owner",
626
+ "__setup_queue",
627
+ "__wrapper",
628
+ )
629
+
630
+ def __init__(self, wrapped: Callable[..., Any], /):
631
+ update_wrapper(self, wrapped)
632
+
633
+ @wraps(wrapped)
634
+ def wrapper(*args, **kwargs):
635
+ self.__consume_setup_queue()
636
+ args, kwargs = self.bind(args, kwargs)
637
+ return wrapped(*args, **kwargs)
595
638
 
596
- def __init__(self, signature: Signature):
597
- self.__signature = signature
639
+ self.__wrapper = wrapper
598
640
  self.__dependencies = Dependencies.empty()
641
+ self.__owner = None
642
+ self.__setup_queue = LimitedQueue[Callable[[], Any]]()
643
+ self.setup(
644
+ lambda: self.__set_signature(
645
+ inspect.signature(
646
+ wrapped,
647
+ eval_str=True,
648
+ )
649
+ )
650
+ )
651
+
652
+ def __repr__(self) -> str:
653
+ return repr(self.__wrapper)
654
+
655
+ def __str__(self) -> str:
656
+ return str(self.__wrapper)
657
+
658
+ def __call__(self, /, *args, **kwargs) -> Any:
659
+ return self.__wrapper(*args, **kwargs)
660
+
661
+ def __get__(self, instance: object = None, owner: type = None):
662
+ if instance is None:
663
+ return self
664
+
665
+ return self.__wrapper.__get__(instance, owner)
666
+
667
+ def __set_name__(self, owner: type, name: str):
668
+ if self.__dependencies.are_resolved:
669
+ raise TypeError(
670
+ "Function owner must be assigned before dependencies are resolved."
671
+ )
672
+
673
+ if self.__owner:
674
+ raise TypeError("Function owner is already defined.")
675
+
676
+ self.__owner = owner
677
+
678
+ @property
679
+ def signature(self) -> Signature:
680
+ return self.__signature__
599
681
 
600
682
  def bind(
601
683
  self,
602
684
  args: Iterable[Any] = (),
603
685
  kwargs: Mapping[str, Any] = None,
604
- force: bool = False,
605
686
  ) -> Arguments:
606
687
  if kwargs is None:
607
688
  kwargs = {}
@@ -609,22 +690,29 @@ class Binder(EventListener):
609
690
  if not self.__dependencies:
610
691
  return Arguments(args, kwargs)
611
692
 
612
- bound = self.__signature.bind_partial(*args, **kwargs)
613
- dependencies = self.__dependencies.arguments
614
-
615
- if force:
616
- bound.arguments |= dependencies
617
- else:
618
- bound.arguments = dependencies | bound.arguments
619
-
693
+ bound = self.signature.bind_partial(*args, **kwargs)
694
+ bound.arguments = (
695
+ bound.arguments | self.__dependencies.arguments | bound.arguments
696
+ )
620
697
  return Arguments(bound.args, bound.kwargs)
621
698
 
622
699
  def update(self, module: Module):
623
- with _thread_lock:
624
- self.__dependencies = Dependencies.resolve(self.__signature, module)
700
+ with thread_lock:
701
+ self.__dependencies = Dependencies.resolve(
702
+ self.signature,
703
+ module,
704
+ self.__owner,
705
+ )
625
706
 
626
707
  return self
627
708
 
709
+ def setup(self, wrapped: Callable[[], Any] = None, /):
710
+ def decorator(wp):
711
+ self.__setup_queue.add(wp)
712
+ return wp
713
+
714
+ return decorator(wrapped) if wrapped else decorator
715
+
628
716
  @singledispatchmethod
629
717
  def on_event(self, event: Event, /):
630
718
  pass
@@ -634,3 +722,15 @@ class Binder(EventListener):
634
722
  def _(self, event: ModuleEvent, /) -> ContextManager:
635
723
  yield
636
724
  self.update(event.on_module)
725
+
726
+ def __consume_setup_queue(self):
727
+ for function in self.__setup_queue:
728
+ function()
729
+
730
+ return self
731
+
732
+ def __set_signature(self, signature: Signature):
733
+ with thread_lock:
734
+ self.__signature__ = signature
735
+
736
+ return self
injection/exceptions.py CHANGED
@@ -1,4 +1,4 @@
1
- from injection.common.tools import format_type
1
+ from injection.common.tools.type import format_type
2
2
 
3
3
  __all__ = (
4
4
  "InjectionError",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-injection
3
- Version: 0.7.4
3
+ Version: 0.8.0
4
4
  Summary: Fast and easy dependency injection framework.
5
5
  Home-page: https://github.com/100nm/python-injection
6
6
  License: MIT
@@ -0,0 +1,19 @@
1
+ injection/__init__.py,sha256=9_AVJILxKIBiL_6KJSh2RRydgSHXH38uahAGD0S1-dI,20
2
+ injection/_pkg.py,sha256=nMIRLAQG6096bcR2Mz1egxe5FItBUsw8zR9yzjt1HDM,647
3
+ injection/_pkg.pyi,sha256=5IE5vbi_sSeKjcFtUT9UuCWeIIwEi1hy3qmTdZeZSMI,5171
4
+ injection/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ injection/common/event.py,sha256=Lq3XTi2iTK9Y51uHtmsxoqeKJsgretqQQAb00HR454c,1392
6
+ injection/common/lazy.py,sha256=mEW4BwLoxkMdQknwWu0tjltgZyqnysocHTeqYMNQCsk,1436
7
+ injection/common/queue.py,sha256=2xzfW2Y43Z67ehQpZbkuTvrotT-JUDNoGoO-5XMhAdg,1566
8
+ injection/common/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ injection/common/tools/threading.py,sha256=doz_TQJWmo3qIaSAhFEyCmdVG7RZoXDmdyfbkYS_vgU,688
10
+ injection/common/tools/type.py,sha256=-zL0dtoVZme71Mscvav7iEWxY2-JltzNTekbWOCPSFo,1276
11
+ injection/core/__init__.py,sha256=zuf0ubI2dHnbjn1059eduhS-ACIkkROa6-dhp10krh0,22
12
+ injection/core/module.py,sha256=BTX2-yeHzeCG7V9p9tUvC5Mz6AAxXYzaLSkMs03pQ2U,18989
13
+ injection/exceptions.py,sha256=nE56jW00ZB1T-Z-dvfPczPShs3CwIc7tIvdYlOXlaXA,653
14
+ injection/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ injection/integrations/blacksheep.py,sha256=vcLil1IccS7JtXpuVu7s2LqN5Zravfe_7xpAt5cTIU0,723
16
+ injection/utils.py,sha256=_79aiciimZpuoUTz5lojKySUMMzpkU-e7SotiHIFTI8,676
17
+ python_injection-0.8.0.dist-info/METADATA,sha256=5Ea9UNMfKOquRZgVNsDw_RJG7sKRvzMlRIFtSqz9v7A,3433
18
+ python_injection-0.8.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
19
+ python_injection-0.8.0.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- injection/__init__.py,sha256=9_AVJILxKIBiL_6KJSh2RRydgSHXH38uahAGD0S1-dI,20
2
- injection/_pkg.py,sha256=nMIRLAQG6096bcR2Mz1egxe5FItBUsw8zR9yzjt1HDM,647
3
- injection/_pkg.pyi,sha256=zxbidnUvr-8x7F8hLJUgEBzyefXtNW6Ajtuin6Z0cf8,5327
4
- injection/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- injection/common/event.py,sha256=uFoGRnxxkohH53JEStn4tN2Pn79HlgGExh7VkXdBwVQ,1316
6
- injection/common/lazy.py,sha256=HIefQ1z7ivgU791MDSwBmUcdST3bOv0sivSMyR2DfHc,1493
7
- injection/common/tools/__init__.py,sha256=S2y9DaQ4EaTRty9fKpBtPXA7hSjkzgM5N2jFf5jcmJU,21
8
- injection/common/tools/_type.py,sha256=-zL0dtoVZme71Mscvav7iEWxY2-JltzNTekbWOCPSFo,1276
9
- injection/core/__init__.py,sha256=zuf0ubI2dHnbjn1059eduhS-ACIkkROa6-dhp10krh0,22
10
- injection/core/module.py,sha256=lEBJ6QGjPyp7bwEWE0RrOr26yrpJr1GKqsA-EV2LOAM,16594
11
- injection/exceptions.py,sha256=lm79jrBkvK52BpcAo1kx7GeDCUtskNBRt9rQ6IE3B4A,648
12
- injection/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- injection/integrations/blacksheep.py,sha256=vcLil1IccS7JtXpuVu7s2LqN5Zravfe_7xpAt5cTIU0,723
14
- injection/utils.py,sha256=_79aiciimZpuoUTz5lojKySUMMzpkU-e7SotiHIFTI8,676
15
- python_injection-0.7.4.dist-info/METADATA,sha256=JXV2O9HN1D8LGa6CSA5KaQ4lDmm4flzuZioxG4z4hBY,3433
16
- python_injection-0.7.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
17
- python_injection-0.7.4.dist-info/RECORD,,
File without changes