python-injection 0.12.1__py3-none-any.whl → 0.12.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
injection/_core/module.py CHANGED
@@ -208,18 +208,20 @@ class Updater[T]:
208
208
  return Record(injectable, self.mode)
209
209
 
210
210
 
211
- class LocatorHooks[T](NamedTuple):
212
- on_conflict: Hook[[Record[T], Record[T], InputType[T]], bool]
213
- on_input: Hook[[Iterable[InputType[T]]], Iterable[InputType[T]]]
214
- on_update: Hook[[Updater[T]], Updater[T]]
215
-
216
- @classmethod
217
- def default(cls) -> Self:
218
- return cls(
219
- on_conflict=Hook(),
220
- on_input=Hook(),
221
- on_update=Hook(),
222
- )
211
+ @dataclass(repr=False, eq=False, frozen=True, slots=True)
212
+ class LocatorHooks[T]:
213
+ on_conflict: Hook[[Record[T], Record[T], InputType[T]], bool] = field(
214
+ default_factory=Hook,
215
+ init=False,
216
+ )
217
+ on_input: Hook[[Iterable[InputType[T]]], Iterable[InputType[T]]] = field(
218
+ default_factory=Hook,
219
+ init=False,
220
+ )
221
+ on_update: Hook[[Updater[T]], Updater[T]] = field(
222
+ default_factory=Hook,
223
+ init=False,
224
+ )
223
225
 
224
226
 
225
227
  @dataclass(repr=False, frozen=True, slots=True)
@@ -233,7 +235,7 @@ class Locator(Broker):
233
235
  init=False,
234
236
  )
235
237
 
236
- static_hooks: ClassVar[LocatorHooks[Any]] = LocatorHooks.default()
238
+ static_hooks: ClassVar[LocatorHooks[Any]] = LocatorHooks()
237
239
 
238
240
  def __getitem__[T](self, cls: InputType[T], /) -> Injectable[T]:
239
241
  for input_class in self.__standardize_inputs((cls,)):
@@ -1,11 +0,0 @@
1
- from importlib.util import find_spec
2
- from typing import Literal
3
-
4
- __all__ = ("_is_installed",)
5
-
6
-
7
- def _is_installed(package: str, needed_for: object, /) -> Literal[True]:
8
- if find_spec(package) is None:
9
- raise RuntimeError(f"To use `{needed_for}`, {package} must be installed.")
10
-
11
- return True
@@ -2,15 +2,13 @@ from collections.abc import Awaitable
2
2
  from types import GenericAlias
3
3
  from typing import Any, TypeAliasType
4
4
 
5
+ from fastapi import Depends
6
+
5
7
  from injection import Module, mod
6
8
  from injection.exceptions import InjectionError
7
- from injection.integrations import _is_installed
8
9
 
9
10
  __all__ = ("Inject",)
10
11
 
11
- if _is_installed("fastapi", __name__):
12
- from fastapi import Depends
13
-
14
12
 
15
13
  def Inject[T]( # noqa: N802
16
14
  cls: type[T] | TypeAliasType | GenericAlias,
injection/utils.py CHANGED
@@ -1,13 +1,15 @@
1
- from collections.abc import Callable, Iterator
1
+ from collections.abc import Callable, Iterable, Iterator
2
2
  from contextlib import contextmanager
3
3
  from importlib import import_module
4
+ from importlib.util import find_spec
4
5
  from pkgutil import walk_packages
5
6
  from types import ModuleType as PythonModule
6
7
  from typing import ContextManager
7
8
 
9
+ from injection import __name__ as injection_package_name
8
10
  from injection import mod
9
11
 
10
- __all__ = ("load_packages", "load_profile")
12
+ __all__ = ("load_modules_with_keywords", "load_packages", "load_profile")
11
13
 
12
14
 
13
15
  def load_profile(*names: str) -> ContextManager[None]:
@@ -33,6 +35,36 @@ def load_profile(*names: str) -> ContextManager[None]:
33
35
  return cleaner()
34
36
 
35
37
 
38
+ def load_modules_with_keywords(
39
+ *packages: PythonModule | str,
40
+ keywords: Iterable[str] | None = None,
41
+ ) -> dict[str, PythonModule]:
42
+ """
43
+ Function to import modules from a Python package if one of the keywords is contained in the Python script.
44
+ The default keywords are:
45
+ - `from injection`
46
+ - `import injection`
47
+ """
48
+
49
+ if keywords is None:
50
+ keywords = f"from {injection_package_name}", f"import {injection_package_name}"
51
+
52
+ b_keywords = tuple(keyword.encode() for keyword in keywords)
53
+
54
+ def predicate(module_name: str) -> bool:
55
+ if (spec := find_spec(module_name)) and (module_path := spec.origin):
56
+ with open(module_path, "rb") as script:
57
+ for line in script:
58
+ line = b" ".join(line.split(b" ")).strip()
59
+
60
+ if line and any(keyword in line for keyword in b_keywords):
61
+ return True
62
+
63
+ return False
64
+
65
+ return load_packages(*packages, predicate=predicate)
66
+
67
+
36
68
  def load_packages(
37
69
  *packages: PythonModule | str,
38
70
  predicate: Callable[[str], bool] = lambda module_name: True,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: python-injection
3
- Version: 0.12.1
3
+ Version: 0.12.2
4
4
  Summary: Fast and easy dependency injection framework.
5
5
  Home-page: https://github.com/100nm/python-injection
6
6
  License: MIT
@@ -11,14 +11,14 @@ injection/_core/common/type.py,sha256=c4QfvbkMfYMlNxqt-vq6QJ83ubMnw6AIVI2Rp-tV1P
11
11
  injection/_core/descriptors.py,sha256=y1rFTQdCDIMLVQfuQE8ZkTPlVZKgzvwZ2Y20Si05DwM,662
12
12
  injection/_core/hook.py,sha256=Qv505pr3kjOE6UitftlLh9JKX9OCNqZBRtHbFha1gqM,3130
13
13
  injection/_core/injectables.py,sha256=rBcrTYRpZ69LkHSGm6bve6TGPwf66XkuK2XVACwcRNc,2427
14
- injection/_core/module.py,sha256=xUgveXJS5PXd3DtfLBH7InafEtSShGND4ccYkCIfGqk,28611
14
+ injection/_core/module.py,sha256=H6seGNW482IEBNGGDxT9Lkv84TYQwWnoYYPcbzdF7YI,28675
15
15
  injection/exceptions.py,sha256=-5Shs7R5rctQXhpMLfcjiMBCzrtFWxC88qETUIHz57s,692
16
- injection/integrations/__init__.py,sha256=NYLcstr4ESdLj326LlDub143z6JGM1z1pCOVWhBXK10,304
17
- injection/integrations/fastapi.py,sha256=OZyZNxqJvOr-c5Ee0G1-oHhGF7067Ugjl_qDnIiAC1I,1760
16
+ injection/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ injection/integrations/fastapi.py,sha256=tI9ohXOm_WucqkS-DZJceIVb_mE9LOY_UpIcr6hfRVM,1668
18
18
  injection/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  injection/testing/__init__.py,sha256=Wd9sq43CJCV7GjYFSIaikIf4hJ5lfVNS7GP3iI8a1X8,719
20
20
  injection/testing/__init__.pyi,sha256=Dyf1LjSj3LrjghXjM2xkMiINg-OPWQMtjCEnnfWzaDY,372
21
- injection/utils.py,sha256=79VoIgxO1MNb_FlfRRbzfx3RXX3DPDtoxMgngfmNF-Q,1920
22
- python_injection-0.12.1.dist-info/METADATA,sha256=2TdNJGHf1TIvBrbRkVjfimNJR7frm4HDoKDnAYiop98,2958
23
- python_injection-0.12.1.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
24
- python_injection-0.12.1.dist-info/RECORD,,
21
+ injection/utils.py,sha256=a9y95B08Fr9IgDiBffeQdcawQcvAs5gwBDt9cCYX0uE,3061
22
+ python_injection-0.12.2.dist-info/METADATA,sha256=z_ybsuZ__2e8nCbkaT9tYjGsywJ6BzdrsBcima0bq20,2958
23
+ python_injection-0.12.2.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
24
+ python_injection-0.12.2.dist-info/RECORD,,