anydi 0.33.0__tar.gz → 0.33.1__tar.gz
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-0.33.0 → anydi-0.33.1}/PKG-INFO +1 -1
- {anydi-0.33.0 → anydi-0.33.1}/anydi/_container.py +24 -23
- {anydi-0.33.0 → anydi-0.33.1}/anydi/_context.py +7 -3
- {anydi-0.33.0 → anydi-0.33.1}/anydi/_types.py +7 -1
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/pytest_plugin.py +8 -4
- {anydi-0.33.0 → anydi-0.33.1}/pyproject.toml +1 -1
- {anydi-0.33.0 → anydi-0.33.1}/LICENSE +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/README.md +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/__init__.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/_logger.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/_module.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/_provider.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/_scanner.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/_utils.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/__init__.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/_utils.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/django/__init__.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/django/_container.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/django/_settings.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/django/_utils.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/django/apps.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/django/middleware.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/django/ninja/__init__.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/django/ninja/_operation.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/django/ninja/_signature.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/fastapi.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/faststream.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/pydantic_settings.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/starlette/__init__.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/ext/starlette/middleware.py +0 -0
- {anydi-0.33.0 → anydi-0.33.1}/anydi/py.typed +0 -0
|
@@ -25,7 +25,7 @@ from ._logger import logger
|
|
|
25
25
|
from ._module import Module, ModuleRegistry
|
|
26
26
|
from ._provider import Provider
|
|
27
27
|
from ._scanner import Scanner
|
|
28
|
-
from ._types import AnyInterface, Interface, Scope,
|
|
28
|
+
from ._types import AnyInterface, DependencyWrapper, Interface, Scope, is_marker
|
|
29
29
|
from ._utils import get_full_qualname, get_typed_parameters, is_builtin_type
|
|
30
30
|
|
|
31
31
|
T = TypeVar("T", bound=Any)
|
|
@@ -371,28 +371,6 @@ class Container:
|
|
|
371
371
|
self._patch_test_resolver(instance)
|
|
372
372
|
return cast(T, instance)
|
|
373
373
|
|
|
374
|
-
def _patch_test_resolver(self, instance: Any) -> None:
|
|
375
|
-
"""Patch the test resolver for the instance."""
|
|
376
|
-
|
|
377
|
-
def _resolver(_self: Any, _name: str) -> Any:
|
|
378
|
-
try:
|
|
379
|
-
test_interfaces = object.__getattribute__(_self, "__test_interfaces__")
|
|
380
|
-
except AttributeError:
|
|
381
|
-
test_interfaces = {
|
|
382
|
-
name: value.interface
|
|
383
|
-
for name, value in object.__getattribute__(
|
|
384
|
-
_self, "__dict__"
|
|
385
|
-
).items()
|
|
386
|
-
if isinstance(value, TestInterface)
|
|
387
|
-
}
|
|
388
|
-
object.__setattr__(_self, "__test_interfaces__", test_interfaces)
|
|
389
|
-
if _name in test_interfaces:
|
|
390
|
-
return self.resolve(test_interfaces[_name])
|
|
391
|
-
return object.__getattribute__(_self, _name)
|
|
392
|
-
|
|
393
|
-
if hasattr(instance, "__class__") and not is_builtin_type(instance.__class__):
|
|
394
|
-
instance.__class__.__getattribute__ = _resolver
|
|
395
|
-
|
|
396
374
|
@overload
|
|
397
375
|
async def aresolve(self, interface: Interface[T]) -> T: ...
|
|
398
376
|
|
|
@@ -411,6 +389,29 @@ class Container:
|
|
|
411
389
|
self._patch_test_resolver(instance)
|
|
412
390
|
return cast(T, instance)
|
|
413
391
|
|
|
392
|
+
def _patch_test_resolver(self, instance: Any) -> None:
|
|
393
|
+
"""Patch the test resolver for the instance."""
|
|
394
|
+
if not hasattr(instance, "__dict__"):
|
|
395
|
+
return
|
|
396
|
+
|
|
397
|
+
wrapped = {
|
|
398
|
+
name: value.interface
|
|
399
|
+
for name, value in instance.__dict__.items()
|
|
400
|
+
if isinstance(value, DependencyWrapper)
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
# Custom resolver function
|
|
404
|
+
def _resolver(_self: Any, _name: str) -> Any:
|
|
405
|
+
if _name in wrapped:
|
|
406
|
+
# Resolve the dependency if it's wrapped
|
|
407
|
+
return self.resolve(wrapped[_name])
|
|
408
|
+
# Fall back to default behavior
|
|
409
|
+
return object.__getattribute__(_self, _name)
|
|
410
|
+
|
|
411
|
+
# Apply the patched resolver if wrapped attributes exist
|
|
412
|
+
if wrapped:
|
|
413
|
+
instance.__class__.__getattribute__ = _resolver
|
|
414
|
+
|
|
414
415
|
def is_resolved(self, interface: AnyInterface) -> bool:
|
|
415
416
|
"""Check if an instance by interface exists."""
|
|
416
417
|
try:
|
|
@@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, Any, Callable, ClassVar
|
|
|
9
9
|
from typing_extensions import Self, final
|
|
10
10
|
|
|
11
11
|
from ._provider import CallableKind, Provider
|
|
12
|
-
from ._types import AnyInterface,
|
|
12
|
+
from ._types import AnyInterface, DependencyWrapper, Scope, is_event_type
|
|
13
13
|
from ._utils import get_full_qualname, run_async
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
@@ -99,7 +99,9 @@ class ScopedContext(abc.ABC):
|
|
|
99
99
|
instance = parameter.default
|
|
100
100
|
else:
|
|
101
101
|
if self.container.testing:
|
|
102
|
-
instance =
|
|
102
|
+
instance = DependencyWrapper(
|
|
103
|
+
interface=parameter.annotation, instance=instance
|
|
104
|
+
)
|
|
103
105
|
if parameter.kind == parameter.POSITIONAL_ONLY:
|
|
104
106
|
args.append(instance)
|
|
105
107
|
else:
|
|
@@ -127,7 +129,9 @@ class ScopedContext(abc.ABC):
|
|
|
127
129
|
instance = parameter.default
|
|
128
130
|
else:
|
|
129
131
|
if self.container.testing:
|
|
130
|
-
instance =
|
|
132
|
+
instance = DependencyWrapper(
|
|
133
|
+
interface=parameter.annotation, instance=instance
|
|
134
|
+
)
|
|
131
135
|
if parameter.kind == parameter.POSITIONAL_ONLY:
|
|
132
136
|
args.append(instance)
|
|
133
137
|
else:
|
|
@@ -39,5 +39,11 @@ def is_event_type(obj: Any) -> bool:
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
@dataclass(frozen=True)
|
|
42
|
-
class
|
|
42
|
+
class DependencyWrapper:
|
|
43
43
|
interface: type[Any]
|
|
44
|
+
instance: Any
|
|
45
|
+
|
|
46
|
+
def __getattribute__(self, name: str) -> Any:
|
|
47
|
+
if name in {"interface", "instance"}:
|
|
48
|
+
return object.__getattribute__(self, name)
|
|
49
|
+
return getattr(self.instance, name)
|
|
@@ -105,8 +105,10 @@ def _anydi_inject(
|
|
|
105
105
|
|
|
106
106
|
try:
|
|
107
107
|
request.node.funcargs[argname] = container.resolve(interface)
|
|
108
|
-
except Exception:
|
|
109
|
-
logger.warning(
|
|
108
|
+
except Exception as exc:
|
|
109
|
+
logger.warning(
|
|
110
|
+
f"Failed to resolve dependency for argument '{argname}'.", exc_info=exc
|
|
111
|
+
)
|
|
110
112
|
_anydi_unresolved.append(interface)
|
|
111
113
|
|
|
112
114
|
|
|
@@ -131,6 +133,8 @@ async def _anydi_ainject(
|
|
|
131
133
|
|
|
132
134
|
try:
|
|
133
135
|
request.node.funcargs[argname] = await container.aresolve(interface)
|
|
134
|
-
except Exception:
|
|
135
|
-
logger.warning(
|
|
136
|
+
except Exception as exc:
|
|
137
|
+
logger.warning(
|
|
138
|
+
f"Failed to resolve dependency for argument '{argname}'.", exc_info=exc
|
|
139
|
+
)
|
|
136
140
|
_anydi_unresolved.append(interface)
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|