python-injection 0.12.1.post0__tar.gz → 0.12.3__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/PKG-INFO +1 -1
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/asynchronous.py +12 -5
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/module.py +2 -2
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/integrations/fastapi.py +2 -4
- python_injection-0.12.3/injection/py.typed +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/utils.py +34 -2
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/pyproject.toml +1 -1
- python_injection-0.12.1.post0/injection/integrations/__init__.py +0 -11
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/README.md +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/__init__.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/__init__.pyi +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/__init__.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/__init__.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/event.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/invertible.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/lazy.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/threading.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/type.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/descriptors.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/hook.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/injectables.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/exceptions.py +0 -0
- /python_injection-0.12.1.post0/injection/py.typed → /python_injection-0.12.3/injection/integrations/__init__.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/testing/__init__.py +0 -0
- {python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/testing/__init__.pyi +0 -0
{python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/asynchronous.py
RENAMED
@@ -1,7 +1,8 @@
|
|
1
|
+
import asyncio
|
1
2
|
from abc import abstractmethod
|
2
3
|
from collections.abc import Awaitable, Callable, Generator
|
3
4
|
from dataclasses import dataclass
|
4
|
-
from typing import Any,
|
5
|
+
from typing import Any, Protocol, runtime_checkable
|
5
6
|
|
6
7
|
|
7
8
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
@@ -32,10 +33,16 @@ class AsyncCaller[**P, T](Caller[P, T]):
|
|
32
33
|
async def acall(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
|
33
34
|
return await self.callable(*args, **kwargs)
|
34
35
|
|
35
|
-
def call(self, /, *args: P.args, **kwargs: P.kwargs) ->
|
36
|
-
|
37
|
-
|
38
|
-
)
|
36
|
+
def call(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
|
37
|
+
loop = asyncio.get_event_loop()
|
38
|
+
|
39
|
+
if loop.is_running():
|
40
|
+
raise RuntimeError(
|
41
|
+
"Can't call an asynchronous function in a synchronous context."
|
42
|
+
)
|
43
|
+
|
44
|
+
coroutine = self.callable(*args, **kwargs)
|
45
|
+
return loop.run_until_complete(coroutine)
|
39
46
|
|
40
47
|
|
41
48
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
@@ -78,8 +78,8 @@ class LocatorDependenciesUpdated[T](LocatorEvent):
|
|
78
78
|
length = len(self.classes)
|
79
79
|
formatted_types = ", ".join(f"`{cls}`" for cls in self.classes)
|
80
80
|
return (
|
81
|
-
f"{length} dependenc{
|
82
|
-
f"updated{f
|
81
|
+
f"{length} dependenc{'ies' if length > 1 else 'y'} have been "
|
82
|
+
f"updated{f': {formatted_types}' if formatted_types else ''}."
|
83
83
|
)
|
84
84
|
|
85
85
|
|
@@ -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,
|
File without changes
|
@@ -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,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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/__init__.py
RENAMED
File without changes
|
File without changes
|
{python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/invertible.py
RENAMED
File without changes
|
File without changes
|
{python_injection-0.12.1.post0 → python_injection-0.12.3}/injection/_core/common/threading.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|