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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/dependency_injector/wiring.py
Original file line number Diff line number Diff line change
Expand Up @@ -959,8 +959,8 @@ def __getitem__(self, item) -> Self:
self.segments.append((self.TYPE_ITEM, item))
return self

def call(self) -> Self:
self.segments.append((self.TYPE_CALL, None))
def call(self, *args, **kwargs) -> Self:
self.segments.append((self.TYPE_CALL, (args, kwargs)))
return self

def modify(
Expand All @@ -975,7 +975,7 @@ def modify(
elif type_ == ProvidedInstance.TYPE_ITEM:
provider = provider[value]
elif type_ == ProvidedInstance.TYPE_CALL:
provider = provider.call()
provider = provider.call(*value[0], **value[1])
else:
assert_never(type_)
return provider
Expand Down
4 changes: 3 additions & 1 deletion tests/unit/samples/wiring/container.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dependency_injector import containers, providers

from .service import Service
from .service import Service, ServiceWithCallable


class SubContainer(containers.DeclarativeContainer):
Expand All @@ -14,4 +14,6 @@ class Container(containers.DeclarativeContainer):

service = providers.Factory(Service)

service_with_callable = providers.Factory(ServiceWithCallable)

sub = providers.Container(SubContainer)
21 changes: 21 additions & 0 deletions tests/unit/samples/wiring/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,27 @@ def test_provided_instance(some_value: int = Provide[Container.service.provided.
return some_value


@inject
def test_provided_instance_call_with_args(
some_value: int = Provide[Container.service_with_callable.provided.method_with_args.call(1, 2)]
Comment thread
ZipFile marked this conversation as resolved.
):
return some_value


@inject
def test_provided_instance_call_with_kwargs(
some_value: dict = Provide[Container.service_with_callable.provided.method_with_kwargs.call(a=1, b=2)]
):
return some_value


@inject
def test_provided_instance_call_with_args_and_kwargs(
some_value: dict = Provide[Container.service_with_callable.provided.foo.process.call(1, 2, key="value")]
):
return some_value


@inject
def test_subcontainer_provider(some_value: int = Provide[Container.sub.int_object]):
return some_value
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/samples/wiring/service.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
class Service:
service_attr: int


class ServiceWithCallable:
def __init__(self):
self.foo = CallableDict({"bar": lambda: 10})
Comment thread
ZipFile marked this conversation as resolved.

def method_with_args(self, x, y):
return x + y

def method_with_kwargs(self, **kwargs):
return kwargs


class CallableDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def process(self, *args, **kwargs):
return {"args": args, "kwargs": kwargs}
4 changes: 3 additions & 1 deletion tests/unit/samples/wiringstringids/container.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dependency_injector import containers, providers

from .service import Service
from .service import Service, ServiceWithCallable


class SubContainer(containers.DeclarativeContainer):
Expand All @@ -14,4 +14,6 @@ class Container(containers.DeclarativeContainer):

service = providers.Factory(Service)

service_with_callable = providers.Factory(ServiceWithCallable)

sub = providers.Container(SubContainer)
82 changes: 60 additions & 22 deletions tests/unit/samples/wiringstringids/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@
from typing import Callable

from dependency_injector.wiring import (
inject,
Provide,
Provider,
as_int,
as_float,
as_,
required,
as_float,
as_int,
inject,
invariant,
provided,
required,
)

from .container import Container
from .service import Service


service: Service = Provide["service"]
service_provider: Callable[..., Service] = Provider["service"]
undefined: Callable = Provide["undefined"]
Expand Down Expand Up @@ -55,22 +54,24 @@ def test_function(service: Service = Provide["service"]):


@inject
def test_function_provider(service_provider: Callable[..., Service] = Provider["service"]):
def test_function_provider(
service_provider: Callable[..., Service] = Provider["service"],
):
service = service_provider()
return service


@inject
def test_config_value(
value_int: int = Provide["config.a.b.c", as_int()],
value_float: float = Provide["config.a.b.c", as_float()],
value_str: str = Provide["config.a.b.c", as_(str)],
value_decimal: Decimal = Provide["config.a.b.c", as_(Decimal)],
value_required: str = Provide["config.a.b.c", required()],
value_required_int: int = Provide["config.a.b.c", required().as_int()],
value_required_float: float = Provide["config.a.b.c", required().as_float()],
value_required_str: str = Provide["config.a.b.c", required().as_(str)],
value_required_decimal: str = Provide["config.a.b.c", required().as_(Decimal)],
value_int: int = Provide["config.a.b.c", as_int()],
value_float: float = Provide["config.a.b.c", as_float()],
value_str: str = Provide["config.a.b.c", as_(str)],
value_decimal: Decimal = Provide["config.a.b.c", as_(Decimal)],
value_required: str = Provide["config.a.b.c", required()],
value_required_int: int = Provide["config.a.b.c", required().as_int()],
value_required_float: float = Provide["config.a.b.c", required().as_float()],
value_required_str: str = Provide["config.a.b.c", required().as_(str)],
value_required_decimal: str = Provide["config.a.b.c", required().as_(Decimal)],
):
return (
value_int,
Expand All @@ -87,25 +88,60 @@ def test_config_value(

@inject
def test_config_value_required_undefined(
value_required: int = Provide["config.a.b.c", required()],
value_required: int = Provide["config.a.b.c", required()],
):
return value_required


@inject
def test_provide_provider(service_provider: Callable[..., Service] = Provide["service.provider"]):
def test_provide_provider(
service_provider: Callable[..., Service] = Provide["service.provider"],
):
service = service_provider()
return service


@inject
def test_provider_provider(service_provider: Callable[..., Service] = Provider["service.provider"]):
def test_provider_provider(
service_provider: Callable[..., Service] = Provider["service.provider"],
):
service = service_provider()
return service


@inject
def test_provided_instance(some_value: int = Provide["service", provided().foo["bar"].call()]):
def test_provided_instance(
some_value: int = Provide["service", provided().foo["bar"].call()]
):
return some_value


@inject
def test_provided_instance_call_with_args(
some_value: int = Provide[
"service_with_callable",
provided().method_with_args.call(1, 2),
],
):
return some_value


@inject
def test_provided_instance_call_with_kwargs(
some_value: dict = Provide[
"service_with_callable",
provided().method_with_kwargs.call(a=1, b=2),
],
):
return some_value


@inject
def test_provided_instance_call_with_args_and_kwargs(
some_value: dict = Provide[
"service_with_callable", provided().foo.process.call(1, 2, key="value")
]
):
return some_value


Expand All @@ -115,14 +151,16 @@ def test_subcontainer_provider(some_value: int = Provide["sub.int_object"]):


@inject
def test_config_invariant(some_value: int = Provide["config.option", invariant("config.switch")]):
def test_config_invariant(
some_value: int = Provide["config.option", invariant("config.switch")]
):
return some_value


@inject
def test_provide_from_different_containers(
service: Service = Provide["service"],
some_value: int = Provide["int_object"],
service: Service = Provide["service"],
some_value: int = Provide["int_object"],
):
return service, some_value

Expand Down
19 changes: 19 additions & 0 deletions tests/unit/samples/wiringstringids/service.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
class Service:
service_attr: int


class ServiceWithCallable:
def __init__(self):
self.foo = CallableDict({"bar": lambda: 10})

def method_with_args(self, x, y):
return x + y

def method_with_kwargs(self, **kwargs):
return kwargs


class CallableDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def process(self, *args, **kwargs):
return {"args": args, "kwargs": kwargs}
15 changes: 15 additions & 0 deletions tests/unit/wiring/provider_ids/test_main_py36.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,21 @@ class TestService:
assert some_value == 10


def test_provided_instance_call_with_args():
some_value = module.test_provided_instance_call_with_args()
assert some_value == 3


def test_provided_instance_call_with_kwargs():
some_value = module.test_provided_instance_call_with_kwargs()
assert some_value == {"a": 1, "b": 2}


def test_provided_instance_call_with_args_and_kwargs():
some_value = module.test_provided_instance_call_with_args_and_kwargs()
assert some_value == {"args": (1, 2), "kwargs": {"key": "value"}}


def test_subcontainer():
some_value = module.test_subcontainer_provider()
assert some_value == 1
Expand Down
30 changes: 28 additions & 2 deletions tests/unit/wiring/string_ids/test_main_py36.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,21 @@ def resourceclosing_container(request):

def test_package_lookup():
from samples.wiringstringids.package import test_package_function

service = test_package_function()
assert isinstance(service, Service)


def test_package_subpackage_lookup():
from samples.wiringstringids.package.subpackage import test_package_function

service = test_package_function()
assert isinstance(service, Service)


def test_package_submodule_lookup():
from samples.wiringstringids.package.subpackage.submodule import test_function

service = test_function()
assert isinstance(service, Service)

Expand All @@ -75,7 +78,13 @@ def test_module_attributes_wiring():

def test_module_attribute_wiring_with_invalid_marker(container: Container):
from samples.wiringstringids import module_invalid_attr_injection
with raises(Exception, match=re.escape("Unknown type of marker {0}".format(module_invalid_attr_injection.service))):

with raises(
Exception,
match=re.escape(
"Unknown type of marker {0}".format(module_invalid_attr_injection.service)
),
):
container.wire(modules=[module_invalid_attr_injection])


Expand Down Expand Up @@ -182,7 +191,7 @@ def test_configuration_option():

def test_configuration_option_required_undefined(container: Container):
container.config.reset_override()
with raises(errors.Error, match="Undefined configuration option \"config.a.b.c\""):
with raises(errors.Error, match='Undefined configuration option "config.a.b.c"'):
module.test_config_value_required_undefined()


Expand All @@ -205,6 +214,21 @@ class TestService:
assert some_value == 10


def test_provided_instance_call_with_args():
some_value = module.test_provided_instance_call_with_args()
assert some_value == 3


def test_provided_instance_call_with_kwargs():
some_value = module.test_provided_instance_call_with_kwargs()
assert some_value == {"a": 1, "b": 2}


def test_provided_instance_call_with_args_and_kwargs():
some_value = module.test_provided_instance_call_with_args_and_kwargs()
assert some_value == {"args": (1, 2), "kwargs": {"key": "value"}}


def test_subcontainer():
some_value = module.test_subcontainer_provider()
assert some_value == 1
Expand Down Expand Up @@ -260,11 +284,13 @@ def test_unwire_class_method(container: Container):
def test_unwire_package_function(container: Container):
container.unwire()
from samples.wiringstringids.package.subpackage.submodule import test_function

assert isinstance(test_function(), Provide)


def test_unwire_package_function_by_reference(container: Container):
from samples.wiringstringids.package.subpackage import submodule

container.unwire()
assert isinstance(submodule.test_function(), Provide)

Expand Down
Loading