python-injection 0.10.12__tar.gz → 0.11.0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (23) hide show
  1. {python_injection-0.10.12 → python_injection-0.11.0}/PKG-INFO +1 -1
  2. {python_injection-0.10.12 → python_injection-0.11.0}/injection/__init__.py +2 -0
  3. {python_injection-0.10.12 → python_injection-0.11.0}/injection/__init__.pyi +28 -4
  4. {python_injection-0.10.12 → python_injection-0.11.0}/injection/_core/common/event.py +2 -4
  5. python_injection-0.11.0/injection/_core/descriptors.py +25 -0
  6. {python_injection-0.10.12 → python_injection-0.11.0}/injection/integrations/fastapi.py +4 -6
  7. {python_injection-0.10.12 → python_injection-0.11.0}/injection/testing/__init__.py +2 -2
  8. {python_injection-0.10.12 → python_injection-0.11.0}/injection/utils.py +2 -2
  9. {python_injection-0.10.12 → python_injection-0.11.0}/pyproject.toml +1 -1
  10. {python_injection-0.10.12 → python_injection-0.11.0}/README.md +0 -0
  11. {python_injection-0.10.12 → python_injection-0.11.0}/injection/_core/__init__.py +0 -0
  12. {python_injection-0.10.12 → python_injection-0.11.0}/injection/_core/common/__init__.py +0 -0
  13. {python_injection-0.10.12 → python_injection-0.11.0}/injection/_core/common/invertible.py +0 -0
  14. {python_injection-0.10.12 → python_injection-0.11.0}/injection/_core/common/lazy.py +0 -0
  15. {python_injection-0.10.12 → python_injection-0.11.0}/injection/_core/common/threading.py +0 -0
  16. {python_injection-0.10.12 → python_injection-0.11.0}/injection/_core/common/type.py +0 -0
  17. {python_injection-0.10.12 → python_injection-0.11.0}/injection/_core/hook.py +0 -0
  18. {python_injection-0.10.12 → python_injection-0.11.0}/injection/_core/module.py +0 -0
  19. {python_injection-0.10.12 → python_injection-0.11.0}/injection/exceptions.py +0 -0
  20. {python_injection-0.10.12 → python_injection-0.11.0}/injection/integrations/__init__.py +0 -0
  21. {python_injection-0.10.12 → python_injection-0.11.0}/injection/integrations/blacksheep.py +0 -0
  22. {python_injection-0.10.12 → python_injection-0.11.0}/injection/py.typed +0 -0
  23. {python_injection-0.10.12 → python_injection-0.11.0}/injection/testing/__init__.pyi +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-injection
3
- Version: 0.10.12
3
+ Version: 0.11.0
4
4
  Summary: Fast and easy dependency injection framework.
5
5
  Home-page: https://github.com/100nm/python-injection
6
6
  License: MIT
@@ -1,7 +1,9 @@
1
+ from ._core.descriptors import LazyInstance
1
2
  from ._core.module import Injectable, Mode, Module, Priority
2
3
 
3
4
  __all__ = (
4
5
  "Injectable",
6
+ "LazyInstance",
5
7
  "Mode",
6
8
  "Module",
7
9
  "Priority",
@@ -9,6 +9,7 @@ from typing import (
9
9
  Protocol,
10
10
  Self,
11
11
  final,
12
+ overload,
12
13
  runtime_checkable,
13
14
  )
14
15
 
@@ -136,23 +137,31 @@ class Module:
136
137
  parameter or an exception will be raised.
137
138
  """
138
139
 
140
+ @overload
139
141
  def get_instance[T, Default](
140
142
  self,
141
143
  cls: _InputType[T],
142
- default: Default | None = ...,
143
- ) -> T | Default | None:
144
+ default: Default,
145
+ ) -> T | Default:
144
146
  """
145
147
  Function used to retrieve an instance associated with the type passed in
146
148
  parameter or return `None`.
147
149
  """
148
150
 
151
+ @overload
152
+ def get_instance[T, _](
153
+ self,
154
+ cls: _InputType[T],
155
+ default: None = ...,
156
+ ) -> T | None: ...
157
+ @overload
149
158
  def get_lazy_instance[T, Default](
150
159
  self,
151
160
  cls: _InputType[T],
152
- default: Default | None = ...,
161
+ default: Default,
153
162
  *,
154
163
  cache: bool = ...,
155
- ) -> _Invertible[T | Default | None]:
164
+ ) -> _Invertible[T | Default]:
156
165
  """
157
166
  Function used to retrieve an instance associated with the type passed in
158
167
  parameter or `None`. Return a `Invertible` object. To access the instance
@@ -162,6 +171,14 @@ class Module:
162
171
  Example: instance = ~lazy_instance
163
172
  """
164
173
 
174
+ @overload
175
+ def get_lazy_instance[T, _](
176
+ self,
177
+ cls: _InputType[T],
178
+ default: None = ...,
179
+ *,
180
+ cache: bool = ...,
181
+ ) -> _Invertible[T | None]: ...
165
182
  def init_modules(self, *modules: Module) -> Self:
166
183
  """
167
184
  Function to clean modules in use and to use those passed as parameters.
@@ -243,3 +260,10 @@ class Mode(Enum):
243
260
  FALLBACK = ...
244
261
  NORMAL = ...
245
262
  OVERRIDE = ...
263
+
264
+ class LazyInstance[T]:
265
+ def __init__(self, cls: _InputType[T], module: Module = ...) -> None: ...
266
+ @overload
267
+ def __get__(self, instance: object, owner: type | None = ...) -> T: ...
268
+ @overload
269
+ def __get__(self, instance: None = ..., owner: type | None = ...) -> Self: ...
@@ -1,6 +1,6 @@
1
1
  from abc import ABC, abstractmethod
2
2
  from collections.abc import Iterator
3
- from contextlib import ExitStack, contextmanager, suppress
3
+ from contextlib import ExitStack, contextmanager
4
4
  from dataclasses import dataclass, field
5
5
  from typing import ContextManager, Self
6
6
  from weakref import WeakSet
@@ -40,7 +40,5 @@ class EventChannel:
40
40
  return self
41
41
 
42
42
  def remove_listener(self, listener: EventListener) -> Self:
43
- with suppress(KeyError):
44
- self.__listeners.remove(listener)
45
-
43
+ self.__listeners.discard(listener)
46
44
  return self
@@ -0,0 +1,25 @@
1
+ from typing import Self
2
+
3
+ from injection._core.common.invertible import Invertible
4
+ from injection._core.common.type import InputType
5
+ from injection._core.module import Module
6
+
7
+
8
+ class LazyInstance[T]:
9
+ __slots__ = ("__value",)
10
+
11
+ __value: Invertible[T]
12
+
13
+ def __init__(self, cls: InputType[T], module: Module | None = None) -> None:
14
+ module = module or Module.default()
15
+ self.__value = module.get_lazy_instance(cls, default=NotImplemented) # type: ignore[assignment]
16
+
17
+ def __get__(
18
+ self,
19
+ instance: object | None = None,
20
+ owner: type | None = None,
21
+ ) -> Self | T:
22
+ if instance is None:
23
+ return self
24
+
25
+ return ~self.__value
@@ -1,6 +1,6 @@
1
1
  from collections.abc import Callable
2
2
  from types import GenericAlias
3
- from typing import Any, ClassVar, TypeAliasType
3
+ from typing import Any, TypeAliasType
4
4
 
5
5
  from injection import Module, mod
6
6
  from injection.exceptions import InjectionError
@@ -34,10 +34,8 @@ class InjectionDependency[T]:
34
34
  __class: type[T] | TypeAliasType | GenericAlias
35
35
  __module: Module
36
36
 
37
- __sentinel: ClassVar[object] = object()
38
-
39
37
  def __init__(self, cls: type[T] | TypeAliasType | GenericAlias, module: Module):
40
- lazy_instance = module.get_lazy_instance(cls, default=self.__sentinel)
38
+ lazy_instance = module.get_lazy_instance(cls, default=NotImplemented)
41
39
  self.__call__ = lambda: self.__ensure(~lazy_instance)
42
40
  self.__class = cls
43
41
  self.__module = module
@@ -55,8 +53,8 @@ class InjectionDependency[T]:
55
53
  def __key(self) -> tuple[type[T] | TypeAliasType | GenericAlias, Module]:
56
54
  return self.__class, self.__module
57
55
 
58
- def __ensure(self, instance: T | Any) -> T:
59
- if instance is self.__sentinel:
56
+ def __ensure(self, instance: T) -> T:
57
+ if instance is NotImplemented:
60
58
  raise InjectionError(f"`{self.__class}` is an unknown dependency.")
61
59
 
62
60
  return instance
@@ -21,5 +21,5 @@ test_injectable = mod(_TEST_PROFILE_NAME).injectable
21
21
  test_singleton = mod(_TEST_PROFILE_NAME).singleton
22
22
 
23
23
 
24
- def load_test_profile(*other_profile_names: str) -> ContextManager[None]:
25
- return load_profile(_TEST_PROFILE_NAME, *other_profile_names)
24
+ def load_test_profile(*names: str) -> ContextManager[None]:
25
+ return load_profile(_TEST_PROFILE_NAME, *names)
@@ -10,13 +10,13 @@ from injection import mod
10
10
  __all__ = ("load_packages", "load_profile")
11
11
 
12
12
 
13
- def load_profile(name: str, /, *other_profile_names: str) -> ContextManager[None]:
13
+ def load_profile(*names: str) -> ContextManager[None]:
14
14
  """
15
15
  Injection module initialization function based on profile name.
16
16
  A profile name is equivalent to an injection module name.
17
17
  """
18
18
 
19
- modules = tuple(mod(module_name) for module_name in (name, *other_profile_names))
19
+ modules = tuple(mod(module_name) for module_name in names)
20
20
 
21
21
  for module in modules:
22
22
  module.unlock()
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-injection"
3
- version = "0.10.12"
3
+ version = "0.11.0"
4
4
  description = "Fast and easy dependency injection framework."
5
5
  license = "MIT"
6
6
  authors = ["remimd"]