python-dependency-injector icon indicating copy to clipboard operation
python-dependency-injector copied to clipboard

Provided type not checked when creating container with arguments

Open chbndrhnns opened this issue 4 years ago • 1 comments

When I try to create a container, it seems there are no checks in place which prevent me from passing in an instance of an incorrect type.

I declared a provided_type field for my custom factory class as described.

Or, is the error rather on my side and I am using the library in an incorrect way?

I expect the test test_incorrect_type_instanciation to pass. Instead, no exception is raised:

def test_incorrect_type_instanciation():
        service = object()
>       with pytest.raises(Exception):
E       Failed: DID NOT RAISE <class 'Exception'>

container_types.py:30: Failed
Click to toggle
import pytest
from dependency_injector import containers, providers


class BaseService:
    ...


class ServiceProvider(providers.Factory):
    provided_type = BaseService


class Application(containers.DeclarativeContainer):
    service = ServiceProvider(BaseService)


def test_ok():
    c = Application()
    assert isinstance(c.service(), BaseService)


def test_incorrect_type_declaration():
    with pytest.raises(Exception):
        class Container(containers.DeclarativeContainer):
            service = ServiceProvider(object)


def test_incorrect_type_instanciation():
    service = object()
    with pytest.raises(Exception):
        c = Application(service=service)
        c.service()

chbndrhnns avatar Sep 11 '21 11:09 chbndrhnns

Hi @chbndrhnns. Yeah, that's confusing, thanks for bringing up the issue. As a workaround, to achieve what you're looking for you can use a combination of Factory and Dependency provider. Tests pass with the code below:

class Application(containers.DeclarativeContainer):
    service = providers.Dependency(BaseService, default=ServiceProvider(BaseService))

Dependency provider makes a runtime check for the provided instance. Factory provider uses provided_type only during provider initialization. In the example you provided the provider is overridden with another provider, and this is not covered. Need to fix the overriding so that c = Application(service=object()) raises an error or introduce a runtime check for the factory, like in Dependency provider.

rmk135 avatar Sep 13 '21 00:09 rmk135

Need to fix the overriding so that c = Application(service=object()) raises an error or introduce a runtime check for the factory, like in Dependency provider.

I would very much like to see this to reduce runtime errors of my application.

chbndrhnns avatar Oct 25 '22 11:10 chbndrhnns