Fix provide issue

This commit is contained in:
Roman Mogylatov 2021-09-25 15:32:53 -04:00
parent cc4235257c
commit abaec3ee15
5 changed files with 36 additions and 9 deletions

View File

@ -10,6 +10,7 @@ follows `Semantic versioning`_
Develop Develop
------- -------
- Fix a wiring bug with improper resolving of ``Provide[some_provider.provider]``.
- Fix a typo in ``Factory`` provider docs ``service.add_attributes(clent=client)`` - Fix a typo in ``Factory`` provider docs ``service.add_attributes(clent=client)``
`#499 <https://github.com/ets-labs/python-dependency-injector/issues/499>`_. `#499 <https://github.com/ets-labs/python-dependency-injector/issues/499>`_.
Thanks to `@rajanjha786 <https://github.com/rajanjha786>`_ for the contribution. Thanks to `@rajanjha786 <https://github.com/rajanjha786>`_ for the contribution.

View File

@ -39,19 +39,29 @@ a function or method argument:
Specifying an annotation is optional. Specifying an annotation is optional.
There are two types of markers: To inject the provider itself use ``Provide[foo.provider]``:
- ``Provide[foo]`` - call the provider ``foo`` and injects the result
- ``Provider[foo]`` - injects the provider ``foo`` itself
.. code-block:: python .. code-block:: python
from dependency_injector.providers import Factory
from dependency_injector.wiring import inject, Provide
@inject
def foo(bar_provider: Factory[Bar] = Provide[Container.bar.provider]):
bar = bar_provider(argument="baz")
...
You can also use ``Provider[foo]`` for injecting the provider itself:
.. code-block:: python
from dependency_injector.providers import Factory
from dependency_injector.wiring import inject, Provider from dependency_injector.wiring import inject, Provider
@inject @inject
def foo(bar_provider: Callable[..., Bar] = Provider[Container.bar]): def foo(bar_provider: Factory[Bar] = Provider[Container.bar]):
bar = bar_provider() bar = bar_provider(argument="baz")
... ...
You can use configuration, provided instance and sub-container providers as you normally do. You can use configuration, provided instance and sub-container providers as you normally do.

View File

@ -226,7 +226,10 @@ class ProvidersMap:
self, self,
original: providers.Delegate, original: providers.Delegate,
) -> Optional[providers.Provider]: ) -> Optional[providers.Provider]:
return self._resolve_provider(original.provides) provider = self._resolve_provider(original.provides)
if provider:
provider = provider.provider
return provider
def _resolve_config_option( def _resolve_config_option(
self, self,
@ -539,6 +542,9 @@ def _bind_injections(fn: Callable[..., Any], providers_map: ProvidersMap) -> Non
if isinstance(marker, Provide): if isinstance(marker, Provide):
fn.__injections__[injection] = provider fn.__injections__[injection] = provider
elif isinstance(marker, Provider): elif isinstance(marker, Provider):
if isinstance(provider, providers.Delegate):
fn.__injections__[injection] = provider
else:
fn.__injections__[injection] = provider.provider fn.__injections__[injection] = provider.provider
if injection in fn.__reference_closing__: if injection in fn.__reference_closing__:

View File

@ -84,7 +84,13 @@ def test_config_value_required_undefined(
@inject @inject
def test_provide_provider(service_provider: Callable[..., Service] = Provider[Container.service.provider]): def test_provide_provider(service_provider: Callable[..., Service] = Provide[Container.service.provider]):
service = service_provider()
return service
@inject
def test_provider_provider(service_provider: Callable[..., Service] = Provider[Container.service.provider]):
service = service_provider() service = service_provider()
return service return service

View File

@ -169,6 +169,10 @@ class WiringTest(unittest.TestCase):
service = module.test_provide_provider() service = module.test_provide_provider()
self.assertIsInstance(service, Service) self.assertIsInstance(service, Service)
def test_provider_provider(self):
service = module.test_provider_provider()
self.assertIsInstance(service, Service)
def test_provided_instance(self): def test_provided_instance(self):
class TestService: class TestService:
foo = { foo = {