mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-12-15 06:04:04 +03:00
Allow annotated marker to be anywhere in the annotation list (#939)
This commit is contained in:
parent
244deee75f
commit
51f8187202
|
|
@ -682,23 +682,18 @@ def _unpatch_attribute(patched: PatchedAttribute) -> None:
|
||||||
|
|
||||||
def _extract_marker(parameter: inspect.Parameter) -> Optional["_Marker"]:
|
def _extract_marker(parameter: inspect.Parameter) -> Optional["_Marker"]:
|
||||||
if get_origin(parameter.annotation) is Annotated:
|
if get_origin(parameter.annotation) is Annotated:
|
||||||
args = get_args(parameter.annotation)
|
candidates = get_args(parameter.annotation)[1:]
|
||||||
if len(args) > 1:
|
|
||||||
marker = args[1]
|
|
||||||
else:
|
|
||||||
marker = None
|
|
||||||
else:
|
else:
|
||||||
marker = parameter.default
|
candidates = (parameter.default,)
|
||||||
|
|
||||||
for marker_extractor in MARKER_EXTRACTORS:
|
for marker in candidates:
|
||||||
if _marker := marker_extractor(marker):
|
for marker_extractor in MARKER_EXTRACTORS:
|
||||||
marker = _marker
|
if _marker := marker_extractor(marker):
|
||||||
break
|
marker = _marker
|
||||||
|
break
|
||||||
if not isinstance(marker, _Marker):
|
if _is_marker(marker):
|
||||||
return None
|
return marker
|
||||||
|
return None
|
||||||
return marker
|
|
||||||
|
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
|
|
@ -1223,9 +1218,11 @@ def _get_members_and_annotated(obj: Any) -> Iterable[Tuple[str, Any]]:
|
||||||
for annotation_name, annotation in annotations.items():
|
for annotation_name, annotation in annotations.items():
|
||||||
if get_origin(annotation) is Annotated:
|
if get_origin(annotation) is Annotated:
|
||||||
args = get_args(annotation)
|
args = get_args(annotation)
|
||||||
if len(args) > 1:
|
# Search through all metadata items (args[1:]) for a DI marker
|
||||||
member = args[1]
|
for arg in args[1:]:
|
||||||
members.append((annotation_name, member))
|
if _is_marker(arg):
|
||||||
|
members.append((annotation_name, arg))
|
||||||
|
break
|
||||||
return members
|
return members
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,3 +124,10 @@ def test_class_decorator(service: Annotated[Service, Provide[Container.service]]
|
||||||
|
|
||||||
def test_container(container: Annotated[Container, Provide[Container]]):
|
def test_container(container: Annotated[Container, Provide[Container]]):
|
||||||
return container.service()
|
return container.service()
|
||||||
|
|
||||||
|
|
||||||
|
@inject
|
||||||
|
def test_annotated_with_non_di_metadata_first(
|
||||||
|
service: Annotated[Service, "some other annotated value", Provide[Container.service]],
|
||||||
|
):
|
||||||
|
return service
|
||||||
|
|
|
||||||
|
|
@ -174,3 +174,14 @@ def test_class_decorator():
|
||||||
def test_container():
|
def test_container():
|
||||||
service = module.test_container()
|
service = module.test_container()
|
||||||
assert isinstance(service, Service)
|
assert isinstance(service, Service)
|
||||||
|
|
||||||
|
|
||||||
|
def test_annotated_with_non_di_metadata_first():
|
||||||
|
"""Test that Annotated works when DI marker is not the first metadata item.
|
||||||
|
|
||||||
|
This tests the case where Annotated has other metadata (like docstrings or
|
||||||
|
other annotations) before the Provide marker, e.g.:
|
||||||
|
Annotated[Service, "some doc", Provide[Container.service]]
|
||||||
|
"""
|
||||||
|
service = module.test_annotated_with_non_di_metadata_first()
|
||||||
|
assert isinstance(service, Service)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user