mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-21 17:16:46 +03:00
Allow Closing
to detect dependent resources (#636)
This commit is contained in:
parent
a79ea1790c
commit
3b76a0d091
|
@ -593,6 +593,22 @@ def _fetch_reference_injections( # noqa: C901
|
||||||
return injections, closing
|
return injections, closing
|
||||||
|
|
||||||
|
|
||||||
|
def _locate_dependent_closing_args(provider: providers.Provider) -> dict[str, providers.Provider]:
|
||||||
|
if not hasattr(provider, "args"):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
closing_deps = {}
|
||||||
|
for arg in provider.args:
|
||||||
|
if not isinstance(arg, providers.Provider) or not hasattr(arg, "args"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not arg.args and isinstance(arg, providers.Resource):
|
||||||
|
return {str(id(arg)): arg}
|
||||||
|
else:
|
||||||
|
closing_deps += _locate_dependent_closing_args(arg)
|
||||||
|
return closing_deps
|
||||||
|
|
||||||
|
|
||||||
def _bind_injections(fn: Callable[..., Any], providers_map: ProvidersMap) -> None:
|
def _bind_injections(fn: Callable[..., Any], providers_map: ProvidersMap) -> None:
|
||||||
patched_callable = _patched_registry.get_callable(fn)
|
patched_callable = _patched_registry.get_callable(fn)
|
||||||
if patched_callable is None:
|
if patched_callable is None:
|
||||||
|
@ -614,6 +630,9 @@ def _bind_injections(fn: Callable[..., Any], providers_map: ProvidersMap) -> Non
|
||||||
|
|
||||||
if injection in patched_callable.reference_closing:
|
if injection in patched_callable.reference_closing:
|
||||||
patched_callable.add_closing(injection, provider)
|
patched_callable.add_closing(injection, provider)
|
||||||
|
deps = _locate_dependent_closing_args(provider)
|
||||||
|
for key, dep in deps.items():
|
||||||
|
patched_callable.add_closing(key, dep)
|
||||||
|
|
||||||
|
|
||||||
def _unbind_injections(fn: Callable[..., Any]) -> None:
|
def _unbind_injections(fn: Callable[..., Any]) -> None:
|
||||||
|
|
|
@ -20,6 +20,11 @@ class Service:
|
||||||
cls.shutdown_counter += 1
|
cls.shutdown_counter += 1
|
||||||
|
|
||||||
|
|
||||||
|
class FactoryService:
|
||||||
|
def __init__(self, service: Service):
|
||||||
|
self.service = service
|
||||||
|
|
||||||
|
|
||||||
def init_service():
|
def init_service():
|
||||||
service = Service()
|
service = Service()
|
||||||
service.init()
|
service.init()
|
||||||
|
@ -30,8 +35,14 @@ def init_service():
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
service = providers.Resource(init_service)
|
service = providers.Resource(init_service)
|
||||||
|
factory_service = providers.Factory(FactoryService, service)
|
||||||
|
|
||||||
|
|
||||||
@inject
|
@inject
|
||||||
def test_function(service: Service = Closing[Provide["service"]]):
|
def test_function(service: Service = Closing[Provide["service"]]):
|
||||||
return service
|
return service
|
||||||
|
|
||||||
|
|
||||||
|
@inject
|
||||||
|
def test_function_dependency(factory: FactoryService = Closing[Provide["factory_service"]]):
|
||||||
|
return factory
|
||||||
|
|
|
@ -289,6 +289,23 @@ def test_closing_resource():
|
||||||
assert result_1 is not result_2
|
assert result_1 is not result_2
|
||||||
|
|
||||||
|
|
||||||
|
@mark.usefixtures("resourceclosing_container")
|
||||||
|
def test_closing_dependency_resource():
|
||||||
|
resourceclosing.Service.reset_counter()
|
||||||
|
|
||||||
|
result_1 = resourceclosing.test_function_dependency()
|
||||||
|
assert isinstance(result_1, resourceclosing.FactoryService)
|
||||||
|
assert result_1.service.init_counter == 1
|
||||||
|
assert result_1.service.shutdown_counter == 1
|
||||||
|
|
||||||
|
result_2 = resourceclosing.test_function_dependency()
|
||||||
|
assert isinstance(result_2, resourceclosing.FactoryService)
|
||||||
|
assert result_2.service.init_counter == 2
|
||||||
|
assert result_2.service.shutdown_counter == 2
|
||||||
|
|
||||||
|
assert result_1 is not result_2
|
||||||
|
|
||||||
|
|
||||||
@mark.usefixtures("resourceclosing_container")
|
@mark.usefixtures("resourceclosing_container")
|
||||||
def test_closing_resource_bypass_marker_injection():
|
def test_closing_resource_bypass_marker_injection():
|
||||||
resourceclosing.Service.reset_counter()
|
resourceclosing.Service.reset_counter()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user