mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 11:04:01 +03:00
Fix `Container
` provider to apply context overridings on root container initialization
This commit is contained in:
parent
de6c3cda78
commit
1628cfaf28
|
@ -9,6 +9,9 @@ follows `Semantic versioning`_
|
||||||
|
|
||||||
Development version
|
Development version
|
||||||
-------------------
|
-------------------
|
||||||
|
- Fix ``Container`` provider to apply context overridings on root container initialization.
|
||||||
|
See issue `#354 <https://github.com/ets-labs/python-dependency-injector/issues/354>`_.
|
||||||
|
Many thanks to `Shaun Cutts <https://github.com/shaunc>`_ for submitting the issue.
|
||||||
- Hotfix for version ``4.8.0``: fix side effect in ``Container`` provider overriding.
|
- Hotfix for version ``4.8.0``: fix side effect in ``Container`` provider overriding.
|
||||||
|
|
||||||
4.8.1
|
4.8.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,6 +15,7 @@ from .providers cimport (
|
||||||
Provider,
|
Provider,
|
||||||
Object,
|
Object,
|
||||||
Resource,
|
Resource,
|
||||||
|
Container as ContainerProvider,
|
||||||
deepcopy,
|
deepcopy,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -252,6 +253,13 @@ class DynamicContainer(object):
|
||||||
if futures:
|
if futures:
|
||||||
return asyncio.gather(*futures)
|
return asyncio.gather(*futures)
|
||||||
|
|
||||||
|
def apply_container_providers_overridings(self):
|
||||||
|
"""Apply container providers' overridings."""
|
||||||
|
for provider in self.providers.values():
|
||||||
|
if not isinstance(provider, ContainerProvider):
|
||||||
|
continue
|
||||||
|
provider.apply_overridings()
|
||||||
|
|
||||||
|
|
||||||
class DeclarativeContainerMetaClass(type):
|
class DeclarativeContainerMetaClass(type):
|
||||||
"""Declarative inversion of control container meta class."""
|
"""Declarative inversion of control container meta class."""
|
||||||
|
@ -407,6 +415,7 @@ class DeclarativeContainer(object):
|
||||||
container.declarative_parent = cls
|
container.declarative_parent = cls
|
||||||
container.set_providers(**deepcopy(cls.providers))
|
container.set_providers(**deepcopy(cls.providers))
|
||||||
container.override_providers(**overriding_providers)
|
container.override_providers(**overriding_providers)
|
||||||
|
container.apply_container_providers_overridings()
|
||||||
return container
|
return container
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -765,10 +765,7 @@ cdef class DependenciesContainer(Object):
|
||||||
cpdef object _override_providers(self, object container):
|
cpdef object _override_providers(self, object container):
|
||||||
"""Override providers with providers from provided container."""
|
"""Override providers with providers from provided container."""
|
||||||
for name, dependency_provider in container.providers.items():
|
for name, dependency_provider in container.providers.items():
|
||||||
provider = self.__providers.get(name)
|
provider = getattr(self, name)
|
||||||
|
|
||||||
if not provider:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if provider.last_overriding is dependency_provider:
|
if provider.last_overriding is dependency_provider:
|
||||||
continue
|
continue
|
||||||
|
@ -3041,7 +3038,6 @@ cdef class Container(Provider):
|
||||||
|
|
||||||
if container is None:
|
if container is None:
|
||||||
container = container_cls()
|
container = container_cls()
|
||||||
container.override_providers(**overriding_providers)
|
|
||||||
self.__container = container
|
self.__container = container
|
||||||
|
|
||||||
super(Container, self).__init__()
|
super(Container, self).__init__()
|
||||||
|
@ -3085,6 +3081,13 @@ cdef class Container(Provider):
|
||||||
self.__container.override_providers(**provider.providers)
|
self.__container.override_providers(**provider.providers)
|
||||||
super().override(provider)
|
super().override(provider)
|
||||||
|
|
||||||
|
def apply_overridings(self):
|
||||||
|
"""Apply container overriding.
|
||||||
|
|
||||||
|
This method should not be called directly. It is called on
|
||||||
|
declarative container initialization."""
|
||||||
|
self.__container.override_providers(**self.__overriding_providers)
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs):
|
cpdef object _provide(self, tuple args, dict kwargs):
|
||||||
"""Return single instance."""
|
"""Return single instance."""
|
||||||
return self.__container
|
return self.__container
|
||||||
|
|
|
@ -76,3 +76,21 @@ class ContainerTests(unittest.TestCase):
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
with self.assertRaises(errors.Error):
|
||||||
provider.override(providers.Object('foo'))
|
provider.override(providers.Object('foo'))
|
||||||
|
|
||||||
|
def test_lazy_overriding(self):
|
||||||
|
class D(containers.DeclarativeContainer):
|
||||||
|
foo = providers.Object("foo")
|
||||||
|
|
||||||
|
class A(containers.DeclarativeContainer):
|
||||||
|
d = providers.DependenciesContainer()
|
||||||
|
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
|
||||||
|
|
||||||
|
class B(containers.DeclarativeContainer):
|
||||||
|
d = providers.DependenciesContainer()
|
||||||
|
|
||||||
|
a = providers.Container(A, d=d)
|
||||||
|
|
||||||
|
b = B(d=D())
|
||||||
|
result = b.a().bar()
|
||||||
|
self.assertEqual(result, 'foo++')
|
||||||
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/354
|
||||||
|
|
Loading…
Reference in New Issue
Block a user