anydi 0.41.0__tar.gz → 0.43.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.
Files changed (100) hide show
  1. {anydi-0.41.0 → anydi-0.43.0}/.github/workflows/ci.yml +3 -2
  2. {anydi-0.41.0 → anydi-0.43.0}/Makefile +3 -3
  3. {anydi-0.41.0 → anydi-0.43.0}/PKG-INFO +2 -2
  4. anydi-0.43.0/anydi/__init__.py +26 -0
  5. anydi-0.43.0/anydi/_async.py +50 -0
  6. {anydi-0.41.0 → anydi-0.43.0}/anydi/_container.py +65 -380
  7. {anydi-0.41.0 → anydi-0.43.0}/anydi/_context.py +2 -2
  8. anydi-0.43.0/anydi/_decorators.py +122 -0
  9. anydi-0.43.0/anydi/_module.py +77 -0
  10. anydi-0.43.0/anydi/_provider.py +81 -0
  11. anydi-0.43.0/anydi/_scan.py +110 -0
  12. anydi-0.43.0/anydi/_scope.py +9 -0
  13. anydi-0.41.0/anydi/_utils.py → anydi-0.43.0/anydi/_typing.py +49 -69
  14. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/_utils.py +4 -4
  15. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/django/_utils.py +2 -42
  16. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/django/apps.py +0 -3
  17. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/django/ninja/__init__.py +3 -3
  18. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/django/ninja/_operation.py +1 -1
  19. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/django/ninja/_signature.py +1 -1
  20. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/fastapi.py +2 -2
  21. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/faststream.py +2 -2
  22. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/pytest_plugin.py +1 -1
  23. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/starlette/middleware.py +1 -1
  24. anydi-0.43.0/anydi/testing.py +172 -0
  25. {anydi-0.41.0 → anydi-0.43.0}/docs/usage.md +24 -8
  26. {anydi-0.41.0 → anydi-0.43.0}/pyproject.toml +6 -15
  27. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/fastapi/app.py +2 -2
  28. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/fastapi/test_routes.py +7 -3
  29. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/starlette/app.py +3 -2
  30. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/starlette/test_routes.py +7 -3
  31. {anydi-0.41.0 → anydi-0.43.0}/tests/fixtures.py +2 -1
  32. anydi-0.43.0/tests/scan_app/b/__init__.py +0 -0
  33. {anydi-0.41.0 → anydi-0.43.0}/tests/test_container.py +38 -434
  34. anydi-0.43.0/tests/test_decorators.py +76 -0
  35. anydi-0.43.0/tests/test_module.py +74 -0
  36. anydi-0.43.0/tests/test_scan.py +68 -0
  37. anydi-0.43.0/tests/test_testing.py +222 -0
  38. {anydi-0.41.0 → anydi-0.43.0}/tests/test_utils.py +3 -13
  39. {anydi-0.41.0 → anydi-0.43.0}/uv.lock +19 -138
  40. anydi-0.41.0/anydi/__init__.py +0 -31
  41. anydi-0.41.0/anydi/_types.py +0 -145
  42. {anydi-0.41.0 → anydi-0.43.0}/.editorconfig +0 -0
  43. {anydi-0.41.0 → anydi-0.43.0}/.gitignore +0 -0
  44. {anydi-0.41.0 → anydi-0.43.0}/.readthedocs.yaml +0 -0
  45. {anydi-0.41.0 → anydi-0.43.0}/LICENSE +0 -0
  46. {anydi-0.41.0 → anydi-0.43.0}/README.md +0 -0
  47. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/__init__.py +0 -0
  48. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/django/__init__.py +0 -0
  49. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/django/_container.py +0 -0
  50. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/django/_settings.py +0 -0
  51. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/django/middleware.py +0 -0
  52. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/pydantic_settings.py +0 -0
  53. {anydi-0.41.0 → anydi-0.43.0}/anydi/ext/starlette/__init__.py +0 -0
  54. {anydi-0.41.0 → anydi-0.43.0}/anydi/py.typed +0 -0
  55. {anydi-0.41.0 → anydi-0.43.0}/docs/examples/basic.md +0 -0
  56. {anydi-0.41.0 → anydi-0.43.0}/docs/extensions/django.md +0 -0
  57. {anydi-0.41.0 → anydi-0.43.0}/docs/extensions/fastapi.md +0 -0
  58. {anydi-0.41.0 → anydi-0.43.0}/docs/extensions/faststream.md +0 -0
  59. {anydi-0.41.0 → anydi-0.43.0}/docs/extensions/pydantic_settings.md +0 -0
  60. {anydi-0.41.0 → anydi-0.43.0}/docs/index.md +0 -0
  61. {anydi-0.41.0 → anydi-0.43.0}/mkdocs.yml +0 -0
  62. /anydi-0.41.0/tests/__init__.py → /anydi-0.43.0/override.py +0 -0
  63. {anydi-0.41.0/tests/ext → anydi-0.43.0/tests}/__init__.py +0 -0
  64. {anydi-0.41.0 → anydi-0.43.0}/tests/conftest.py +0 -0
  65. {anydi-0.41.0/tests/ext/django → anydi-0.43.0/tests/ext}/__init__.py +0 -0
  66. {anydi-0.41.0/tests/ext/django/api → anydi-0.43.0/tests/ext/django}/__init__.py +0 -0
  67. {anydi-0.41.0/tests/ext/django/scan → anydi-0.43.0/tests/ext/django/api}/__init__.py +0 -0
  68. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/api/router.py +0 -0
  69. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/api/test_router.py +0 -0
  70. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/api/urls.py +0 -0
  71. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/conftest.py +0 -0
  72. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/container.py +0 -0
  73. {anydi-0.41.0/tests/ext/fastapi → anydi-0.43.0/tests/ext/django/scan}/__init__.py +0 -0
  74. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/services.py +0 -0
  75. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/settings.py +0 -0
  76. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/test_views.py +0 -0
  77. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/urls.py +0 -0
  78. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/django/views.py +0 -0
  79. {anydi-0.41.0/tests/ext/faststream → anydi-0.43.0/tests/ext/fastapi}/__init__.py +0 -0
  80. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/fastapi/conftest.py +0 -0
  81. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/fastapi/test_auto_register.py +0 -0
  82. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/fastapi/test_ext.py +0 -0
  83. {anydi-0.41.0/tests/ext/starlette → anydi-0.43.0/tests/ext/faststream}/__init__.py +0 -0
  84. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/faststream/test_ext.py +0 -0
  85. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/faststream/test_subscribers.py +0 -0
  86. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/fixtures.py +0 -0
  87. {anydi-0.41.0/tests/scan_app/a → anydi-0.43.0/tests/ext/starlette}/__init__.py +0 -0
  88. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/starlette/conftest.py +0 -0
  89. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/test_pydantic.py +0 -0
  90. {anydi-0.41.0 → anydi-0.43.0}/tests/ext/test_pytest_plugin.py +0 -0
  91. {anydi-0.41.0 → anydi-0.43.0}/tests/scan_app/__init__.py +0 -0
  92. {anydi-0.41.0/tests/scan_app/a/a2 → anydi-0.43.0/tests/scan_app/a}/__init__.py +0 -0
  93. {anydi-0.41.0 → anydi-0.43.0}/tests/scan_app/a/a1/__init__.py +0 -0
  94. {anydi-0.41.0 → anydi-0.43.0}/tests/scan_app/a/a1/handlers.py +0 -0
  95. {anydi-0.41.0/tests/scan_app/a/a2/a21 → anydi-0.43.0/tests/scan_app/a/a2}/__init__.py +0 -0
  96. {anydi-0.41.0/tests/scan_app/a/a3 → anydi-0.43.0/tests/scan_app/a/a2/a21}/__init__.py +0 -0
  97. {anydi-0.41.0 → anydi-0.43.0}/tests/scan_app/a/a2/a21/handlers.py +0 -0
  98. {anydi-0.41.0/tests/scan_app/b → anydi-0.43.0/tests/scan_app/a/a3}/__init__.py +0 -0
  99. {anydi-0.41.0 → anydi-0.43.0}/tests/scan_app/a/a3/handlers.py +0 -0
  100. {anydi-0.41.0 → anydi-0.43.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 mypy anydi tests
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.9'
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 mypy anydi tests
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.41.0
3
+ Version: 0.43.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.13.2
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()