anydi 0.43.0__py3-none-any.whl → 0.44.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.
- anydi/_container.py +12 -31
- anydi/ext/_utils.py +1 -11
- anydi/ext/django/_settings.py +0 -2
- anydi/ext/django/apps.py +1 -3
- anydi/ext/pytest_plugin.py +4 -4
- anydi/testing.py +1 -4
- {anydi-0.43.0.dist-info → anydi-0.44.0.dist-info}/METADATA +1 -1
- {anydi-0.43.0.dist-info → anydi-0.44.0.dist-info}/RECORD +11 -11
- {anydi-0.43.0.dist-info → anydi-0.44.0.dist-info}/WHEEL +0 -0
- {anydi-0.43.0.dist-info → anydi-0.44.0.dist-info}/entry_points.txt +0 -0
- {anydi-0.43.0.dist-info → anydi-0.44.0.dist-info}/licenses/LICENSE +0 -0
anydi/_container.py
CHANGED
|
@@ -19,11 +19,7 @@ from ._async import run_sync
|
|
|
19
19
|
from ._context import InstanceContext
|
|
20
20
|
from ._decorators import is_provided
|
|
21
21
|
from ._module import ModuleDef, ModuleRegistrar
|
|
22
|
-
from ._provider import
|
|
23
|
-
Provider,
|
|
24
|
-
ProviderDef,
|
|
25
|
-
ProviderKind,
|
|
26
|
-
)
|
|
22
|
+
from ._provider import Provider, ProviderDef, ProviderKind
|
|
27
23
|
from ._scan import PackageOrIterable, Scanner
|
|
28
24
|
from ._scope import ALLOWED_SCOPES, Scope
|
|
29
25
|
from ._typing import (
|
|
@@ -53,12 +49,10 @@ class Container:
|
|
|
53
49
|
*,
|
|
54
50
|
providers: Iterable[ProviderDef] | None = None,
|
|
55
51
|
modules: Iterable[ModuleDef] | None = None,
|
|
56
|
-
strict: bool = False,
|
|
57
52
|
default_scope: Scope = "transient",
|
|
58
53
|
logger: logging.Logger | None = None,
|
|
59
54
|
) -> None:
|
|
60
55
|
self._providers: dict[Any, Provider] = {}
|
|
61
|
-
self._strict = strict
|
|
62
56
|
self._default_scope: Scope = default_scope
|
|
63
57
|
self._logger = logger or logging.getLogger(__name__)
|
|
64
58
|
self._resources: dict[str, list[Any]] = defaultdict(list)
|
|
@@ -91,11 +85,6 @@ class Container:
|
|
|
91
85
|
# Properties
|
|
92
86
|
############################
|
|
93
87
|
|
|
94
|
-
@property
|
|
95
|
-
def strict(self) -> bool:
|
|
96
|
-
"""Check if strict mode is enabled."""
|
|
97
|
-
return self._strict
|
|
98
|
-
|
|
99
88
|
@property
|
|
100
89
|
def default_scope(self) -> Scope:
|
|
101
90
|
"""Get the default scope."""
|
|
@@ -231,6 +220,10 @@ class Container:
|
|
|
231
220
|
"""Check if a provider is registered for the specified interface."""
|
|
232
221
|
return interface in self._providers
|
|
233
222
|
|
|
223
|
+
def has_provider_for(self, interface: Any) -> bool:
|
|
224
|
+
"""Check if a provider exists for the specified interface."""
|
|
225
|
+
return self.is_registered(interface) or is_provided(interface)
|
|
226
|
+
|
|
234
227
|
def unregister(self, interface: Any) -> None:
|
|
235
228
|
"""Unregister a provider by interface."""
|
|
236
229
|
if not self.is_registered(interface):
|
|
@@ -440,7 +433,7 @@ class Container:
|
|
|
440
433
|
try:
|
|
441
434
|
return self._get_provider(interface)
|
|
442
435
|
except LookupError:
|
|
443
|
-
if
|
|
436
|
+
if interface is inspect.Parameter.empty:
|
|
444
437
|
raise
|
|
445
438
|
if inspect.isclass(interface) and not is_builtin_type(interface):
|
|
446
439
|
# Try to get defined scope
|
|
@@ -464,14 +457,13 @@ class Container:
|
|
|
464
457
|
if provider.is_resource:
|
|
465
458
|
self._resources[provider.scope].remove(provider.interface)
|
|
466
459
|
|
|
460
|
+
@staticmethod
|
|
467
461
|
def _parameter_has_default(
|
|
468
|
-
|
|
462
|
+
parameter: inspect.Parameter, /, **defaults: Any
|
|
469
463
|
) -> bool:
|
|
470
464
|
has_default_in_kwargs = parameter.name in defaults if defaults else False
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
)
|
|
474
|
-
return has_default_in_kwargs or has_non_strict_default
|
|
465
|
+
has_default = parameter.default is not inspect.Parameter.empty
|
|
466
|
+
return has_default_in_kwargs or has_default
|
|
475
467
|
|
|
476
468
|
############################
|
|
477
469
|
# Instance Methods
|
|
@@ -822,18 +814,7 @@ class Container:
|
|
|
822
814
|
for parameter in get_typed_parameters(call):
|
|
823
815
|
if not is_marker(parameter.default):
|
|
824
816
|
continue
|
|
825
|
-
|
|
826
|
-
self._validate_injected_parameter(call, parameter)
|
|
827
|
-
except LookupError as exc:
|
|
828
|
-
if not self.strict:
|
|
829
|
-
self.logger.debug(
|
|
830
|
-
f"Cannot validate the `{type_repr(call)}` parameter "
|
|
831
|
-
f"`{parameter.name}` with an annotation of "
|
|
832
|
-
f"`{type_repr(parameter.annotation)} due to being "
|
|
833
|
-
"in non-strict mode. It will be validated at the first call."
|
|
834
|
-
)
|
|
835
|
-
else:
|
|
836
|
-
raise exc
|
|
817
|
+
self._validate_injected_parameter(call, parameter)
|
|
837
818
|
injected_params[parameter.name] = parameter.annotation
|
|
838
819
|
return injected_params
|
|
839
820
|
|
|
@@ -846,7 +827,7 @@ class Container:
|
|
|
846
827
|
f"Missing `{type_repr(call)}` parameter `{parameter.name}` annotation."
|
|
847
828
|
)
|
|
848
829
|
|
|
849
|
-
if not self.
|
|
830
|
+
if not self.has_provider_for(parameter.annotation):
|
|
850
831
|
raise LookupError(
|
|
851
832
|
f"`{type_repr(call)}` has an unknown dependency parameter "
|
|
852
833
|
f"`{parameter.name}` with an annotation of "
|
anydi/ext/_utils.py
CHANGED
|
@@ -9,7 +9,6 @@ from typing import Annotated, Any, Callable
|
|
|
9
9
|
from typing_extensions import get_args, get_origin
|
|
10
10
|
|
|
11
11
|
from anydi._container import Container
|
|
12
|
-
from anydi._typing import type_repr
|
|
13
12
|
|
|
14
13
|
logger = logging.getLogger(__name__)
|
|
15
14
|
|
|
@@ -69,15 +68,6 @@ def patch_call_parameter(
|
|
|
69
68
|
if not isinstance(parameter.default, HasInterface):
|
|
70
69
|
return None
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
logger.debug(
|
|
74
|
-
f"Callable `{type_repr(call)}` injected parameter "
|
|
75
|
-
f"`{parameter.name}` with an annotation of "
|
|
76
|
-
f"`{type_repr(parameter.annotation)}` "
|
|
77
|
-
"is not registered. It will be registered at runtime with the "
|
|
78
|
-
"first call because it is running in non-strict mode."
|
|
79
|
-
)
|
|
80
|
-
else:
|
|
81
|
-
container._validate_injected_parameter(call, parameter) # noqa
|
|
71
|
+
container._validate_injected_parameter(call, parameter) # noqa
|
|
82
72
|
|
|
83
73
|
parameter.default.interface = parameter.annotation
|
anydi/ext/django/_settings.py
CHANGED
|
@@ -8,7 +8,6 @@ from typing_extensions import TypedDict
|
|
|
8
8
|
|
|
9
9
|
class Settings(TypedDict):
|
|
10
10
|
CONTAINER_FACTORY: str | None
|
|
11
|
-
STRICT_MODE: bool
|
|
12
11
|
REGISTER_SETTINGS: bool
|
|
13
12
|
REGISTER_COMPONENTS: bool
|
|
14
13
|
INJECT_URLCONF: str | Sequence[str] | None
|
|
@@ -19,7 +18,6 @@ class Settings(TypedDict):
|
|
|
19
18
|
|
|
20
19
|
DEFAULTS = Settings(
|
|
21
20
|
CONTAINER_FACTORY=None,
|
|
22
|
-
STRICT_MODE=False,
|
|
23
21
|
REGISTER_SETTINGS=False,
|
|
24
22
|
REGISTER_COMPONENTS=False,
|
|
25
23
|
MODULES=[],
|
anydi/ext/django/apps.py
CHANGED
|
@@ -34,9 +34,7 @@ class ContainerConfig(AppConfig):
|
|
|
34
34
|
) from exc
|
|
35
35
|
self.container = container_factory()
|
|
36
36
|
else:
|
|
37
|
-
self.container = anydi.Container(
|
|
38
|
-
strict=self.settings["STRICT_MODE"],
|
|
39
|
-
)
|
|
37
|
+
self.container = anydi.Container()
|
|
40
38
|
|
|
41
39
|
def ready(self) -> None: # noqa: C901
|
|
42
40
|
# Register Django settings
|
anydi/ext/pytest_plugin.py
CHANGED
|
@@ -88,8 +88,8 @@ def _anydi_inject(
|
|
|
88
88
|
container = cast(Container, request.getfixturevalue("anydi_setup_container"))
|
|
89
89
|
|
|
90
90
|
for argname, interface in _anydi_injected_parameter_iterator():
|
|
91
|
-
# Skip if the interface
|
|
92
|
-
if
|
|
91
|
+
# Skip if the interface has no provider
|
|
92
|
+
if not container.has_provider_for(interface):
|
|
93
93
|
continue
|
|
94
94
|
|
|
95
95
|
try:
|
|
@@ -128,8 +128,8 @@ def _anydi_ainject(
|
|
|
128
128
|
container = cast(Container, request.getfixturevalue("anydi_setup_container"))
|
|
129
129
|
|
|
130
130
|
for argname, interface in _anydi_injected_parameter_iterator():
|
|
131
|
-
# Skip if the interface
|
|
132
|
-
if
|
|
131
|
+
# Skip if the interface has no provider
|
|
132
|
+
if not container.has_provider_for(interface):
|
|
133
133
|
continue
|
|
134
134
|
|
|
135
135
|
try:
|
anydi/testing.py
CHANGED
|
@@ -23,14 +23,12 @@ class TestContainer(Container):
|
|
|
23
23
|
*,
|
|
24
24
|
providers: Sequence[ProviderDef] | None = None,
|
|
25
25
|
modules: Iterable[ModuleDef] | None = None,
|
|
26
|
-
strict: bool = False,
|
|
27
26
|
default_scope: Scope = "transient",
|
|
28
27
|
logger: logging.Logger | None = None,
|
|
29
28
|
) -> None:
|
|
30
29
|
super().__init__(
|
|
31
30
|
providers=providers,
|
|
32
31
|
modules=modules,
|
|
33
|
-
strict=strict,
|
|
34
32
|
default_scope=default_scope,
|
|
35
33
|
logger=logger,
|
|
36
34
|
)
|
|
@@ -47,7 +45,6 @@ class TestContainer(Container):
|
|
|
47
45
|
)
|
|
48
46
|
for provider in container.providers.values()
|
|
49
47
|
],
|
|
50
|
-
strict=container.strict,
|
|
51
48
|
default_scope=container.default_scope,
|
|
52
49
|
logger=container.logger,
|
|
53
50
|
)
|
|
@@ -57,7 +54,7 @@ class TestContainer(Container):
|
|
|
57
54
|
"""
|
|
58
55
|
Override the provider for the specified interface with a specific instance.
|
|
59
56
|
"""
|
|
60
|
-
if not self.
|
|
57
|
+
if not self.has_provider_for(interface):
|
|
61
58
|
raise LookupError(
|
|
62
59
|
f"The provider interface `{type_repr(interface)}` not registered."
|
|
63
60
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
anydi/__init__.py,sha256=UH3N0LIw4ysoV0_EFgtDNioxEQxOmeytYbJnS8MXIXM,532
|
|
2
2
|
anydi/_async.py,sha256=KhRd3RmZFcwNDzrMm8ctA1gwrg-6m_7laECTYsZdF5k,1445
|
|
3
|
-
anydi/_container.py,sha256=
|
|
3
|
+
anydi/_container.py,sha256=lc4sT0kMgPUgJOxKEaJcNCuVZ8Lc4tS-6POOTumrCmM,30946
|
|
4
4
|
anydi/_context.py,sha256=_Xy8cTpRskb4cxTd-Fe-5NnIZyBe1DnovkofhdeUfmw,3020
|
|
5
5
|
anydi/_decorators.py,sha256=F3yBeGQSz1EsulZaEvYn3cd6FEjJRMoyA6u1QCbEwcs,2813
|
|
6
6
|
anydi/_module.py,sha256=QPvP27JndZkwl-FYUZWscJm6yfkNzjwoFGURyDhb6Pc,2582
|
|
@@ -9,26 +9,26 @@ anydi/_scan.py,sha256=WOdsPaoRZPYw4kBzoBXyWhkiwuxY8_UjHfa0c9QFyLc,3639
|
|
|
9
9
|
anydi/_scope.py,sha256=PFHjPb2-n0vhRo9mvD_craTFfoJBzR3y-N3_0apL5Q0,258
|
|
10
10
|
anydi/_typing.py,sha256=m7KnVenDE1E420IeYz2Ocw6dhddmSFbuBBgkOXtl9pA,3709
|
|
11
11
|
anydi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
anydi/testing.py,sha256=
|
|
12
|
+
anydi/testing.py,sha256=J7W5m4nRxi8XW99pi5gqHLXfwCC0AqAtemIA1Li3x8c,5856
|
|
13
13
|
anydi/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
anydi/ext/_utils.py,sha256=
|
|
14
|
+
anydi/ext/_utils.py,sha256=QthoO0Nxv_nI-yQ9kGSi9jLLT5N71BxOgFNXwLQ5DQ0,2073
|
|
15
15
|
anydi/ext/fastapi.py,sha256=q7q1hF5v4dpV3YM4L1CVuD20bXC7f5S7e1apAfekkG0,2448
|
|
16
16
|
anydi/ext/faststream.py,sha256=DLZTfiGeZJCiwfmZTvVecaTlX84_jqClh6cgY2qMPJg,1910
|
|
17
17
|
anydi/ext/pydantic_settings.py,sha256=8IXXLuG_OvKbvKlBkBRQUHcXgbTpgQUxeWyoMcRIUQM,1488
|
|
18
|
-
anydi/ext/pytest_plugin.py,sha256=
|
|
18
|
+
anydi/ext/pytest_plugin.py,sha256=IoP6XKuGLGLd2Xlpfttc3mI4pxCm2WQLE7x_a7asbv4,4732
|
|
19
19
|
anydi/ext/django/__init__.py,sha256=QI1IABCVgSDTUoh7M9WMECKXwB3xvh04HfQ9TOWw1Mk,223
|
|
20
20
|
anydi/ext/django/_container.py,sha256=cxVoYQG16WP0S_Yv4TnLwuaaT7NVEOhLWO-YdALJUb4,418
|
|
21
|
-
anydi/ext/django/_settings.py,sha256=
|
|
21
|
+
anydi/ext/django/_settings.py,sha256=NsYbFBeslqw_tcXCn2b2gKnSp7eb64DM4dRc4tn_eiw,808
|
|
22
22
|
anydi/ext/django/_utils.py,sha256=N1DZlY5RHxbb7TUWH-BWWC78GzUX_a1oYEZ8hT8WgaE,2663
|
|
23
|
-
anydi/ext/django/apps.py,sha256=
|
|
23
|
+
anydi/ext/django/apps.py,sha256=YLL1uU6dSQ3uf3GB0VHzPW_eLuB1j9h6pv8EdAutMqo,2725
|
|
24
24
|
anydi/ext/django/middleware.py,sha256=5OUdp0OWRozyW338Sq04BDhacaFlyUTTOduS_7EwCTA,854
|
|
25
25
|
anydi/ext/django/ninja/__init__.py,sha256=4J0zoHPK9itbTVrjjvLX6Ftrsb2ND8bITqNDIJzEhks,520
|
|
26
26
|
anydi/ext/django/ninja/_operation.py,sha256=wk5EOjLY3KVIHk9jMCGsFsja9-dQmMOpLpHXciqxQdk,2680
|
|
27
27
|
anydi/ext/django/ninja/_signature.py,sha256=UVLmKpYvH1fNb9C7ffP50KCmh0BE6unHegfss5dvpVU,2261
|
|
28
28
|
anydi/ext/starlette/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
29
|
anydi/ext/starlette/middleware.py,sha256=MxnzshAs-CMvjJp0r457k52MzBL8O4KAuClnF6exBdU,803
|
|
30
|
-
anydi-0.
|
|
31
|
-
anydi-0.
|
|
32
|
-
anydi-0.
|
|
33
|
-
anydi-0.
|
|
34
|
-
anydi-0.
|
|
30
|
+
anydi-0.44.0.dist-info/METADATA,sha256=c5w1BMcgZzQpKFh2pQlRYq602OKr56x1kMt9gy5m31U,4957
|
|
31
|
+
anydi-0.44.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
32
|
+
anydi-0.44.0.dist-info/entry_points.txt,sha256=Nklo9f3Oe4AkNsEgC4g43nCJ-23QDngZSVDNRMdaILI,43
|
|
33
|
+
anydi-0.44.0.dist-info/licenses/LICENSE,sha256=V6rU8a8fv6o2jQ-7ODHs0XfDFimot8Q6Km6CylRIDTo,1069
|
|
34
|
+
anydi-0.44.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|