anydi 0.29.1__tar.gz → 0.30.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 (30) hide show
  1. {anydi-0.29.1 → anydi-0.30.0}/PKG-INFO +2 -1
  2. {anydi-0.29.1 → anydi-0.30.0}/anydi/_container.py +2 -2
  3. {anydi-0.29.1 → anydi-0.30.0}/anydi/_module.py +8 -1
  4. {anydi-0.29.1 → anydi-0.30.0}/anydi/_utils.py +25 -0
  5. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/django/_utils.py +1 -1
  6. {anydi-0.29.1 → anydi-0.30.0}/pyproject.toml +3 -2
  7. {anydi-0.29.1 → anydi-0.30.0}/LICENSE +0 -0
  8. {anydi-0.29.1 → anydi-0.30.0}/README.md +0 -0
  9. {anydi-0.29.1 → anydi-0.30.0}/anydi/__init__.py +0 -0
  10. {anydi-0.29.1 → anydi-0.30.0}/anydi/_context.py +0 -0
  11. {anydi-0.29.1 → anydi-0.30.0}/anydi/_logger.py +0 -0
  12. {anydi-0.29.1 → anydi-0.30.0}/anydi/_scanner.py +0 -0
  13. {anydi-0.29.1 → anydi-0.30.0}/anydi/_types.py +0 -0
  14. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/__init__.py +0 -0
  15. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/_utils.py +0 -0
  16. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/django/__init__.py +0 -0
  17. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/django/_container.py +0 -0
  18. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/django/_settings.py +0 -0
  19. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/django/apps.py +0 -0
  20. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/django/middleware.py +0 -0
  21. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/django/ninja/__init__.py +0 -0
  22. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/django/ninja/_operation.py +0 -0
  23. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/django/ninja/_signature.py +0 -0
  24. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/fastapi.py +0 -0
  25. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/faststream.py +0 -0
  26. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/pydantic_settings.py +0 -0
  27. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/pytest_plugin.py +0 -0
  28. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/starlette/__init__.py +0 -0
  29. {anydi-0.29.1 → anydi-0.30.0}/anydi/ext/starlette/middleware.py +0 -0
  30. {anydi-0.29.1 → anydi-0.30.0}/anydi/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: anydi
3
- Version: 0.29.1
3
+ Version: 0.30.0
4
4
  Summary: Dependency Injection library
5
5
  Home-page: https://github.com/antonrh/anydi
6
6
  License: MIT
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Programming Language :: Python :: 3 :: Only
25
+ Classifier: Programming Language :: Python :: 3.13
25
26
  Classifier: Topic :: Internet
26
27
  Classifier: Topic :: Software Development
27
28
  Classifier: Topic :: Software Development :: Libraries
@@ -72,7 +72,7 @@ class Container:
72
72
  self,
73
73
  *,
74
74
  providers: Mapping[type[Any], Provider] | None = None,
75
- modules: Sequence[Module | type[Module] | Callable[[Container], None]]
75
+ modules: Sequence[Module | type[Module] | Callable[[Container], None] | str]
76
76
  | None = None,
77
77
  strict: bool = False,
78
78
  ) -> None:
@@ -410,7 +410,7 @@ class Container:
410
410
  return None
411
411
 
412
412
  def register_module(
413
- self, module: Module | type[Module] | Callable[[Container], None]
413
+ self, module: Module | type[Module] | Callable[[Container], None] | str
414
414
  ) -> None:
415
415
  """Register a module as a callable, module type, or module instance.
416
416
 
@@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Any, Callable, TypeVar
8
8
  from typing_extensions import Concatenate, NamedTuple, ParamSpec
9
9
 
10
10
  from ._types import Scope
11
+ from ._utils import import_string
11
12
 
12
13
  if TYPE_CHECKING:
13
14
  from ._container import Container
@@ -67,21 +68,27 @@ class ModuleRegistry:
67
68
  self.container = container
68
69
 
69
70
  def register(
70
- self, module: Module | type[Module] | Callable[[Container], None]
71
+ self, module: Module | type[Module] | Callable[[Container], None] | str
71
72
  ) -> None:
72
73
  """Register a module as a callable, module type, or module instance.
73
74
 
74
75
  Args:
75
76
  module: The module to register.
76
77
  """
78
+
77
79
  # Callable Module
78
80
  if inspect.isfunction(module):
79
81
  module(self.container)
80
82
  return
81
83
 
84
+ # Module path
85
+ if isinstance(module, str):
86
+ module = import_string(module)
87
+
82
88
  # Class based Module or Module type
83
89
  if inspect.isclass(module) and issubclass(module, Module):
84
90
  module = module()
91
+
85
92
  if isinstance(module, Module):
86
93
  module.configure(self.container)
87
94
  for provider_name, decorator_args in module.providers:
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import builtins
6
6
  import functools
7
+ import importlib
7
8
  import inspect
8
9
  import sys
9
10
  from typing import Any, AsyncIterator, Callable, ForwardRef, Iterator, TypeVar
@@ -129,3 +130,27 @@ async def run_async(
129
130
  "it first, or consider using `anydi[full]` instead."
130
131
  )
131
132
  return await anyio.to_thread.run_sync(functools.partial(func, *args, **kwargs))
133
+
134
+
135
+ def import_string(dotted_path: str) -> Any:
136
+ """
137
+ Import a module or a specific attribute from a module using its dotted string path.
138
+
139
+ Args:
140
+ dotted_path: The dotted path to the object to import.
141
+
142
+ Returns:
143
+ object: The imported module or attribute/class/function.
144
+
145
+ Raises:
146
+ ImportError: If the import fails.
147
+ """
148
+ try:
149
+ module_path, _, attribute_name = dotted_path.rpartition(".")
150
+ if module_path:
151
+ module = importlib.import_module(module_path)
152
+ return getattr(module, attribute_name)
153
+ else:
154
+ return importlib.import_module(attribute_name)
155
+ except (ImportError, AttributeError) as exc:
156
+ raise ImportError(f"Cannot import '{dotted_path}': {exc}") from exc
@@ -15,7 +15,7 @@ from anydi import Container
15
15
 
16
16
 
17
17
  def register_settings(
18
- container: Container, prefix: str = "django.conf.setting."
18
+ container: Container, prefix: str = "django.conf.settings."
19
19
  ) -> None:
20
20
  """Register Django settings into the container."""
21
21
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "anydi"
3
- version = "0.29.1"
3
+ version = "0.30.0"
4
4
  description = "Dependency Injection library"
5
5
  authors = ["Anton Ruhlov <antonruhlov@gmail.com>"]
6
6
  license = "MIT"
@@ -27,6 +27,7 @@ classifiers = [
27
27
  "Programming Language :: Python :: 3.10",
28
28
  "Programming Language :: Python :: 3.11",
29
29
  "Programming Language :: Python :: 3.12",
30
+ "Programming Language :: Python :: 3.13",
30
31
  "Programming Language :: Python :: 3 :: Only",
31
32
  ]
32
33
  packages = [
@@ -46,7 +47,7 @@ async = ["anyio"]
46
47
 
47
48
  [tool.poetry.group.dev.dependencies]
48
49
  mypy = "^1.11.2"
49
- ruff = "^0.6.2"
50
+ ruff = "^0.6.9"
50
51
  pytest = "^8.3.1"
51
52
  pytest-cov = "^5.0.0"
52
53
  fastapi = "^0.100.0"
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