2021-10-18 23:19:03 +03:00
|
|
|
"""Container provider tests."""
|
2020-06-23 05:45:16 +03:00
|
|
|
|
|
|
|
import copy
|
|
|
|
|
2021-01-12 16:41:59 +03:00
|
|
|
from dependency_injector import containers, providers, errors
|
2021-10-18 23:19:03 +03:00
|
|
|
from pytest import raises
|
2020-06-23 05:45:16 +03:00
|
|
|
|
|
|
|
|
2021-10-01 03:09:42 +03:00
|
|
|
TEST_VALUE_1 = "core_section_value1"
|
2020-06-23 05:45:16 +03:00
|
|
|
TEST_CONFIG_1 = {
|
2021-10-01 03:09:42 +03:00
|
|
|
"core": {
|
|
|
|
"section": {
|
|
|
|
"value": TEST_VALUE_1,
|
2020-06-23 05:45:16 +03:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-10-01 03:09:42 +03:00
|
|
|
TEST_VALUE_2 = "core_section_value2"
|
2020-06-23 05:45:16 +03:00
|
|
|
TEST_CONFIG_2 = {
|
2021-10-01 03:09:42 +03:00
|
|
|
"core": {
|
|
|
|
"section": {
|
|
|
|
"value": TEST_VALUE_2,
|
2020-06-23 05:45:16 +03:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def _copied(value):
|
|
|
|
return copy.deepcopy(value)
|
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
class Core(containers.DeclarativeContainer):
|
2021-10-01 03:09:42 +03:00
|
|
|
config = providers.Configuration("core")
|
2020-06-23 05:45:16 +03:00
|
|
|
value_getter = providers.Callable(lambda _: _, config.section.value)
|
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
class Application(containers.DeclarativeContainer):
|
2021-10-01 03:09:42 +03:00
|
|
|
config = providers.Configuration("config")
|
2021-10-18 23:19:03 +03:00
|
|
|
core = providers.Container(Core, config=config.core)
|
2020-06-23 05:45:16 +03:00
|
|
|
dict_factory = providers.Factory(dict, value=core.value_getter)
|
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test():
|
|
|
|
application = Application(config=_copied(TEST_CONFIG_1))
|
|
|
|
assert application.dict_factory() == {"value": TEST_VALUE_1}
|
2020-06-23 05:45:16 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_double_override():
|
|
|
|
application = Application()
|
|
|
|
application.config.override(_copied(TEST_CONFIG_1))
|
|
|
|
application.config.override(_copied(TEST_CONFIG_2))
|
|
|
|
assert application.dict_factory() == {"value": TEST_VALUE_2}
|
2021-01-12 16:41:59 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_override():
|
|
|
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/354
|
|
|
|
class D(containers.DeclarativeContainer):
|
|
|
|
foo = providers.Object("foo")
|
2021-01-12 16:41:59 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
class A(containers.DeclarativeContainer):
|
|
|
|
d = providers.DependenciesContainer()
|
|
|
|
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
|
2021-01-12 16:41:59 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
class B(containers.DeclarativeContainer):
|
|
|
|
d = providers.Container(D)
|
2021-01-12 16:41:59 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
a = providers.Container(A, d=d)
|
2021-01-27 22:01:33 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
b = B(d=D())
|
|
|
|
result = b.a().bar()
|
|
|
|
assert result == "foo++"
|
2021-01-27 22:01:33 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_override_not_root_provider():
|
|
|
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/379
|
|
|
|
class NestedContainer(containers.DeclarativeContainer):
|
|
|
|
settings = providers.Configuration()
|
|
|
|
|
|
|
|
print_settings = providers.Callable(
|
|
|
|
lambda s: s,
|
|
|
|
settings,
|
|
|
|
)
|
|
|
|
|
|
|
|
class TestContainer(containers.DeclarativeContainer):
|
|
|
|
settings = providers.Configuration()
|
|
|
|
|
|
|
|
root_container = providers.Container(
|
|
|
|
NestedContainer,
|
|
|
|
settings=settings,
|
|
|
|
)
|
2021-01-27 22:01:33 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
not_root_container = providers.Selector(
|
|
|
|
settings.container,
|
|
|
|
using_factory=providers.Factory(
|
|
|
|
NestedContainer,
|
|
|
|
settings=settings,
|
|
|
|
),
|
|
|
|
using_container=providers.Container(
|
2021-01-27 22:01:33 +03:00
|
|
|
NestedContainer,
|
|
|
|
settings=settings,
|
|
|
|
)
|
2021-10-18 23:19:03 +03:00
|
|
|
)
|
2021-01-27 22:01:33 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
container_using_factory = TestContainer(settings=dict(
|
|
|
|
container="using_factory",
|
|
|
|
foo="bar"
|
|
|
|
))
|
|
|
|
assert container_using_factory.root_container().print_settings() == {"container": "using_factory", "foo": "bar"}
|
|
|
|
assert container_using_factory.not_root_container().print_settings() == {"container": "using_factory", "foo": "bar"}
|
2021-01-27 22:01:33 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
container_using_container = TestContainer(settings=dict(
|
|
|
|
container="using_container",
|
|
|
|
foo="bar"
|
|
|
|
))
|
|
|
|
assert container_using_container.root_container().print_settings() == {"container": "using_container", "foo": "bar"}
|
|
|
|
assert container_using_container.not_root_container().print_settings() == {"container": "using_container", "foo": "bar"}
|
2021-01-27 22:01:33 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_override_by_not_a_container():
|
|
|
|
provider = providers.Container(Core)
|
|
|
|
|
|
|
|
with raises(errors.Error):
|
|
|
|
provider.override(providers.Object("foo"))
|
|
|
|
|
|
|
|
|
|
|
|
def test_lazy_overriding():
|
|
|
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/354
|
|
|
|
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()
|
|
|
|
assert result == "foo++"
|
|
|
|
|
|
|
|
|
|
|
|
def test_lazy_overriding_deep():
|
|
|
|
# Extended version of test_lazy_overriding()
|
|
|
|
class D(containers.DeclarativeContainer):
|
|
|
|
foo = providers.Object("foo")
|
|
|
|
|
|
|
|
class C(containers.DeclarativeContainer):
|
|
|
|
d = providers.DependenciesContainer()
|
|
|
|
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
|
|
|
|
|
|
|
|
class A(containers.DeclarativeContainer):
|
|
|
|
d = providers.DependenciesContainer()
|
|
|
|
c = providers.Container(C, d=d)
|
2021-01-12 16:41:59 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
class B(containers.DeclarativeContainer):
|
|
|
|
d = providers.DependenciesContainer()
|
2021-01-12 16:41:59 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
a = providers.Container(A, d=d)
|
2021-01-14 01:07:41 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
b = B(d=D())
|
|
|
|
result = b.a().c().bar()
|
|
|
|
assert result == "foo++"
|
2021-02-05 16:59:16 +03:00
|
|
|
|
2021-01-14 01:07:41 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_reset_last_overriding():
|
|
|
|
application = Application(config=_copied(TEST_CONFIG_1))
|
|
|
|
application.core.override(Core(config=_copied(TEST_CONFIG_2["core"])))
|
2021-01-14 01:07:41 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
application.core.reset_last_overriding()
|
2021-01-14 01:07:41 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
assert application.dict_factory() == {"value": TEST_VALUE_1}
|
2021-01-14 01:07:41 +03:00
|
|
|
|
2021-02-05 16:59:16 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_reset_last_overriding_only_overridden():
|
|
|
|
application = Application(config=_copied(TEST_CONFIG_1))
|
|
|
|
application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2["core"])))
|
2021-02-05 16:59:16 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
application.core.reset_last_overriding()
|
2021-02-05 16:59:16 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
assert application.dict_factory() == {"value": TEST_VALUE_1}
|
2021-02-05 16:59:16 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_override_context_manager():
|
|
|
|
application = Application(config=_copied(TEST_CONFIG_1))
|
|
|
|
overriding_core = Core(config=_copied(TEST_CONFIG_2["core"]))
|
2021-02-05 16:59:16 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
with application.core.override(overriding_core) as context_core:
|
|
|
|
assert application.dict_factory() == {"value": TEST_VALUE_2}
|
|
|
|
assert context_core() is overriding_core
|
2021-02-05 16:59:16 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
assert application.dict_factory() == {"value": TEST_VALUE_1}
|
2021-02-13 00:58:23 +03:00
|
|
|
|
2021-03-03 17:05:15 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_reset_override():
|
|
|
|
application = Application(config=_copied(TEST_CONFIG_1))
|
|
|
|
application.core.override(Core(config=_copied(TEST_CONFIG_2["core"])))
|
2021-03-03 17:05:15 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
application.core.reset_override()
|
2021-03-03 17:05:15 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
assert application.dict_factory() == {"value": None}
|
2021-03-03 17:05:15 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_reset_override_only_overridden():
|
|
|
|
application = Application(config=_copied(TEST_CONFIG_1))
|
|
|
|
application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2["core"])))
|
2021-03-03 17:05:15 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
application.core.reset_override()
|
2021-03-03 17:05:15 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
assert application.dict_factory() == {"value": None}
|
2021-03-03 17:05:15 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_assign_parent():
|
|
|
|
parent = providers.DependenciesContainer()
|
|
|
|
provider = providers.Container(Core)
|
2021-03-03 17:05:15 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
provider.assign_parent(parent)
|
2021-03-03 17:05:15 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
assert provider.parent is parent
|
2021-03-03 17:05:15 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_parent_name():
|
|
|
|
container = containers.DynamicContainer()
|
|
|
|
provider = providers.Container(Core)
|
|
|
|
container.name = provider
|
|
|
|
assert provider.parent_name == "name"
|
2021-03-03 17:05:15 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_parent_name_with_deep_parenting():
|
|
|
|
provider = providers.Container(Core)
|
|
|
|
container = providers.DependenciesContainer(name=provider)
|
|
|
|
_ = providers.DependenciesContainer(container=container)
|
|
|
|
assert provider.parent_name == "container.name"
|
2021-02-13 00:58:23 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_parent_name_is_none():
|
|
|
|
provider = providers.Container(Core)
|
|
|
|
assert provider.parent_name is None
|
2021-02-13 00:58:23 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_parent_deepcopy():
|
|
|
|
container = containers.DynamicContainer()
|
|
|
|
provider = providers.Container(Core)
|
|
|
|
container.name = provider
|
2021-02-13 00:58:23 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
copied = providers.deepcopy(container)
|
2021-02-13 00:58:23 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
assert container.name.parent is container
|
|
|
|
assert copied.name.parent is copied
|
2021-02-13 00:58:23 +03:00
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
assert container is not copied
|
|
|
|
assert container.name is not copied.name
|
|
|
|
assert container.name.parent is not copied.name.parent
|
2021-02-13 00:58:23 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_resolve_provider_name():
|
|
|
|
container = providers.Container(Core)
|
|
|
|
assert container.resolve_provider_name(container.value_getter) == "value_getter"
|
2021-02-13 00:58:23 +03:00
|
|
|
|
|
|
|
|
2021-10-18 23:19:03 +03:00
|
|
|
def test_resolve_provider_name_no_provider():
|
|
|
|
container = providers.Container(Core)
|
|
|
|
with raises(errors.Error):
|
|
|
|
container.resolve_provider_name(providers.Provider())
|