anydi 0.41.0__tar.gz → 0.42.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.41.0 → anydi-0.42.0}/.github/workflows/ci.yml +3 -2
- {anydi-0.41.0 → anydi-0.42.0}/Makefile +3 -3
- {anydi-0.41.0 → anydi-0.42.0}/PKG-INFO +2 -2
- anydi-0.42.0/anydi/__init__.py +26 -0
- anydi-0.42.0/anydi/_async.py +50 -0
- {anydi-0.41.0 → anydi-0.42.0}/anydi/_container.py +59 -371
- {anydi-0.41.0 → anydi-0.42.0}/anydi/_context.py +2 -2
- anydi-0.42.0/anydi/_decorators.py +80 -0
- anydi-0.42.0/anydi/_module.py +76 -0
- anydi-0.42.0/anydi/_provider.py +81 -0
- anydi-0.42.0/anydi/_scan.py +110 -0
- anydi-0.42.0/anydi/_scope.py +9 -0
- anydi-0.41.0/anydi/_utils.py → anydi-0.42.0/anydi/_typing.py +49 -69
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/_utils.py +4 -4
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/django/_utils.py +3 -3
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/django/apps.py +0 -3
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/django/ninja/__init__.py +3 -3
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/django/ninja/_operation.py +1 -1
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/django/ninja/_signature.py +1 -1
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/fastapi.py +2 -2
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/faststream.py +2 -2
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/pytest_plugin.py +1 -1
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/starlette/middleware.py +1 -1
- anydi-0.42.0/anydi/testing.py +172 -0
- {anydi-0.41.0 → anydi-0.42.0}/docs/usage.md +24 -8
- {anydi-0.41.0 → anydi-0.42.0}/pyproject.toml +5 -15
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/fastapi/app.py +2 -2
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/fastapi/test_routes.py +7 -3
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/starlette/app.py +3 -2
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/starlette/test_routes.py +7 -3
- {anydi-0.41.0 → anydi-0.42.0}/tests/fixtures.py +2 -1
- anydi-0.42.0/tests/scan_app/b/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/test_container.py +8 -388
- anydi-0.42.0/tests/test_decorators.py +66 -0
- anydi-0.42.0/tests/test_module.py +74 -0
- anydi-0.42.0/tests/test_scan.py +41 -0
- anydi-0.42.0/tests/test_testing.py +224 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/test_utils.py +3 -13
- {anydi-0.41.0 → anydi-0.42.0}/uv.lock +5 -138
- anydi-0.41.0/anydi/__init__.py +0 -31
- anydi-0.41.0/anydi/_types.py +0 -145
- {anydi-0.41.0 → anydi-0.42.0}/.editorconfig +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/.gitignore +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/.readthedocs.yaml +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/LICENSE +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/README.md +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/django/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/django/_container.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/django/_settings.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/django/middleware.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/pydantic_settings.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/anydi/ext/starlette/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/anydi/py.typed +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/docs/examples/basic.md +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/docs/extensions/django.md +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/docs/extensions/fastapi.md +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/docs/extensions/faststream.md +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/docs/extensions/pydantic_settings.md +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/docs/index.md +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/mkdocs.yml +0 -0
- /anydi-0.41.0/tests/__init__.py → /anydi-0.42.0/override.py +0 -0
- {anydi-0.41.0/tests/ext → anydi-0.42.0/tests}/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/conftest.py +0 -0
- {anydi-0.41.0/tests/ext/django → anydi-0.42.0/tests/ext}/__init__.py +0 -0
- {anydi-0.41.0/tests/ext/django/api → anydi-0.42.0/tests/ext/django}/__init__.py +0 -0
- {anydi-0.41.0/tests/ext/django/scan → anydi-0.42.0/tests/ext/django/api}/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/api/router.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/api/test_router.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/api/urls.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/conftest.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/container.py +0 -0
- {anydi-0.41.0/tests/ext/fastapi → anydi-0.42.0/tests/ext/django/scan}/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/services.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/settings.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/test_views.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/urls.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/django/views.py +0 -0
- {anydi-0.41.0/tests/ext/faststream → anydi-0.42.0/tests/ext/fastapi}/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/fastapi/conftest.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/fastapi/test_auto_register.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/fastapi/test_ext.py +0 -0
- {anydi-0.41.0/tests/ext/starlette → anydi-0.42.0/tests/ext/faststream}/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/faststream/test_ext.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/faststream/test_subscribers.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/fixtures.py +0 -0
- {anydi-0.41.0/tests/scan_app/a → anydi-0.42.0/tests/ext/starlette}/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/starlette/conftest.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/test_pydantic.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/ext/test_pytest_plugin.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/scan_app/__init__.py +0 -0
- {anydi-0.41.0/tests/scan_app/a/a2 → anydi-0.42.0/tests/scan_app/a}/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/scan_app/a/a1/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/scan_app/a/a1/handlers.py +0 -0
- {anydi-0.41.0/tests/scan_app/a/a2/a21 → anydi-0.42.0/tests/scan_app/a/a2}/__init__.py +0 -0
- {anydi-0.41.0/tests/scan_app/a/a3 → anydi-0.42.0/tests/scan_app/a/a2/a21}/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/scan_app/a/a2/a21/handlers.py +0 -0
- {anydi-0.41.0/tests/scan_app/b → anydi-0.42.0/tests/scan_app/a/a3}/__init__.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/scan_app/a/a3/handlers.py +0 -0
- {anydi-0.41.0 → anydi-0.42.0}/tests/scan_app/b/handlers.py +0 -0
|
@@ -18,13 +18,14 @@ jobs:
|
|
|
18
18
|
- name: Install uv
|
|
19
19
|
uses: astral-sh/setup-uv@v5
|
|
20
20
|
with:
|
|
21
|
+
python-version: '3.10'
|
|
21
22
|
enable-cache: true
|
|
22
23
|
- name: Set up Python
|
|
23
24
|
run: uv python install
|
|
24
25
|
- name: Install dependencies
|
|
25
26
|
run: uv sync --all-extras --dev
|
|
26
27
|
- name: Static type checking
|
|
27
|
-
run: uv run
|
|
28
|
+
run: uv run pyright
|
|
28
29
|
- name: Code formatting
|
|
29
30
|
run: uv run ruff check && uv run ruff format --check
|
|
30
31
|
|
|
@@ -57,4 +58,4 @@ jobs:
|
|
|
57
58
|
uv run pytest -vv tests/ext/test_pytest_plugin.py --cov=anydi --cov-append --cov-report=xml
|
|
58
59
|
- name: Upload coverage to Codecov
|
|
59
60
|
uses: codecov/codecov-action@v3
|
|
60
|
-
if: matrix.python == '3.
|
|
61
|
+
if: matrix.python == '3.10'
|
|
@@ -5,13 +5,13 @@ help:
|
|
|
5
5
|
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
|
6
6
|
|
|
7
7
|
lint: ## Run code linters
|
|
8
|
-
uv run
|
|
9
|
-
uv run ruff check
|
|
8
|
+
uv run pyright
|
|
10
9
|
uv run ruff format --check
|
|
10
|
+
uv run ruff check
|
|
11
11
|
|
|
12
12
|
fmt: ## Run code formatters
|
|
13
|
-
uv run ruff check --fix
|
|
14
13
|
uv run ruff format
|
|
14
|
+
uv run ruff check --fix
|
|
15
15
|
|
|
16
16
|
test: ## Run unit tests
|
|
17
17
|
uv run pytest -vv tests --ignore=tests/ext/test_pytest_plugin.py --cov=anydi -p no:anydi -p no:testanydi
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: anydi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.42.0
|
|
4
4
|
Summary: Dependency Injection library
|
|
5
5
|
Project-URL: Repository, https://github.com/antonrh/anydi
|
|
6
6
|
Author-email: Anton Ruhlov <antonruhlov@gmail.com>
|
|
@@ -29,7 +29,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
29
29
|
Classifier: Typing :: Typed
|
|
30
30
|
Requires-Python: ~=3.9
|
|
31
31
|
Requires-Dist: anyio>=3.7.1
|
|
32
|
-
Requires-Dist: typing-extensions<5,>=4.
|
|
32
|
+
Requires-Dist: typing-extensions<5,>=4.14.0
|
|
33
33
|
Requires-Dist: wrapt<2,>=1.17.0
|
|
34
34
|
Description-Content-Type: text/markdown
|
|
35
35
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""AnyDI public objects and functions."""
|
|
2
|
+
|
|
3
|
+
from ._container import Container
|
|
4
|
+
from ._decorators import injectable, provided, provider, request, singleton, transient
|
|
5
|
+
from ._module import Module
|
|
6
|
+
from ._provider import ProviderDef as Provider
|
|
7
|
+
from ._scope import Scope
|
|
8
|
+
from ._typing import Marker
|
|
9
|
+
|
|
10
|
+
# Alias for dependency auto marker
|
|
11
|
+
auto = Marker()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"Container",
|
|
16
|
+
"Module",
|
|
17
|
+
"Provider",
|
|
18
|
+
"Scope",
|
|
19
|
+
"auto",
|
|
20
|
+
"injectable",
|
|
21
|
+
"provider",
|
|
22
|
+
"request",
|
|
23
|
+
"singleton",
|
|
24
|
+
"transient",
|
|
25
|
+
"provided",
|
|
26
|
+
]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
from types import TracebackType
|
|
3
|
+
from typing import Any, Callable, TypeVar
|
|
4
|
+
|
|
5
|
+
import anyio.to_thread
|
|
6
|
+
from typing_extensions import ParamSpec, Self
|
|
7
|
+
|
|
8
|
+
T = TypeVar("T")
|
|
9
|
+
P = ParamSpec("P")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def run_sync(func: Callable[P, T], /, *args: P.args, **kwargs: P.kwargs) -> T:
|
|
13
|
+
"""Runs the given function asynchronously using the `anyio` library."""
|
|
14
|
+
return await anyio.to_thread.run_sync(functools.partial(func, *args, **kwargs))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AsyncRLock:
|
|
18
|
+
def __init__(self) -> None:
|
|
19
|
+
self._lock = anyio.Lock()
|
|
20
|
+
self._owner: anyio.TaskInfo | None = None
|
|
21
|
+
self._count = 0
|
|
22
|
+
|
|
23
|
+
async def acquire(self) -> None:
|
|
24
|
+
current_task = anyio.get_current_task()
|
|
25
|
+
if self._owner == current_task:
|
|
26
|
+
self._count += 1
|
|
27
|
+
else:
|
|
28
|
+
await self._lock.acquire()
|
|
29
|
+
self._owner = current_task
|
|
30
|
+
self._count = 1
|
|
31
|
+
|
|
32
|
+
def release(self) -> None:
|
|
33
|
+
if self._owner != anyio.get_current_task():
|
|
34
|
+
raise RuntimeError("Lock can only be released by the owner")
|
|
35
|
+
self._count -= 1
|
|
36
|
+
if self._count == 0:
|
|
37
|
+
self._owner = None
|
|
38
|
+
self._lock.release()
|
|
39
|
+
|
|
40
|
+
async def __aenter__(self) -> Self:
|
|
41
|
+
await self.acquire()
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
async def __aexit__(
|
|
45
|
+
self,
|
|
46
|
+
exc_type: type[BaseException] | None,
|
|
47
|
+
exc_val: BaseException | None,
|
|
48
|
+
exc_tb: TracebackType | None,
|
|
49
|
+
) -> Any:
|
|
50
|
+
self.release()
|