mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-12 01:20:51 +03:00
Implement Provide[foo.provided.bar.baz.call()]
This commit is contained in:
parent
6d92df32aa
commit
95db0eddc9
File diff suppressed because it is too large
Load Diff
|
@ -2703,6 +2703,11 @@ cdef class ProvidedInstance(Provider):
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
return ItemGetter(self, item)
|
return ItemGetter(self, item)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def provides(self):
|
||||||
|
"""Return provider."""
|
||||||
|
return self.__provider
|
||||||
|
|
||||||
def call(self, *args, **kwargs):
|
def call(self, *args, **kwargs):
|
||||||
return MethodCaller(self, *args, **kwargs)
|
return MethodCaller(self, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -2742,6 +2747,16 @@ cdef class AttributeGetter(Provider):
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
return ItemGetter(self, item)
|
return ItemGetter(self, item)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def provides(self):
|
||||||
|
"""Return provider."""
|
||||||
|
return self.__provider
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return name of the attribute."""
|
||||||
|
return self.__attribute
|
||||||
|
|
||||||
def call(self, *args, **kwargs):
|
def call(self, *args, **kwargs):
|
||||||
return MethodCaller(self, *args, **kwargs)
|
return MethodCaller(self, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -2782,6 +2797,16 @@ cdef class ItemGetter(Provider):
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
return ItemGetter(self, item)
|
return ItemGetter(self, item)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def provides(self):
|
||||||
|
"""Return provider."""
|
||||||
|
return self.__provider
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return name of the item."""
|
||||||
|
return self.__item
|
||||||
|
|
||||||
def call(self, *args, **kwargs):
|
def call(self, *args, **kwargs):
|
||||||
return MethodCaller(self, *args, **kwargs)
|
return MethodCaller(self, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -2833,6 +2858,37 @@ cdef class MethodCaller(Provider):
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
return ItemGetter(self, item)
|
return ItemGetter(self, item)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def provides(self):
|
||||||
|
"""Return provider."""
|
||||||
|
return self.__provider
|
||||||
|
|
||||||
|
@property
|
||||||
|
def args(self):
|
||||||
|
"""Return positional argument injections."""
|
||||||
|
cdef int index
|
||||||
|
cdef PositionalInjection arg
|
||||||
|
cdef list args
|
||||||
|
|
||||||
|
args = list()
|
||||||
|
for index in range(self.__args_len):
|
||||||
|
arg = self.__args[index]
|
||||||
|
args.append(arg.__value)
|
||||||
|
return tuple(args)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def kwargs(self):
|
||||||
|
"""Return keyword argument injections."""
|
||||||
|
cdef int index
|
||||||
|
cdef NamedInjection kwarg
|
||||||
|
cdef dict kwargs
|
||||||
|
|
||||||
|
kwargs = dict()
|
||||||
|
for index in range(self.__kwargs_len):
|
||||||
|
kwarg = self.__kwargs[index]
|
||||||
|
kwargs[kwarg.__name] = kwarg.__value
|
||||||
|
return kwargs
|
||||||
|
|
||||||
def call(self, *args, **kwargs):
|
def call(self, *args, **kwargs):
|
||||||
return MethodCaller(self, *args, **kwargs)
|
return MethodCaller(self, *args, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,16 @@ def _resolve_injections(fn: Callable[..., Any], container: AnyContainer) -> Dict
|
||||||
elif isinstance(marker.provider, providers.Delegate):
|
elif isinstance(marker.provider, providers.Delegate):
|
||||||
provider_name = container.resolve_provider_name(marker.provider.provides)
|
provider_name = container.resolve_provider_name(marker.provider.provides)
|
||||||
provider = container.providers[provider_name]
|
provider = container.providers[provider_name]
|
||||||
|
elif isinstance(marker.provider, (
|
||||||
|
providers.ProvidedInstance,
|
||||||
|
providers.AttributeGetter,
|
||||||
|
providers.ItemGetter,
|
||||||
|
providers.MethodCaller,
|
||||||
|
)):
|
||||||
|
provider = _prepare_provided_instance_injection(
|
||||||
|
marker.provider,
|
||||||
|
container,
|
||||||
|
)
|
||||||
elif isinstance(marker.provider, providers.Provider):
|
elif isinstance(marker.provider, providers.Provider):
|
||||||
provider_name = container.resolve_provider_name(marker.provider)
|
provider_name = container.resolve_provider_name(marker.provider)
|
||||||
if not provider_name:
|
if not provider_name:
|
||||||
|
@ -159,6 +169,40 @@ def _prepare_config_injection(
|
||||||
return provider
|
return provider
|
||||||
|
|
||||||
|
|
||||||
|
def _prepare_provided_instance_injection(
|
||||||
|
current_provider: providers.Provider,
|
||||||
|
container: AnyContainer,
|
||||||
|
) -> providers.Provider:
|
||||||
|
provided_instance_markers = []
|
||||||
|
instance_provider_marker = current_provider
|
||||||
|
while isinstance(instance_provider_marker, (
|
||||||
|
providers.ProvidedInstance,
|
||||||
|
providers.AttributeGetter,
|
||||||
|
providers.ItemGetter,
|
||||||
|
providers.MethodCaller,
|
||||||
|
)):
|
||||||
|
provided_instance_markers.insert(0, instance_provider_marker)
|
||||||
|
instance_provider_marker = instance_provider_marker.provides
|
||||||
|
|
||||||
|
provider_name = container.resolve_provider_name(instance_provider_marker)
|
||||||
|
provider = container.providers[provider_name]
|
||||||
|
|
||||||
|
for provided_instance in provided_instance_markers:
|
||||||
|
if isinstance(provided_instance, providers.ProvidedInstance):
|
||||||
|
provider = provider.provided
|
||||||
|
elif isinstance(provided_instance, providers.AttributeGetter):
|
||||||
|
provider = getattr(provider, provided_instance.name)
|
||||||
|
elif isinstance(provided_instance, providers.ItemGetter):
|
||||||
|
provider = provider[provided_instance.name]
|
||||||
|
elif isinstance(provided_instance, providers.MethodCaller):
|
||||||
|
provider = provider.call(
|
||||||
|
*provided_instance.args,
|
||||||
|
**provided_instance.kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return provider
|
||||||
|
|
||||||
|
|
||||||
def _resolve_container_config(container: AnyContainer) -> Optional[providers.Configuration]:
|
def _resolve_container_config(container: AnyContainer) -> Optional[providers.Configuration]:
|
||||||
for provider in container.providers.values():
|
for provider in container.providers.values():
|
||||||
if isinstance(provider, providers.Configuration):
|
if isinstance(provider, providers.Configuration):
|
||||||
|
|
|
@ -35,3 +35,7 @@ def test_config_value(
|
||||||
def test_provide_provider(service_provider: Callable[..., Service] = Provider[Container.service.provider]):
|
def test_provide_provider(service_provider: Callable[..., Service] = Provider[Container.service.provider]):
|
||||||
service = service_provider()
|
service = service_provider()
|
||||||
return service
|
return service
|
||||||
|
|
||||||
|
|
||||||
|
def test_provided_instance(some_value: int = Provide[Container.service.provided.foo['bar'].call()]):
|
||||||
|
return some_value
|
||||||
|
|
|
@ -62,3 +62,13 @@ class WiringTest(unittest.TestCase):
|
||||||
def test_provide_provider(self):
|
def test_provide_provider(self):
|
||||||
service = module.test_provide_provider()
|
service = module.test_provide_provider()
|
||||||
self.assertIsInstance(service, Service)
|
self.assertIsInstance(service, Service)
|
||||||
|
|
||||||
|
def test_provided_instance(self):
|
||||||
|
class TestService:
|
||||||
|
foo = {
|
||||||
|
'bar': lambda: 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.container.service.override(TestService()):
|
||||||
|
some_value = module.test_provided_instance()
|
||||||
|
self.assertEqual(some_value, 10)
|
Loading…
Reference in New Issue
Block a user