anydi 0.45.0__py3-none-any.whl → 0.46.0__py3-none-any.whl

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/__init__.py CHANGED
@@ -5,10 +5,10 @@ from ._decorators import injectable, provided, provider, request, singleton, tra
5
5
  from ._module import Module
6
6
  from ._provider import ProviderDef as Provider
7
7
  from ._scope import Scope
8
- from ._typing import Marker
8
+ from ._typing import InjectMarker
9
9
 
10
10
  # Alias for dependency auto marker
11
- auto = Marker()
11
+ auto = InjectMarker()
12
12
 
13
13
 
14
14
  __all__ = [
anydi/_container.py CHANGED
@@ -31,8 +31,8 @@ from ._typing import (
31
31
  is_builtin_type,
32
32
  is_context_manager,
33
33
  is_event_type,
34
+ is_inject_marker,
34
35
  is_iterator_type,
35
- is_marker,
36
36
  is_none_type,
37
37
  type_repr,
38
38
  )
@@ -806,29 +806,34 @@ class Container:
806
806
  """Get the injected parameters of a callable object."""
807
807
  injected_params: dict[str, Any] = {}
808
808
  for parameter in get_typed_parameters(call):
809
- if not is_marker(parameter.default):
810
- continue
811
- self._validate_injected_parameter(call, parameter)
812
- injected_params[parameter.name] = parameter.annotation
809
+ interface, should_inject = self._validate_injected_parameter(
810
+ parameter, call=call
811
+ )
812
+ if should_inject:
813
+ injected_params[parameter.name] = interface
813
814
  return injected_params
814
815
 
815
816
  def _validate_injected_parameter(
816
- self, call: Callable[..., Any], parameter: inspect.Parameter
817
- ) -> None:
817
+ self, parameter: inspect.Parameter, *, call: Callable[..., Any]
818
+ ) -> tuple[Any, bool]:
818
819
  """Validate an injected parameter."""
819
- # TODO: temporary disable until strict is enforced
820
- return None
820
+ interface, should_inject = parameter.annotation, False
821
+ if is_inject_marker(parameter.default):
822
+ if parameter.annotation is inspect.Parameter.empty:
823
+ raise TypeError(
824
+ f"Missing `{type_repr(call)}` "
825
+ f"parameter `{parameter.name}` annotation."
826
+ )
827
+ should_inject = True
821
828
 
822
- if parameter.annotation is inspect.Parameter.empty:
823
- raise TypeError(
824
- f"Missing `{type_repr(call)}` parameter `{parameter.name}` annotation."
825
- )
829
+ return interface, should_inject
826
830
 
827
- if not self.has_provider_for(parameter.annotation):
831
+ # TODO: temporary disable until strict is enforced
832
+ if not self.has_provider_for(interface):
828
833
  raise LookupError(
829
834
  f"`{type_repr(call)}` has an unknown dependency parameter "
830
835
  f"`{parameter.name}` with an annotation of "
831
- f"`{type_repr(parameter.annotation)}`."
836
+ f"`{type_repr(interface)}`."
832
837
  )
833
838
 
834
839
  ############################
anydi/_scan.py CHANGED
@@ -9,7 +9,7 @@ from types import ModuleType
9
9
  from typing import TYPE_CHECKING, Any, Callable, Union
10
10
 
11
11
  from ._decorators import is_injectable
12
- from ._typing import get_typed_parameters, is_marker
12
+ from ._typing import get_typed_parameters, is_inject_marker
13
13
 
14
14
  if TYPE_CHECKING:
15
15
  from ._container import Container
@@ -104,7 +104,7 @@ class Scanner:
104
104
  # check for parameter markers
105
105
  if not tags:
106
106
  for param in get_typed_parameters(member):
107
- if is_marker(param.default):
107
+ if is_inject_marker(param.default):
108
108
  return True
109
109
 
110
110
  return False
anydi/_typing.py CHANGED
@@ -93,8 +93,8 @@ def get_typed_parameters(obj: Callable[..., Any]) -> list[inspect.Parameter]:
93
93
  ]
94
94
 
95
95
 
96
- class _Marker:
97
- """A marker class for marking dependencies."""
96
+ class _InjectMarker:
97
+ """A marker object for declaring injectable dependencies."""
98
98
 
99
99
  __slots__ = ()
100
100
 
@@ -102,13 +102,12 @@ class _Marker:
102
102
  return self
103
103
 
104
104
 
105
- def Marker() -> Any:
106
- return _Marker()
105
+ def InjectMarker() -> Any:
106
+ return _InjectMarker()
107
107
 
108
108
 
109
- def is_marker(obj: Any) -> bool:
110
- """Checks if an object is a marker."""
111
- return isinstance(obj, _Marker)
109
+ def is_inject_marker(obj: Any) -> bool:
110
+ return isinstance(obj, _InjectMarker)
112
111
 
113
112
 
114
113
  class Event:
anydi/ext/_utils.py CHANGED
@@ -8,13 +8,17 @@ from typing import Annotated, Any, Callable
8
8
 
9
9
  from typing_extensions import get_args, get_origin
10
10
 
11
- from anydi._container import Container
11
+ from anydi import Container
12
+ from anydi._typing import _InjectMarker
12
13
 
13
14
  logger = logging.getLogger(__name__)
14
15
 
15
16
 
16
- class HasInterface:
17
- _interface: Any = None
17
+ class HasInterface(_InjectMarker):
18
+ __slots__ = ("_interface",)
19
+
20
+ def __init__(self, interface: Any = None) -> None:
21
+ self._interface = interface
18
22
 
19
23
  @property
20
24
  def interface(self) -> Any:
@@ -65,9 +69,9 @@ def patch_call_parameter(
65
69
  """Patch a parameter to inject dependencies using AnyDI."""
66
70
  parameter = patch_annotated_parameter(parameter)
67
71
 
68
- if not isinstance(parameter.default, HasInterface):
69
- return None
70
-
71
- container._validate_injected_parameter(call, parameter) # noqa
72
-
73
- parameter.default.interface = parameter.annotation
72
+ interface, should_inject = container._validate_injected_parameter(
73
+ parameter, call=call
74
+ ) # noqa
75
+ if should_inject:
76
+ parameter.default.interface = interface
77
+ return None
@@ -11,7 +11,8 @@ from ninja.signature.details import (
11
11
  )
12
12
  from ninja.signature.utils import get_path_param_names, get_typed_signature
13
13
 
14
- from anydi._typing import is_marker # noqa
14
+ from anydi._typing import is_inject_marker # noqa
15
+ from anydi.ext.django import container
15
16
 
16
17
 
17
18
  class ViewSignature(BaseViewSignature):
@@ -45,8 +46,10 @@ class ViewSignature(BaseViewSignature):
45
46
  self.response_arg = name
46
47
  continue
47
48
 
48
- # Skip default values that are anydi dependency markers
49
- if is_marker(arg.default):
49
+ interface, should_inject = container._validate_injected_parameter(
50
+ arg, call=self.view_func
51
+ )
52
+ if should_inject:
50
53
  self.dependencies.append((name, arg.annotation))
51
54
  continue
52
55
 
anydi/ext/fastapi.py CHANGED
@@ -49,11 +49,12 @@ def get_container(request: Request) -> Container:
49
49
  return cast(Container, request.app.state.container)
50
50
 
51
51
 
52
- class Resolver(HasInterface, params.Depends):
52
+ class Resolver(params.Depends, HasInterface):
53
53
  """Parameter dependency class for injecting dependencies using AnyDI."""
54
54
 
55
55
  def __init__(self) -> None:
56
56
  super().__init__(dependency=self._dependency, use_cache=True)
57
+ HasInterface.__init__(self)
57
58
 
58
59
  async def _dependency(self, container: Container = Depends(get_container)) -> Any:
59
60
  return await container.aresolve(self.interface)
anydi/ext/faststream.py CHANGED
@@ -43,11 +43,12 @@ def get_container(broker: BrokerUsecase[Any, Any]) -> Container:
43
43
  return cast(Container, getattr(broker, "_container")) # noqa
44
44
 
45
45
 
46
- class Resolver(HasInterface, Depends):
46
+ class Resolver(Depends, HasInterface):
47
47
  """Parameter dependency class for injecting dependencies using AnyDI."""
48
48
 
49
49
  def __init__(self) -> None:
50
50
  super().__init__(dependency=self._dependency, use_cache=True, cast=True)
51
+ HasInterface.__init__(self)
51
52
 
52
53
  async def _dependency(self, context: ContextRepo) -> Any:
53
54
  container = get_container(context.get("broker"))
anydi/testing.py CHANGED
@@ -18,6 +18,8 @@ T = TypeVar("T")
18
18
 
19
19
 
20
20
  class TestContainer(Container):
21
+ __test__ = False
22
+
21
23
  def __init__(
22
24
  self,
23
25
  *,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anydi
3
- Version: 0.45.0
3
+ Version: 0.46.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>
@@ -1,19 +1,19 @@
1
- anydi/__init__.py,sha256=UH3N0LIw4ysoV0_EFgtDNioxEQxOmeytYbJnS8MXIXM,532
1
+ anydi/__init__.py,sha256=GNKdoiDe1XNdMIGvI8UP43QSLOBbMQYyFpiicLlgZxI,544
2
2
  anydi/_async.py,sha256=KhRd3RmZFcwNDzrMm8ctA1gwrg-6m_7laECTYsZdF5k,1445
3
- anydi/_container.py,sha256=pclsUVpXDPhacgdBl1_MZ9pV4AUc6a3jBVQOHLniW-4,31047
3
+ anydi/_container.py,sha256=EC06Uur6GOahFF5mhluGYX95woOnKv2Hcr7j1rs9xu8,31262
4
4
  anydi/_context.py,sha256=_Xy8cTpRskb4cxTd-Fe-5NnIZyBe1DnovkofhdeUfmw,3020
5
5
  anydi/_decorators.py,sha256=F3yBeGQSz1EsulZaEvYn3cd6FEjJRMoyA6u1QCbEwcs,2813
6
6
  anydi/_module.py,sha256=QPvP27JndZkwl-FYUZWscJm6yfkNzjwoFGURyDhb6Pc,2582
7
7
  anydi/_provider.py,sha256=ig2ecn-STmFGcpkLE5A5OM35XHtU2NsxFVrGp2CvuvM,2123
8
- anydi/_scan.py,sha256=WOdsPaoRZPYw4kBzoBXyWhkiwuxY8_UjHfa0c9QFyLc,3639
8
+ anydi/_scan.py,sha256=nOpspmceVucdwf8nUv1QVFsz2sRVWCVUb0QTH9EbWr4,3653
9
9
  anydi/_scope.py,sha256=PFHjPb2-n0vhRo9mvD_craTFfoJBzR3y-N3_0apL5Q0,258
10
- anydi/_typing.py,sha256=m7KnVenDE1E420IeYz2Ocw6dhddmSFbuBBgkOXtl9pA,3709
10
+ anydi/_typing.py,sha256=zSyE4JAnaBsJLZ3Zb3o9o02LgKePwBWzMwczdhmyG3U,3711
11
11
  anydi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- anydi/testing.py,sha256=rKKvwjSKCg4MH7wp8InzG3tgCcQtLJ9ajHXIH_nnMIw,5656
12
+ anydi/testing.py,sha256=ex9grqKpQmmJWwhIVnzq6aHaUAGLu2-7fwLyYTUuKHE,5678
13
13
  anydi/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- anydi/ext/_utils.py,sha256=QthoO0Nxv_nI-yQ9kGSi9jLLT5N71BxOgFNXwLQ5DQ0,2073
15
- anydi/ext/fastapi.py,sha256=q7q1hF5v4dpV3YM4L1CVuD20bXC7f5S7e1apAfekkG0,2448
16
- anydi/ext/faststream.py,sha256=DLZTfiGeZJCiwfmZTvVecaTlX84_jqClh6cgY2qMPJg,1910
14
+ anydi/ext/_utils.py,sha256=EjOhBtze0tqWMjpTiBCSzaOyecHCRWygMDZbj4ZyAEA,2213
15
+ anydi/ext/fastapi.py,sha256=QIC45I3sfE_cNVL27cilw7lwLEZhHPhxj0mtFdtKlIc,2484
16
+ anydi/ext/faststream.py,sha256=Ewfj9hXbCSr5x7QWoLEORmc3uPcbr7PEcCcG1wM-6XM,1946
17
17
  anydi/ext/pydantic_settings.py,sha256=8IXXLuG_OvKbvKlBkBRQUHcXgbTpgQUxeWyoMcRIUQM,1488
18
18
  anydi/ext/pytest_plugin.py,sha256=IoP6XKuGLGLd2Xlpfttc3mI4pxCm2WQLE7x_a7asbv4,4732
19
19
  anydi/ext/django/__init__.py,sha256=QI1IABCVgSDTUoh7M9WMECKXwB3xvh04HfQ9TOWw1Mk,223
@@ -24,11 +24,11 @@ anydi/ext/django/apps.py,sha256=YLL1uU6dSQ3uf3GB0VHzPW_eLuB1j9h6pv8EdAutMqo,2725
24
24
  anydi/ext/django/middleware.py,sha256=5OUdp0OWRozyW338Sq04BDhacaFlyUTTOduS_7EwCTA,854
25
25
  anydi/ext/django/ninja/__init__.py,sha256=4J0zoHPK9itbTVrjjvLX6Ftrsb2ND8bITqNDIJzEhks,520
26
26
  anydi/ext/django/ninja/_operation.py,sha256=wk5EOjLY3KVIHk9jMCGsFsja9-dQmMOpLpHXciqxQdk,2680
27
- anydi/ext/django/ninja/_signature.py,sha256=UVLmKpYvH1fNb9C7ffP50KCmh0BE6unHegfss5dvpVU,2261
27
+ anydi/ext/django/ninja/_signature.py,sha256=mseRTLZZdwdXCG-jdTe1l4WRacbKoa3kfEGWQ1aq3QY,2364
28
28
  anydi/ext/starlette/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  anydi/ext/starlette/middleware.py,sha256=MxnzshAs-CMvjJp0r457k52MzBL8O4KAuClnF6exBdU,803
30
- anydi-0.45.0.dist-info/METADATA,sha256=q54mbfxsSFZ_hpaOqCyaMlW_njtsrY2XvhRL28DeHac,4957
31
- anydi-0.45.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
- anydi-0.45.0.dist-info/entry_points.txt,sha256=Nklo9f3Oe4AkNsEgC4g43nCJ-23QDngZSVDNRMdaILI,43
33
- anydi-0.45.0.dist-info/licenses/LICENSE,sha256=V6rU8a8fv6o2jQ-7ODHs0XfDFimot8Q6Km6CylRIDTo,1069
34
- anydi-0.45.0.dist-info/RECORD,,
30
+ anydi-0.46.0.dist-info/METADATA,sha256=4C-I83UUd7PWkcDhIUm7Z1KfWqEDWyhoecoLgf6GlB4,4957
31
+ anydi-0.46.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
+ anydi-0.46.0.dist-info/entry_points.txt,sha256=Nklo9f3Oe4AkNsEgC4g43nCJ-23QDngZSVDNRMdaILI,43
33
+ anydi-0.46.0.dist-info/licenses/LICENSE,sha256=V6rU8a8fv6o2jQ-7ODHs0XfDFimot8Q6Km6CylRIDTo,1069
34
+ anydi-0.46.0.dist-info/RECORD,,
File without changes