mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 02:53:56 +03:00
Improve @containers.copy to replace subcontainer providers (#378)
* Improve @containers.copy to replace subcontainer providers * Bump version to 4.11.1
This commit is contained in:
parent
78479c65e6
commit
92938b018d
|
@ -7,6 +7,12 @@ that were made in every particular version.
|
||||||
From version 0.7.6 *Dependency Injector* framework strictly
|
From version 0.7.6 *Dependency Injector* framework strictly
|
||||||
follows `Semantic versioning`_
|
follows `Semantic versioning`_
|
||||||
|
|
||||||
|
4.11.1
|
||||||
|
------
|
||||||
|
- Fix a bug in ``@containers.copy`` to improve replacing of subcontainer providers.
|
||||||
|
See issue `#378 <https://github.com/ets-labs/python-dependency-injector/issues/378>`_.
|
||||||
|
Many thanks to `Shaun Cutts <https://github.com/shaunc>`_ for reporting the issue.
|
||||||
|
|
||||||
4.11.0
|
4.11.0
|
||||||
------
|
------
|
||||||
- Add ``loader`` argument to the configuration provider ``Configuration.from_yaml(..., loader=...)``
|
- Add ``loader`` argument to the configuration provider ``Configuration.from_yaml(..., loader=...)``
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Top-level package."""
|
"""Top-level package."""
|
||||||
|
|
||||||
__version__ = '4.11.0'
|
__version__ = '4.11.1'
|
||||||
"""Version number.
|
"""Version number.
|
||||||
|
|
||||||
:type: str
|
:type: str
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -541,16 +541,25 @@ def copy(object container):
|
||||||
:return: Declarative container's copying decorator.
|
:return: Declarative container's copying decorator.
|
||||||
:rtype: callable(:py:class:`DeclarativeContainer`)
|
:rtype: callable(:py:class:`DeclarativeContainer`)
|
||||||
"""
|
"""
|
||||||
def _decorator(copied_container):
|
def _get_providers_memo(from_providers, source_providers):
|
||||||
cdef dict memo = dict()
|
memo = dict()
|
||||||
for name, provider in six.iteritems(copied_container.cls_providers):
|
|
||||||
|
for name, provider in from_providers.items():
|
||||||
try:
|
try:
|
||||||
source_provider = getattr(container, name)
|
source_provider = source_providers[name]
|
||||||
except AttributeError:
|
except KeyError:
|
||||||
pass
|
...
|
||||||
else:
|
else:
|
||||||
memo[id(source_provider)] = provider
|
memo[id(source_provider)] = provider
|
||||||
|
|
||||||
|
if hasattr(provider, 'providers') and hasattr(source_provider, 'providers'):
|
||||||
|
sub_memo = _get_providers_memo(provider.providers, source_provider.providers)
|
||||||
|
memo.update(sub_memo)
|
||||||
|
return memo
|
||||||
|
|
||||||
|
def _decorator(copied_container):
|
||||||
|
memo = _get_providers_memo(copied_container.cls_providers, container.providers)
|
||||||
|
|
||||||
providers_copy = deepcopy(container.providers, memo)
|
providers_copy = deepcopy(container.providers, memo)
|
||||||
for name, provider in six.iteritems(providers_copy):
|
for name, provider in six.iteritems(providers_copy):
|
||||||
setattr(copied_container, name, provider)
|
setattr(copied_container, name, provider)
|
||||||
|
|
|
@ -296,6 +296,26 @@ class DeclarativeContainerTests(unittest.TestCase):
|
||||||
self.assertEqual(_Container1.p13(), 11)
|
self.assertEqual(_Container1.p13(), 11)
|
||||||
self.assertEqual(_Container2.p13(), 22)
|
self.assertEqual(_Container2.p13(), 22)
|
||||||
|
|
||||||
|
def test_copy_with_replacing_subcontainer_providers(self):
|
||||||
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/374
|
||||||
|
class X(containers.DeclarativeContainer):
|
||||||
|
foo = providers.Dependency(instance_of=str)
|
||||||
|
|
||||||
|
def build_x():
|
||||||
|
return X(foo='1')
|
||||||
|
|
||||||
|
class A(containers.DeclarativeContainer):
|
||||||
|
x = providers.DependenciesContainer(**X.providers)
|
||||||
|
y = x.foo
|
||||||
|
|
||||||
|
@containers.copy(A)
|
||||||
|
class B1(A):
|
||||||
|
x = providers.Container(build_x)
|
||||||
|
|
||||||
|
b1 = B1()
|
||||||
|
|
||||||
|
self.assertEqual(b1.y(), '1')
|
||||||
|
|
||||||
def test_containers_attribute(self):
|
def test_containers_attribute(self):
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
class Container1(containers.DeclarativeContainer):
|
class Container1(containers.DeclarativeContainer):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user