mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-29 04:53:59 +03:00
Fix multiple containers wiring issue
This commit is contained in:
parent
2565a1eab0
commit
776cb4eebf
|
@ -9,6 +9,9 @@ follows `Semantic versioning`_
|
||||||
|
|
||||||
Develop
|
Develop
|
||||||
-----
|
-----
|
||||||
|
- Fix wiring of multiple containers
|
||||||
|
(see issue `#313 <https://github.com/ets-labs/python-dependency-injector/issues/313>`_).
|
||||||
|
Thanks to `iskorini <https://github.com/iskorini>`_ for reporting the issue.
|
||||||
- Fix wiring for ``@classmethod``.
|
- Fix wiring for ``@classmethod``.
|
||||||
|
|
||||||
4.1.5
|
4.1.5
|
||||||
|
|
|
@ -37,7 +37,7 @@ class ProvidersMap:
|
||||||
original_providers=container.declarative_parent.providers,
|
original_providers=container.declarative_parent.providers,
|
||||||
)
|
)
|
||||||
|
|
||||||
def resolve_provider(self, provider: providers.Provider) -> providers.Provider:
|
def resolve_provider(self, provider: providers.Provider) -> Optional[providers.Provider]:
|
||||||
if isinstance(provider, providers.Delegate):
|
if isinstance(provider, providers.Delegate):
|
||||||
return self._resolve_delegate(provider)
|
return self._resolve_delegate(provider)
|
||||||
elif isinstance(provider, (
|
elif isinstance(provider, (
|
||||||
|
@ -54,10 +54,10 @@ class ProvidersMap:
|
||||||
else:
|
else:
|
||||||
return self._resolve_provider(provider)
|
return self._resolve_provider(provider)
|
||||||
|
|
||||||
def _resolve_delegate(self, original: providers.Delegate) -> providers.Provider:
|
def _resolve_delegate(self, original: providers.Delegate) -> Optional[providers.Provider]:
|
||||||
return self._resolve_provider(original.provides)
|
return self._resolve_provider(original.provides)
|
||||||
|
|
||||||
def _resolve_provided_instance(self, original: providers.Provider) -> providers.Provider:
|
def _resolve_provided_instance(self, original: providers.Provider) -> Optional[providers.Provider]:
|
||||||
modifiers = []
|
modifiers = []
|
||||||
while isinstance(original, (
|
while isinstance(original, (
|
||||||
providers.ProvidedInstance,
|
providers.ProvidedInstance,
|
||||||
|
@ -69,6 +69,8 @@ class ProvidersMap:
|
||||||
original = original.provides
|
original = original.provides
|
||||||
|
|
||||||
new = self._resolve_provider(original)
|
new = self._resolve_provider(original)
|
||||||
|
if new is None:
|
||||||
|
return None
|
||||||
|
|
||||||
for modifier in modifiers:
|
for modifier in modifiers:
|
||||||
if isinstance(modifier, providers.ProvidedInstance):
|
if isinstance(modifier, providers.ProvidedInstance):
|
||||||
|
@ -89,9 +91,11 @@ class ProvidersMap:
|
||||||
self,
|
self,
|
||||||
original: providers.ConfigurationOption,
|
original: providers.ConfigurationOption,
|
||||||
as_: Any = None,
|
as_: Any = None,
|
||||||
) -> providers.Provider:
|
) -> Optional[providers.Provider]:
|
||||||
original_root = original.root
|
original_root = original.root
|
||||||
new = self._resolve_provider(original_root)
|
new = self._resolve_provider(original_root)
|
||||||
|
if new is None:
|
||||||
|
return None
|
||||||
new = cast(providers.Configuration, new)
|
new = cast(providers.Configuration, new)
|
||||||
|
|
||||||
for segment in original.get_name_segments():
|
for segment in original.get_name_segments():
|
||||||
|
@ -106,11 +110,11 @@ class ProvidersMap:
|
||||||
|
|
||||||
return new
|
return new
|
||||||
|
|
||||||
def _resolve_provider(self, original: providers.Provider) -> providers.Provider:
|
def _resolve_provider(self, original: providers.Provider) -> Optional[providers.Provider]:
|
||||||
try:
|
try:
|
||||||
return self._map[original]
|
return self._map[original]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise Exception('Unable to resolve original provider')
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _create_providers_map(
|
def _create_providers_map(
|
||||||
|
@ -216,6 +220,9 @@ def _resolve_injections(fn: Callable[..., Any], providers_map: ProvidersMap) ->
|
||||||
marker = parameter.default
|
marker = parameter.default
|
||||||
|
|
||||||
provider = providers_map.resolve_provider(marker.provider)
|
provider = providers_map.resolve_provider(marker.provider)
|
||||||
|
if provider is None:
|
||||||
|
continue
|
||||||
|
|
||||||
if isinstance(marker, Provide):
|
if isinstance(marker, Provide):
|
||||||
injections[parameter_name] = provider
|
injections[parameter_name] = provider
|
||||||
elif isinstance(marker, Provider):
|
elif isinstance(marker, Provider):
|
||||||
|
|
|
@ -5,7 +5,7 @@ from typing import Callable
|
||||||
|
|
||||||
from dependency_injector.wiring import Provide, Provider
|
from dependency_injector.wiring import Provide, Provider
|
||||||
|
|
||||||
from .container import Container
|
from .container import Container, SubContainer
|
||||||
from .service import Service
|
from .service import Service
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,3 +58,10 @@ def test_subcontainer_provider(some_value: int = Provide[Container.sub.int_objec
|
||||||
|
|
||||||
def test_config_invariant(some_value: int = Provide[Container.config.option[Container.config.switch]]):
|
def test_config_invariant(some_value: int = Provide[Container.config.option[Container.config.switch]]):
|
||||||
return some_value
|
return some_value
|
||||||
|
|
||||||
|
|
||||||
|
def test_provide_from_different_containers(
|
||||||
|
service: Service = Provide[Container.service],
|
||||||
|
some_value: int = Provide[SubContainer.int_object],
|
||||||
|
):
|
||||||
|
return service, some_value
|
||||||
|
|
|
@ -16,7 +16,7 @@ sys.path.append(_SAMPLES_DIR)
|
||||||
|
|
||||||
from wiringsamples import module, package
|
from wiringsamples import module, package
|
||||||
from wiringsamples.service import Service
|
from wiringsamples.service import Service
|
||||||
from wiringsamples.container import Container
|
from wiringsamples.container import Container, SubContainer
|
||||||
|
|
||||||
|
|
||||||
class WiringTest(unittest.TestCase):
|
class WiringTest(unittest.TestCase):
|
||||||
|
@ -161,3 +161,16 @@ class WiringTest(unittest.TestCase):
|
||||||
from wiringsamples.package.subpackage import submodule
|
from wiringsamples.package.subpackage import submodule
|
||||||
self.container.unwire()
|
self.container.unwire()
|
||||||
self.assertIsInstance(submodule.test_function(), Provide)
|
self.assertIsInstance(submodule.test_function(), Provide)
|
||||||
|
|
||||||
|
def test_wire_multiple_containers(self):
|
||||||
|
sub_container = SubContainer()
|
||||||
|
sub_container.wire(
|
||||||
|
modules=[module],
|
||||||
|
packages=[package],
|
||||||
|
)
|
||||||
|
self.addCleanup(sub_container.unwire)
|
||||||
|
|
||||||
|
service, some_value = module.test_provide_from_different_containers()
|
||||||
|
|
||||||
|
self.assertIsInstance(service, Service)
|
||||||
|
self.assertEqual(some_value, 1)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user