anydi 0.43.0__tar.gz → 0.44.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 (98) hide show
  1. {anydi-0.43.0 → anydi-0.44.0}/PKG-INFO +1 -1
  2. {anydi-0.43.0 → anydi-0.44.0}/anydi/_container.py +12 -31
  3. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/_utils.py +1 -11
  4. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/django/_settings.py +0 -2
  5. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/django/apps.py +1 -3
  6. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/pytest_plugin.py +4 -4
  7. {anydi-0.43.0 → anydi-0.44.0}/anydi/testing.py +1 -4
  8. {anydi-0.43.0 → anydi-0.44.0}/docs/extensions/django.md +1 -2
  9. {anydi-0.43.0 → anydi-0.44.0}/docs/usage.md +4 -16
  10. {anydi-0.43.0 → anydi-0.44.0}/pyproject.toml +2 -2
  11. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/fastapi/app.py +1 -1
  12. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/fastapi/test_ext.py +2 -2
  13. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/faststream/test_ext.py +2 -2
  14. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/faststream/test_subscribers.py +1 -1
  15. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/test_pytest_plugin.py +1 -1
  16. {anydi-0.43.0 → anydi-0.44.0}/tests/test_container.py +9 -32
  17. {anydi-0.43.0 → anydi-0.44.0}/tests/test_testing.py +5 -6
  18. anydi-0.43.0/override.py +0 -0
  19. anydi-0.43.0/tests/ext/fastapi/test_auto_register.py +0 -34
  20. {anydi-0.43.0 → anydi-0.44.0}/.editorconfig +0 -0
  21. {anydi-0.43.0 → anydi-0.44.0}/.github/workflows/ci.yml +0 -0
  22. {anydi-0.43.0 → anydi-0.44.0}/.gitignore +0 -0
  23. {anydi-0.43.0 → anydi-0.44.0}/.readthedocs.yaml +0 -0
  24. {anydi-0.43.0 → anydi-0.44.0}/LICENSE +0 -0
  25. {anydi-0.43.0 → anydi-0.44.0}/Makefile +0 -0
  26. {anydi-0.43.0 → anydi-0.44.0}/README.md +0 -0
  27. {anydi-0.43.0 → anydi-0.44.0}/anydi/__init__.py +0 -0
  28. {anydi-0.43.0 → anydi-0.44.0}/anydi/_async.py +0 -0
  29. {anydi-0.43.0 → anydi-0.44.0}/anydi/_context.py +0 -0
  30. {anydi-0.43.0 → anydi-0.44.0}/anydi/_decorators.py +0 -0
  31. {anydi-0.43.0 → anydi-0.44.0}/anydi/_module.py +0 -0
  32. {anydi-0.43.0 → anydi-0.44.0}/anydi/_provider.py +0 -0
  33. {anydi-0.43.0 → anydi-0.44.0}/anydi/_scan.py +0 -0
  34. {anydi-0.43.0 → anydi-0.44.0}/anydi/_scope.py +0 -0
  35. {anydi-0.43.0 → anydi-0.44.0}/anydi/_typing.py +0 -0
  36. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/__init__.py +0 -0
  37. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/django/__init__.py +0 -0
  38. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/django/_container.py +0 -0
  39. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/django/_utils.py +0 -0
  40. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/django/middleware.py +0 -0
  41. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/django/ninja/__init__.py +0 -0
  42. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/django/ninja/_operation.py +0 -0
  43. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/django/ninja/_signature.py +0 -0
  44. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/fastapi.py +0 -0
  45. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/faststream.py +0 -0
  46. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/pydantic_settings.py +0 -0
  47. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/starlette/__init__.py +0 -0
  48. {anydi-0.43.0 → anydi-0.44.0}/anydi/ext/starlette/middleware.py +0 -0
  49. {anydi-0.43.0 → anydi-0.44.0}/anydi/py.typed +0 -0
  50. {anydi-0.43.0 → anydi-0.44.0}/docs/examples/basic.md +0 -0
  51. {anydi-0.43.0 → anydi-0.44.0}/docs/extensions/fastapi.md +0 -0
  52. {anydi-0.43.0 → anydi-0.44.0}/docs/extensions/faststream.md +0 -0
  53. {anydi-0.43.0 → anydi-0.44.0}/docs/extensions/pydantic_settings.md +0 -0
  54. {anydi-0.43.0 → anydi-0.44.0}/docs/index.md +0 -0
  55. {anydi-0.43.0 → anydi-0.44.0}/mkdocs.yml +0 -0
  56. {anydi-0.43.0 → anydi-0.44.0}/tests/__init__.py +0 -0
  57. {anydi-0.43.0 → anydi-0.44.0}/tests/conftest.py +0 -0
  58. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/__init__.py +0 -0
  59. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/__init__.py +0 -0
  60. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/api/__init__.py +0 -0
  61. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/api/router.py +0 -0
  62. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/api/test_router.py +0 -0
  63. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/api/urls.py +0 -0
  64. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/conftest.py +0 -0
  65. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/container.py +0 -0
  66. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/scan/__init__.py +0 -0
  67. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/services.py +0 -0
  68. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/settings.py +0 -0
  69. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/test_views.py +0 -0
  70. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/urls.py +0 -0
  71. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/django/views.py +0 -0
  72. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/fastapi/__init__.py +0 -0
  73. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/fastapi/conftest.py +0 -0
  74. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/fastapi/test_routes.py +0 -0
  75. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/faststream/__init__.py +0 -0
  76. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/fixtures.py +0 -0
  77. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/starlette/__init__.py +0 -0
  78. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/starlette/app.py +0 -0
  79. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/starlette/conftest.py +0 -0
  80. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/starlette/test_routes.py +0 -0
  81. {anydi-0.43.0 → anydi-0.44.0}/tests/ext/test_pydantic.py +0 -0
  82. {anydi-0.43.0 → anydi-0.44.0}/tests/fixtures.py +0 -0
  83. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/__init__.py +0 -0
  84. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/a/__init__.py +0 -0
  85. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/a/a1/__init__.py +0 -0
  86. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/a/a1/handlers.py +0 -0
  87. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/a/a2/__init__.py +0 -0
  88. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/a/a2/a21/__init__.py +0 -0
  89. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/a/a2/a21/handlers.py +0 -0
  90. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/a/a3/__init__.py +0 -0
  91. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/a/a3/handlers.py +0 -0
  92. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/b/__init__.py +0 -0
  93. {anydi-0.43.0 → anydi-0.44.0}/tests/scan_app/b/handlers.py +0 -0
  94. {anydi-0.43.0 → anydi-0.44.0}/tests/test_decorators.py +0 -0
  95. {anydi-0.43.0 → anydi-0.44.0}/tests/test_module.py +0 -0
  96. {anydi-0.43.0 → anydi-0.44.0}/tests/test_scan.py +0 -0
  97. {anydi-0.43.0 → anydi-0.44.0}/tests/test_utils.py +0 -0
  98. {anydi-0.43.0 → anydi-0.44.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anydi
3
- Version: 0.43.0
3
+ Version: 0.44.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>
@@ -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 self.strict or interface is inspect.Parameter.empty:
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
- self, parameter: inspect.Parameter, /, **defaults: Any
462
+ parameter: inspect.Parameter, /, **defaults: Any
469
463
  ) -> bool:
470
464
  has_default_in_kwargs = parameter.name in defaults if defaults else False
471
- has_non_strict_default = not self.strict and (
472
- parameter.default is not inspect.Parameter.empty
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
- try:
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.is_registered(parameter.annotation):
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 "
@@ -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
- if not container.strict and not container.is_registered(parameter.annotation):
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
@@ -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=[],
@@ -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
@@ -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 is not registered
92
- if container.strict and not container.is_registered(interface):
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 is not registered
132
- if container.strict and not container.is_registered(interface):
131
+ # Skip if the interface has no provider
132
+ if not container.has_provider_for(interface):
133
133
  continue
134
134
 
135
135
  try:
@@ -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.is_registered(interface) and self.strict:
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
  )
@@ -59,7 +59,6 @@ The `HelloService` will be automatically injected into the hello view through th
59
59
  `ANYDI` supports the following settings:
60
60
 
61
61
  * `CONTAINER_FACTORY: str | None` - Specifies the factory function used to create the container. If not provided, the default container factory will be utilized.
62
- * `STRICT_MODE: bool` - Determines the container's behavior when a dependency cannot be resolved. If set to `True`, the container will raise an exception. If `False`, it will attempt to automatically create the dependency.
63
62
  * `REGISTER_SETTINGS: bool` - If `True`, the container will register the Django settings within it.
64
63
  * `REGISTER_COMPONENTS: bool` - If `True`, the container will register Django components such as the database and cache.
65
64
  * `INJECT_URLCONF: str | Sequence[str] | None` - Specifies the URL configuration where dependencies should be injected.
@@ -148,7 +147,7 @@ from anydi import Container
148
147
 
149
148
 
150
149
  def get_container() -> Container:
151
- container = Container(strict=True)
150
+ container = Container()
152
151
  # Add custom container configuration here
153
152
  return container
154
153
  ```
@@ -145,10 +145,11 @@ assert not container.is_resolved(int)
145
145
 
146
146
  This pattern can be used while writing unit tests to ensure that each test case has a clean dependency graph.
147
147
 
148
- ## Strict Mode
148
+ ## Auto-Registration
149
149
 
150
150
 
151
- `AnyDI` operates in non-strict mode by default, meaning it doesn't require explicit registration for every type. It can dynamically resolve or auto-register dependencies, simplifying setups where manual registration for each type is impractical.
151
+ `AnyDI` doesn't require explicit registration for every type. It can dynamically resolve and auto-register dependencies,
152
+ simplifying setups where manual registration for each type is impractical.
152
153
 
153
154
  Consider a scenario with class dependencies:
154
155
 
@@ -194,19 +195,6 @@ assert container.is_resolved(Repository)
194
195
  assert container.is_resolved(Database)
195
196
  ```
196
197
 
197
- ### Enabling Strict Mode
198
-
199
- For strict checking, enable strict mode by setting `strict=True` when creating the `Container`. In strict mode, all types must be explicitly registered or have a definable provider before instantiation.
200
-
201
- ```python
202
- container = Container(strict=True)
203
-
204
- # Raises LookupError if `Service` or dependencies aren't registered.
205
- _ = container.resolve(Service)
206
- ```
207
-
208
- Here's an improved version of the documentation with some enhancements for clarity, completeness, and formatting:
209
-
210
198
  ### Automatic Resource Management
211
199
 
212
200
  When your class dependencies implement the context manager protocol by defining the `__enter__/__aenter__` and `__exit__/__aexit__` methods, these resources are automatically managed by the container for `singleton` and `request` scoped providers.
@@ -229,7 +217,7 @@ class Connection:
229
217
  self.disconnected = True
230
218
 
231
219
 
232
- container = Container(strict=False)
220
+ container = Container()
233
221
  connection = container.resolve(Connection)
234
222
 
235
223
  assert container.is_resolved(Connection)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "anydi"
3
- version = "0.43.0"
3
+ version = "0.44.0"
4
4
  description = "Dependency Injection library"
5
5
  authors = [{ name = "Anton Ruhlov", email = "antonruhlov@gmail.com" }]
6
6
  requires-python = "~=3.9"
@@ -137,7 +137,7 @@ omit = [
137
137
  ]
138
138
 
139
139
  [tool.bumpversion]
140
- current_version = "0.43.0"
140
+ current_version = "0.44.0"
141
141
  parse = """(?x)
142
142
  (?P<major>0|[1-9]\\d*)\\.
143
143
  (?P<minor>0|[1-9]\\d*)\\.
@@ -10,7 +10,7 @@ from anydi.testing import TestContainer
10
10
 
11
11
  from tests.ext.fixtures import Mail, MailService, User, UserService
12
12
 
13
- container = TestContainer(strict=True)
13
+ container = TestContainer()
14
14
 
15
15
 
16
16
  @container.provider(scope="singleton")
@@ -15,7 +15,7 @@ def test_inject_param_missing_interface() -> None:
15
15
 
16
16
 
17
17
  def test_install_without_annotation() -> None:
18
- container = Container(strict=True)
18
+ container = Container()
19
19
 
20
20
  @container.provider(scope="singleton")
21
21
  def message() -> str:
@@ -34,7 +34,7 @@ def test_install_without_annotation() -> None:
34
34
 
35
35
 
36
36
  def test_install_unknown_annotation() -> None:
37
- container = Container(strict=True)
37
+ container = Container()
38
38
 
39
39
  app = FastAPI()
40
40
 
@@ -15,7 +15,7 @@ def test_inject_param_missing_interface() -> None:
15
15
 
16
16
 
17
17
  def test_install_without_annotation() -> None:
18
- container = Container(strict=True)
18
+ container = Container()
19
19
 
20
20
  @container.provider(scope="singleton")
21
21
  def message() -> str:
@@ -34,7 +34,7 @@ def test_install_without_annotation() -> None:
34
34
 
35
35
 
36
36
  def test_install_unknown_annotation() -> None:
37
- container = Container(strict=True)
37
+ container = Container()
38
38
 
39
39
  broker = RedisBroker()
40
40
 
@@ -18,7 +18,7 @@ class UserMessage(BaseModel):
18
18
 
19
19
  @pytest.fixture(scope="session")
20
20
  def container() -> Container:
21
- container = Container(strict=True)
21
+ container = Container()
22
22
 
23
23
  @container.provider(scope="singleton")
24
24
  def provide_user_service() -> UserService:
@@ -14,7 +14,7 @@ class UnknownService:
14
14
 
15
15
  @pytest.fixture(scope="module")
16
16
  def container() -> Container:
17
- container = Container(strict=True)
17
+ container = Container()
18
18
  container.register(Service, lambda: Service(), scope="singleton")
19
19
  return container
20
20
 
@@ -1,5 +1,4 @@
1
1
  import asyncio
2
- import logging
3
2
  import sys
4
3
  import threading
5
4
  import uuid
@@ -35,12 +34,6 @@ def container() -> Container:
35
34
 
36
35
 
37
36
  class TestContainer:
38
- def test_default_properties(self) -> None:
39
- container = Container()
40
-
41
- assert not container.strict
42
- assert container.default_scope == "transient"
43
-
44
37
  def test_register_provider(self, container: Container) -> None:
45
38
  def provider_call() -> str:
46
39
  return "test"
@@ -1319,7 +1312,7 @@ class TestContainer:
1319
1312
  def __init__(self, name: str) -> None:
1320
1313
  self.name = name
1321
1314
 
1322
- container = Container(strict=False)
1315
+ container = Container()
1323
1316
 
1324
1317
  instance = container.create(Component, name="test")
1325
1318
 
@@ -1331,7 +1324,7 @@ class TestContainer:
1331
1324
  def __init__(self, name: str) -> None:
1332
1325
  self.name = name
1333
1326
 
1334
- container = Container(strict=False)
1327
+ container = Container()
1335
1328
 
1336
1329
  instance = container.create(Component, name="test")
1337
1330
 
@@ -1343,7 +1336,7 @@ class TestContainer:
1343
1336
  def __init__(self, name: str) -> None:
1344
1337
  self.name = name
1345
1338
 
1346
- container = Container(strict=False)
1339
+ container = Container()
1347
1340
 
1348
1341
  with container.request_context():
1349
1342
  instance = container.create(Component, name="test")
@@ -1355,7 +1348,7 @@ class TestContainer:
1355
1348
  class Component:
1356
1349
  pass
1357
1350
 
1358
- container = Container(strict=False)
1351
+ container = Container()
1359
1352
 
1360
1353
  with pytest.raises(TypeError, match="takes no arguments"):
1361
1354
  container.create(Component, param="test")
@@ -1366,7 +1359,7 @@ class TestContainer:
1366
1359
  def __init__(self, name: str) -> None:
1367
1360
  self.name = name
1368
1361
 
1369
- container = Container(strict=False)
1362
+ container = Container()
1370
1363
 
1371
1364
  instance = await container.acreate(Component, name="test")
1372
1365
 
@@ -1378,7 +1371,7 @@ class TestContainer:
1378
1371
  def __init__(self, name: str) -> None:
1379
1372
  self.name = name
1380
1373
 
1381
- container = Container(strict=False)
1374
+ container = Container()
1382
1375
 
1383
1376
  instance = await container.acreate(Component, name="test")
1384
1377
 
@@ -1390,7 +1383,7 @@ class TestContainer:
1390
1383
  def __init__(self, name: str) -> None:
1391
1384
  self.name = name
1392
1385
 
1393
- container = Container(strict=False)
1386
+ container = Container()
1394
1387
 
1395
1388
  with container.request_context():
1396
1389
  instance = await container.acreate(Component, name="test")
@@ -1402,7 +1395,7 @@ class TestContainer:
1402
1395
  class Component:
1403
1396
  pass
1404
1397
 
1405
- container = Container(strict=False)
1398
+ container = Container()
1406
1399
 
1407
1400
  with pytest.raises(TypeError, match="takes no arguments"):
1408
1401
  await container.acreate(Component, param="test")
@@ -1426,22 +1419,6 @@ class TestContainerInjector:
1426
1419
 
1427
1420
  assert result == "service ident = 1000"
1428
1421
 
1429
- def test_inject_auto_registered_log_message(
1430
- self, container: Container, caplog: pytest.LogCaptureFixture
1431
- ) -> None:
1432
- with caplog.at_level(logging.DEBUG, logger="anydi"):
1433
-
1434
- @container.inject
1435
- def handler(service: Service = auto) -> None:
1436
- pass
1437
-
1438
- assert caplog.messages == [
1439
- "Cannot validate the `tests.test_container.TestContainerInjector"
1440
- ".test_inject_auto_registered_log_message.<locals>.handler` parameter "
1441
- "`service` with an annotation of `tests.fixtures.Service due to "
1442
- "being in non-strict mode. It will be validated at the first call."
1443
- ]
1444
-
1445
1422
  def test_inject_missing_annotation(self, container: Container) -> None:
1446
1423
  def handler(name=auto) -> str: # type: ignore[no-untyped-def]
1447
1424
  return name # type: ignore[no-any-return]
@@ -1452,7 +1429,7 @@ class TestContainerInjector:
1452
1429
  container.inject(handler)
1453
1430
 
1454
1431
  def test_inject_unknown_dependency_using_strict_mode(self) -> None:
1455
- container = Container(strict=True)
1432
+ container = Container()
1456
1433
 
1457
1434
  def handler(message: str = auto) -> None:
1458
1435
  pass
@@ -20,7 +20,6 @@ class TestTestContainer:
20
20
  test_container = TestContainer.from_container(container)
21
21
 
22
22
  assert test_container.providers == container.providers
23
- assert test_container.strict == container.strict
24
23
  assert test_container.default_scope == container.default_scope
25
24
 
26
25
  assert test_container.resolve(str) == "Hello, world!"
@@ -41,7 +40,7 @@ class TestTestContainer:
41
40
  assert container.resolve(str) == origin_name
42
41
 
43
42
  def test_override_instance_provider_not_registered_using_strict_mode(self) -> None:
44
- container = TestContainer(strict=True)
43
+ container = TestContainer()
45
44
 
46
45
  with pytest.raises(
47
46
  LookupError, match="The provider interface `str` not registered."
@@ -92,7 +91,7 @@ class TestTestContainer:
92
91
  assert (await container.aresolve(str)) == overridden
93
92
 
94
93
  def test_override_registered_instance(self) -> None:
95
- container = TestContainer(strict=False)
94
+ container = TestContainer()
96
95
  container.register(Annotated[str, "param"], lambda: "param", scope="singleton")
97
96
 
98
97
  class UserRepo:
@@ -126,7 +125,7 @@ class TestTestContainer:
126
125
  }
127
126
 
128
127
  async def test_override_instance_async_resolved(self) -> None:
129
- container = TestContainer(strict=False)
128
+ container = TestContainer()
130
129
  container.register(Annotated[str, "param"], lambda: "param", scope="singleton")
131
130
 
132
131
  @singleton
@@ -147,7 +146,7 @@ class TestTestContainer:
147
146
  }
148
147
 
149
148
  def test_override_instance_in_strict_mode(self) -> None:
150
- container = TestContainer(strict=True)
149
+ container = TestContainer()
151
150
 
152
151
  class Settings:
153
152
  def __init__(self, name: str) -> None:
@@ -166,7 +165,7 @@ class TestTestContainer:
166
165
  assert service.ident == "test"
167
166
 
168
167
  def test_override_instance_first(self) -> None:
169
- container = TestContainer(strict=True)
168
+ container = TestContainer()
170
169
 
171
170
  @dataclass
172
171
  class Item:
anydi-0.43.0/override.py DELETED
File without changes
@@ -1,34 +0,0 @@
1
- import logging
2
- from typing import Any
3
-
4
- import pytest
5
- from fastapi import FastAPI
6
-
7
- import anydi.ext.fastapi
8
- from anydi import Container
9
- from anydi.ext.fastapi import Inject
10
-
11
- from tests.ext.fixtures import Mail, MailService
12
-
13
-
14
- def test_auto_register(caplog: pytest.LogCaptureFixture) -> None:
15
- container = Container(strict=False)
16
-
17
- app = FastAPI()
18
-
19
- @app.post("/send-mail", response_model=Mail)
20
- async def send_email(
21
- mail_service: MailService = Inject(),
22
- ) -> Any:
23
- return await mail_service.send_mail(email="test@mail.com", message="test")
24
-
25
- with caplog.at_level(logging.DEBUG, logger="anydi"):
26
- anydi.ext.fastapi.install(app, container)
27
-
28
- assert caplog.messages == [
29
- "Callable `tests.ext.fastapi.test_auto_register.test_auto_register.<locals>"
30
- ".send_email` injected parameter `mail_service` with an annotation of "
31
- "`tests.ext.fixtures.MailService` is not registered. It will be "
32
- "registered at runtime with the first call because it is running in "
33
- "non-strict mode."
34
- ]
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
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