anydi 0.64.0__tar.gz → 0.66.0__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.64.0 → anydi-0.66.0}/PKG-INFO +28 -28
- {anydi-0.64.0 → anydi-0.66.0}/README.md +27 -27
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_container.py +5 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_resolver.py +34 -16
- {anydi-0.64.0 → anydi-0.66.0}/pyproject.toml +1 -1
- {anydi-0.64.0 → anydi-0.66.0}/anydi/__init__.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_async_lock.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_context.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_decorators.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_injector.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_marker.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_module.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_provider.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_scanner.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/_types.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/ext/__init__.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/ext/django/__init__.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/ext/fastapi.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/ext/faststream.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/ext/pydantic_settings.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/ext/pytest_plugin.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/ext/starlette/__init__.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/ext/starlette/middleware.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/ext/typer.py +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/py.typed +0 -0
- {anydi-0.64.0 → anydi-0.66.0}/anydi/testing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: anydi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.66.0
|
|
4
4
|
Summary: Dependency Injection library
|
|
5
5
|
Keywords: dependency injection,dependencies,di,async,asyncio,application
|
|
6
6
|
Author: Anton Ruhlov
|
|
@@ -37,7 +37,7 @@ Description-Content-Type: text/markdown
|
|
|
37
37
|
|
|
38
38
|
<div style="text-align: center;">
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Simple Dependency Injection library that uses Python type annotations.
|
|
41
41
|
|
|
42
42
|
[](https://github.com/antonrh/anydi/actions/workflows/ci.yml)
|
|
43
43
|
[](https://codecov.io/gh/antonrh/anydi)
|
|
@@ -53,21 +53,21 @@ http://anydi.readthedocs.io/
|
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
|
-
`AnyDI` is a
|
|
56
|
+
`AnyDI` is a simple Dependency Injection library for Python 3.10+. It works with sync and async applications and uses type annotations ([PEP 484](https://peps.python.org/pep-0484/)).
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
Main features:
|
|
59
59
|
|
|
60
|
-
* **Type-safe**:
|
|
61
|
-
* **Async
|
|
62
|
-
* **
|
|
63
|
-
* **Simple**:
|
|
64
|
-
* **Fast**:
|
|
65
|
-
* **Named**: `Annotated[...]`
|
|
66
|
-
* **
|
|
67
|
-
* **Modular**:
|
|
68
|
-
* **
|
|
69
|
-
* **
|
|
70
|
-
* **
|
|
60
|
+
* **Type-safe**: Uses type hints for dependency resolution.
|
|
61
|
+
* **Async support**: Works with both sync and async code.
|
|
62
|
+
* **Scopes**: Provides singleton, transient, and request scopes. Supports custom scope definitions.
|
|
63
|
+
* **Simple**: Minimal boilerplate with straightforward API.
|
|
64
|
+
* **Fast**: Low overhead dependency resolution.
|
|
65
|
+
* **Named providers**: Use `Annotated[...]` for multiple providers per type.
|
|
66
|
+
* **Resource management**: Context manager protocol support for lifecycle management.
|
|
67
|
+
* **Modular**: Container and module composition for large applications.
|
|
68
|
+
* **Auto-scan**: Automatic discovery of injectable callables.
|
|
69
|
+
* **Framework integrations**: Extensions for popular frameworks.
|
|
70
|
+
* **Testing**: Provider override mechanism for test isolation.
|
|
71
71
|
|
|
72
72
|
## Installation
|
|
73
73
|
|
|
@@ -266,23 +266,23 @@ urlpatterns = [
|
|
|
266
266
|
]
|
|
267
267
|
```
|
|
268
268
|
|
|
269
|
-
##
|
|
269
|
+
## Learn More
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
Want to know more? Here are helpful resources:
|
|
272
272
|
|
|
273
273
|
**Core Documentation:**
|
|
274
|
-
- [Core Concepts](https://anydi.readthedocs.io/en/latest/concepts/) -
|
|
275
|
-
- [Providers](https://anydi.readthedocs.io/en/latest/usage/providers/) -
|
|
276
|
-
- [Scopes](https://anydi.readthedocs.io/en/latest/usage/scopes/) -
|
|
277
|
-
- [Dependency Injection](https://anydi.readthedocs.io/en/latest/usage/injection/) -
|
|
278
|
-
- [Testing](https://anydi.readthedocs.io/en/latest/usage/testing/) -
|
|
274
|
+
- [Core Concepts](https://anydi.readthedocs.io/en/latest/concepts/) - Learn about containers, providers, scopes, and dependency injection
|
|
275
|
+
- [Providers](https://anydi.readthedocs.io/en/latest/usage/providers/) - How to register providers and manage resources
|
|
276
|
+
- [Scopes](https://anydi.readthedocs.io/en/latest/usage/scopes/) - How to use built-in and custom scopes
|
|
277
|
+
- [Dependency Injection](https://anydi.readthedocs.io/en/latest/usage/injection/) - Different ways to inject dependencies
|
|
278
|
+
- [Testing](https://anydi.readthedocs.io/en/latest/usage/testing/) - How to test your code with provider overrides
|
|
279
279
|
|
|
280
280
|
**Framework Integrations:**
|
|
281
|
-
- [FastAPI](https://anydi.readthedocs.io/en/latest/extensions/fastapi/) -
|
|
282
|
-
- [Django](https://anydi.readthedocs.io/en/latest/extensions/django/) -
|
|
283
|
-
- [FastStream](https://anydi.readthedocs.io/en/latest/extensions/faststream/) -
|
|
284
|
-
- [Typer](https://anydi.readthedocs.io/en/latest/extensions/typer/) -
|
|
285
|
-
- [Pydantic Settings](https://anydi.readthedocs.io/en/latest/extensions/pydantic_settings/) -
|
|
281
|
+
- [FastAPI](https://anydi.readthedocs.io/en/latest/extensions/fastapi/) - How to use with FastAPI
|
|
282
|
+
- [Django](https://anydi.readthedocs.io/en/latest/extensions/django/) - How to use with Django and Django Ninja
|
|
283
|
+
- [FastStream](https://anydi.readthedocs.io/en/latest/extensions/faststream/) - How to use with message brokers
|
|
284
|
+
- [Typer](https://anydi.readthedocs.io/en/latest/extensions/typer/) - How to use in CLI applications
|
|
285
|
+
- [Pydantic Settings](https://anydi.readthedocs.io/en/latest/extensions/pydantic_settings/) - How to manage configuration
|
|
286
286
|
|
|
287
287
|
**Full Documentation:**
|
|
288
|
-
- [Read the Docs](https://anydi.readthedocs.io/) -
|
|
288
|
+
- [Read the Docs](https://anydi.readthedocs.io/) - All documentation with examples and guides
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<div style="text-align: center;">
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Simple Dependency Injection library that uses Python type annotations.
|
|
6
6
|
|
|
7
7
|
[](https://github.com/antonrh/anydi/actions/workflows/ci.yml)
|
|
8
8
|
[](https://codecov.io/gh/antonrh/anydi)
|
|
@@ -18,21 +18,21 @@ http://anydi.readthedocs.io/
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
`AnyDI` is a
|
|
21
|
+
`AnyDI` is a simple Dependency Injection library for Python 3.10+. It works with sync and async applications and uses type annotations ([PEP 484](https://peps.python.org/pep-0484/)).
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Main features:
|
|
24
24
|
|
|
25
|
-
* **Type-safe**:
|
|
26
|
-
* **Async
|
|
27
|
-
* **
|
|
28
|
-
* **Simple**:
|
|
29
|
-
* **Fast**:
|
|
30
|
-
* **Named**: `Annotated[...]`
|
|
31
|
-
* **
|
|
32
|
-
* **Modular**:
|
|
33
|
-
* **
|
|
34
|
-
* **
|
|
35
|
-
* **
|
|
25
|
+
* **Type-safe**: Uses type hints for dependency resolution.
|
|
26
|
+
* **Async support**: Works with both sync and async code.
|
|
27
|
+
* **Scopes**: Provides singleton, transient, and request scopes. Supports custom scope definitions.
|
|
28
|
+
* **Simple**: Minimal boilerplate with straightforward API.
|
|
29
|
+
* **Fast**: Low overhead dependency resolution.
|
|
30
|
+
* **Named providers**: Use `Annotated[...]` for multiple providers per type.
|
|
31
|
+
* **Resource management**: Context manager protocol support for lifecycle management.
|
|
32
|
+
* **Modular**: Container and module composition for large applications.
|
|
33
|
+
* **Auto-scan**: Automatic discovery of injectable callables.
|
|
34
|
+
* **Framework integrations**: Extensions for popular frameworks.
|
|
35
|
+
* **Testing**: Provider override mechanism for test isolation.
|
|
36
36
|
|
|
37
37
|
## Installation
|
|
38
38
|
|
|
@@ -231,23 +231,23 @@ urlpatterns = [
|
|
|
231
231
|
]
|
|
232
232
|
```
|
|
233
233
|
|
|
234
|
-
##
|
|
234
|
+
## Learn More
|
|
235
235
|
|
|
236
|
-
|
|
236
|
+
Want to know more? Here are helpful resources:
|
|
237
237
|
|
|
238
238
|
**Core Documentation:**
|
|
239
|
-
- [Core Concepts](https://anydi.readthedocs.io/en/latest/concepts/) -
|
|
240
|
-
- [Providers](https://anydi.readthedocs.io/en/latest/usage/providers/) -
|
|
241
|
-
- [Scopes](https://anydi.readthedocs.io/en/latest/usage/scopes/) -
|
|
242
|
-
- [Dependency Injection](https://anydi.readthedocs.io/en/latest/usage/injection/) -
|
|
243
|
-
- [Testing](https://anydi.readthedocs.io/en/latest/usage/testing/) -
|
|
239
|
+
- [Core Concepts](https://anydi.readthedocs.io/en/latest/concepts/) - Learn about containers, providers, scopes, and dependency injection
|
|
240
|
+
- [Providers](https://anydi.readthedocs.io/en/latest/usage/providers/) - How to register providers and manage resources
|
|
241
|
+
- [Scopes](https://anydi.readthedocs.io/en/latest/usage/scopes/) - How to use built-in and custom scopes
|
|
242
|
+
- [Dependency Injection](https://anydi.readthedocs.io/en/latest/usage/injection/) - Different ways to inject dependencies
|
|
243
|
+
- [Testing](https://anydi.readthedocs.io/en/latest/usage/testing/) - How to test your code with provider overrides
|
|
244
244
|
|
|
245
245
|
**Framework Integrations:**
|
|
246
|
-
- [FastAPI](https://anydi.readthedocs.io/en/latest/extensions/fastapi/) -
|
|
247
|
-
- [Django](https://anydi.readthedocs.io/en/latest/extensions/django/) -
|
|
248
|
-
- [FastStream](https://anydi.readthedocs.io/en/latest/extensions/faststream/) -
|
|
249
|
-
- [Typer](https://anydi.readthedocs.io/en/latest/extensions/typer/) -
|
|
250
|
-
- [Pydantic Settings](https://anydi.readthedocs.io/en/latest/extensions/pydantic_settings/) -
|
|
246
|
+
- [FastAPI](https://anydi.readthedocs.io/en/latest/extensions/fastapi/) - How to use with FastAPI
|
|
247
|
+
- [Django](https://anydi.readthedocs.io/en/latest/extensions/django/) - How to use with Django and Django Ninja
|
|
248
|
+
- [FastStream](https://anydi.readthedocs.io/en/latest/extensions/faststream/) - How to use with message brokers
|
|
249
|
+
- [Typer](https://anydi.readthedocs.io/en/latest/extensions/typer/) - How to use in CLI applications
|
|
250
|
+
- [Pydantic Settings](https://anydi.readthedocs.io/en/latest/extensions/pydantic_settings/) - How to manage configuration
|
|
251
251
|
|
|
252
252
|
**Full Documentation:**
|
|
253
|
-
- [Read the Docs](https://anydi.readthedocs.io/) -
|
|
253
|
+
- [Read the Docs](https://anydi.readthedocs.io/) - All documentation with examples and guides
|
|
@@ -62,6 +62,13 @@ class Resolver:
|
|
|
62
62
|
def add_unresolved(self, interface: Any) -> None:
|
|
63
63
|
self._unresolved_interfaces.add(interface)
|
|
64
64
|
|
|
65
|
+
def clear_caches(self) -> None:
|
|
66
|
+
"""Clear all cached resolvers."""
|
|
67
|
+
self._cache.clear()
|
|
68
|
+
self._async_cache.clear()
|
|
69
|
+
self._override_cache.clear()
|
|
70
|
+
self._async_override_cache.clear()
|
|
71
|
+
|
|
65
72
|
def get_cached(self, interface: Any, *, is_async: bool) -> CompiledResolver | None:
|
|
66
73
|
"""Get cached resolver if it exists."""
|
|
67
74
|
if self.override_mode:
|
|
@@ -83,9 +90,14 @@ class Resolver:
|
|
|
83
90
|
return cache[provider.interface]
|
|
84
91
|
|
|
85
92
|
# Recursively compile dependencies first
|
|
86
|
-
for
|
|
87
|
-
if
|
|
88
|
-
|
|
93
|
+
for param in provider.parameters:
|
|
94
|
+
if param.provider is not None:
|
|
95
|
+
# Look up the current provider to handle overrides
|
|
96
|
+
current_provider = self._container.providers.get(param.annotation)
|
|
97
|
+
if current_provider is not None:
|
|
98
|
+
self.compile(current_provider, is_async=is_async)
|
|
99
|
+
else:
|
|
100
|
+
self.compile(param.provider, is_async=is_async)
|
|
89
101
|
|
|
90
102
|
# Compile the resolver and creator functions
|
|
91
103
|
compiled = self._compile_resolver(
|
|
@@ -155,23 +167,29 @@ class Resolver:
|
|
|
155
167
|
else (self._async_cache if is_async else self._cache)
|
|
156
168
|
)
|
|
157
169
|
|
|
158
|
-
for idx,
|
|
159
|
-
param_annotations[idx] =
|
|
160
|
-
param_defaults[idx] =
|
|
161
|
-
param_has_default[idx] =
|
|
162
|
-
param_names[idx] =
|
|
163
|
-
param_shared_scopes[idx] =
|
|
164
|
-
|
|
165
|
-
if
|
|
166
|
-
|
|
170
|
+
for idx, param in enumerate(provider.parameters):
|
|
171
|
+
param_annotations[idx] = param.annotation
|
|
172
|
+
param_defaults[idx] = param.default
|
|
173
|
+
param_has_default[idx] = param.has_default
|
|
174
|
+
param_names[idx] = param.name
|
|
175
|
+
param_shared_scopes[idx] = param.shared_scope
|
|
176
|
+
|
|
177
|
+
if param.provider is not None:
|
|
178
|
+
# Look up the current provider from the container to handle overrides
|
|
179
|
+
current_provider = self._container.providers.get(param.annotation)
|
|
180
|
+
if current_provider is not None:
|
|
181
|
+
compiled = cache.get(current_provider.interface)
|
|
182
|
+
else:
|
|
183
|
+
# Fallback to the original provider if not in container
|
|
184
|
+
compiled = cache.get(param.provider.interface)
|
|
167
185
|
if compiled is None:
|
|
168
|
-
compiled = self.compile(
|
|
169
|
-
cache[
|
|
186
|
+
compiled = self.compile(param.provider, is_async=is_async)
|
|
187
|
+
cache[param.provider.interface] = compiled
|
|
170
188
|
param_resolvers[idx] = compiled.resolve
|
|
171
189
|
|
|
172
190
|
unresolved_message = (
|
|
173
|
-
f"You are attempting to get the parameter `{
|
|
174
|
-
f"annotation `{type_repr(
|
|
191
|
+
f"You are attempting to get the parameter `{param.name}` with the "
|
|
192
|
+
f"annotation `{type_repr(param.annotation)}` as a dependency into "
|
|
175
193
|
f"`{type_repr(provider.call)}` which is not registered or set in the "
|
|
176
194
|
"scoped context."
|
|
177
195
|
)
|
|
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
|