Container provider override API (#418)

* Implement override API

* Add tests

* Update changelog
This commit is contained in:
Roman Mogylatov 2021-03-03 09:05:15 -05:00 committed by GitHub
parent 2bf3601695
commit 1304e596d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 2015 additions and 1458 deletions

View File

@ -12,6 +12,9 @@ Development version
- Implement context manager interface for resetting a singleton provider. - Implement context manager interface for resetting a singleton provider.
See issue: `#413 <https://github.com/ets-labs/python-dependency-injector/issues/413>`_. See issue: `#413 <https://github.com/ets-labs/python-dependency-injector/issues/413>`_.
Thanks to `@Arrowana <https://github.com/Arrowana>`_ for suggesting the improvement. Thanks to `@Arrowana <https://github.com/Arrowana>`_ for suggesting the improvement.
- Implement overriding interface to container provider.
See issue: `#415 <https://github.com/ets-labs/python-dependency-injector/issues/415>`_.
Thanks to `@wackazong <https://github.com/wackazong>`_ for bringing up the use case.
4.28.1 4.28.1
------ ------

File diff suppressed because it is too large Load Diff

View File

@ -3578,7 +3578,32 @@ cdef class Container(Provider):
raise Error('Container provider {0} can be overridden only by providers container'.format(self)) raise Error('Container provider {0} can be overridden only by providers container'.format(self))
self.__container.override_providers(**provider.providers) self.__container.override_providers(**provider.providers)
super().override(provider) return super().override(provider)
def reset_last_overriding(self):
"""Reset last overriding provider.
:raise: :py:exc:`dependency_injector.errors.Error` if provider is not
overridden.
:rtype: None
"""
super().reset_last_overriding()
for provider in self.__container.providers.values():
if not provider.overridden:
continue
provider.reset_last_overriding()
def reset_override(self):
"""Reset all overriding providers.
:rtype: None
"""
super().reset_override()
for provider in self.__container.providers.values():
if not provider.overridden:
continue
provider.reset_override()
def apply_overridings(self): def apply_overridings(self):
"""Apply container overriding. """Apply container overriding.

View File

@ -176,6 +176,48 @@ class ContainerTests(unittest.TestCase):
result = b.a().c().bar() result = b.a().c().bar()
self.assertEqual(result, 'foo++') self.assertEqual(result, 'foo++')
def test_reset_last_overriding(self):
application = TestApplication(config=_copied(TEST_CONFIG_1))
application.core.override(TestCore(config=_copied(TEST_CONFIG_2['core'])))
application.core.reset_last_overriding()
self.assertEqual(application.dict_factory(), {'value': TEST_VALUE_1})
def test_reset_last_overriding_only_overridden(self):
application = TestApplication(config=_copied(TEST_CONFIG_1))
application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2['core'])))
application.core.reset_last_overriding()
self.assertEqual(application.dict_factory(), {'value': TEST_VALUE_1})
def test_override_context_manager(self):
application = TestApplication(config=_copied(TEST_CONFIG_1))
overriding_core = TestCore(config=_copied(TEST_CONFIG_2['core']))
with application.core.override(overriding_core) as context_core:
self.assertEqual(application.dict_factory(), {'value': TEST_VALUE_2})
self.assertIs(context_core(), overriding_core)
self.assertEqual(application.dict_factory(), {'value': TEST_VALUE_1})
def test_reset_override(self):
application = TestApplication(config=_copied(TEST_CONFIG_1))
application.core.override(TestCore(config=_copied(TEST_CONFIG_2['core'])))
application.core.reset_override()
self.assertEqual(application.dict_factory(), {'value': None})
def test_reset_override_only_overridden(self):
application = TestApplication(config=_copied(TEST_CONFIG_1))
application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2['core'])))
application.core.reset_override()
self.assertEqual(application.dict_factory(), {'value': None})
def test_assign_parent(self): def test_assign_parent(self):
parent = providers.DependenciesContainer() parent = providers.DependenciesContainer()
provider = providers.Container(TestCore) provider = providers.Container(TestCore)