Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/main/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ Development version
- Rename ``ExternalDependency`` provider to ``Dependency``.
- Add default value for ``instance_of`` argument of ``Dependency`` provider -
``Dependency(instance_of=object)``.
- Change initialization of declarative container, so it accepts overriding
providers as keyword arguments -
``DeclarativeContainer(**overriding_providers)``.
- Add method to dynamic catalog for setting groups of providers -
``DynamicContainer.set_providers(**providers)``.
- Add method to dynamic catalog for overriding groups of providers -
``DynamicContainer.set_providers(**overriding_providers)``.


3.8.2
Expand Down
2 changes: 1 addition & 1 deletion examples/miniapps/bundles/bundles/photos/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Photos bundle."""

from core import containers
from dependency_injector import containers
from dependency_injector import providers

from . import entities
Expand Down
2 changes: 1 addition & 1 deletion examples/miniapps/bundles/bundles/users/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Users bundle."""

from core import containers
from dependency_injector import containers
from dependency_injector import providers

from . import entities
Expand Down
Empty file.
43 changes: 0 additions & 43 deletions examples/miniapps/bundles/core/containers.py

This file was deleted.

2 changes: 1 addition & 1 deletion examples/miniapps/bundles/run.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Example application - Bundles."""

from core import containers
from dependency_injector import containers
from dependency_injector import providers

from bundles.users import Users
Expand Down
2,882 changes: 1,713 additions & 1,169 deletions src/dependency_injector/containers.c

Large diffs are not rendered by default.

35 changes: 29 additions & 6 deletions src/dependency_injector/containers.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ class DynamicContainer(object):
del self.providers[name]
super(DynamicContainer, self).__delattr__(name)

def set_providers(self, **providers):
"""Set container providers.

:param providers: Dictionary of providers
:type providers:
dict[str, :py:class:`dependency_injector.providers.Provider`]

:rtype: None
"""
for name, provider in six.iteritems(providers):
setattr(self, name, provider)

def override(self, object overriding):
"""Override current container by overriding container.

Expand All @@ -111,6 +123,19 @@ class DynamicContainer(object):
except AttributeError:
pass

def override_providers(self, **overriding_providers):
"""Override container providers.

:param overriding_providers: Dictionary of providers
:type overriding_providers:
dict[str, :py:class:`dependency_injector.providers.Provider`]

:rtype: None
"""
for name, overriding_provider in six.iteritems(overriding_providers):
container_provider = getattr(self, name)
container_provider.override(overriding_provider)

def reset_last_overriding(self):
"""Reset last overriding provider for each container providers.

Expand Down Expand Up @@ -265,18 +290,16 @@ class DeclarativeContainer(object):
:type: tuple[:py:class:`DeclarativeContainer`]
"""

def __new__(cls, *args, **kwargs):
def __new__(cls, **overriding_providers):
"""Constructor.

:return: Dynamic container with copy of all providers.
:rtype: :py:class:`DynamicContainer`
"""
container = cls.instance_type(*args, **kwargs)
container = cls.instance_type()
container.provider_type = cls.provider_type

for name, provider in six.iteritems(deepcopy(cls.providers)):
setattr(container, name, provider)

container.set_providers(**deepcopy(cls.providers))
container.override_providers(**overriding_providers)
return container

@classmethod
Expand Down
9 changes: 9 additions & 0 deletions tests/unit/containers/test_declarative.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,12 @@ class Container2(containers.DeclarativeContainer):
dict(Container1=Container.Container1,
Container2=Container.Container2,
Container3=Container.Container3))

def test_init_with_overriding_providers(self):
p1 = providers.Provider()
p2 = providers.Provider()

container = ContainerA(p11=p1, p12=p2)

self.assertIs(container.p11.last_overriding, p1)
self.assertIs(container.p12.last_overriding, p2)
26 changes: 26 additions & 0 deletions tests/unit/containers/test_dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ def test_set_invalid_provider_type(self):
self.assertIs(ContainerA.provider_type,
containers.DeclarativeContainer.provider_type)

def test_set_providers(self):
p13 = providers.Provider()
p14 = providers.Provider()
container_a = ContainerA()

container_a.set_providers(p13=p13, p14=p14)

self.assertIs(container_a.p13, p13)
self.assertIs(container_a.p14, p14)

def test_override(self):
class _Container(containers.DeclarativeContainer):
p11 = providers.Provider()
Expand Down Expand Up @@ -108,6 +118,22 @@ def test_override_with_itself(self):
with self.assertRaises(errors.Error):
container.override(container)

def test_override_providers(self):
p1 = providers.Provider()
p2 = providers.Provider()
container_a = ContainerA()

container_a.override_providers(p11=p1, p12=p2)

self.assertIs(container_a.p11.last_overriding, p1)
self.assertIs(container_a.p12.last_overriding, p2)

def test_override_providers_with_unknown_provider(self):
container_a = ContainerA()

with self.assertRaises(AttributeError):
container_a.override_providers(unknown=providers.Provider())

def test_reset_last_overridding(self):
class _Container(containers.DeclarativeContainer):
p11 = providers.Provider()
Expand Down