mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-22 09:36:48 +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
|
||||
-------------------
|
||||
- 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.
|
||||
|
||||
4.8.1
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,6 +15,7 @@ from .providers cimport (
|
|||
Provider,
|
||||
Object,
|
||||
Resource,
|
||||
Container as ContainerProvider,
|
||||
deepcopy,
|
||||
)
|
||||
|
||||
|
@ -252,6 +253,13 @@ class DynamicContainer(object):
|
|||
if 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):
|
||||
"""Declarative inversion of control container meta class."""
|
||||
|
@ -407,6 +415,7 @@ class DeclarativeContainer(object):
|
|||
container.declarative_parent = cls
|
||||
container.set_providers(**deepcopy(cls.providers))
|
||||
container.override_providers(**overriding_providers)
|
||||
container.apply_container_providers_overridings()
|
||||
return container
|
||||
|
||||
@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):
|
||||
"""Override providers with providers from provided container."""
|
||||
for name, dependency_provider in container.providers.items():
|
||||
provider = self.__providers.get(name)
|
||||
|
||||
if not provider:
|
||||
continue
|
||||
provider = getattr(self, name)
|
||||
|
||||
if provider.last_overriding is dependency_provider:
|
||||
continue
|
||||
|
@ -3041,7 +3038,6 @@ cdef class Container(Provider):
|
|||
|
||||
if container is None:
|
||||
container = container_cls()
|
||||
container.override_providers(**overriding_providers)
|
||||
self.__container = container
|
||||
|
||||
super(Container, self).__init__()
|
||||
|
@ -3085,6 +3081,13 @@ cdef class Container(Provider):
|
|||
self.__container.override_providers(**provider.providers)
|
||||
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):
|
||||
"""Return single instance."""
|
||||
return self.__container
|
||||
|
|
|
@ -76,3 +76,21 @@ class ContainerTests(unittest.TestCase):
|
|||
|
||||
with self.assertRaises(errors.Error):
|
||||
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