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

An overridden provider is ignored when the override does not happen at the declaration place

Open chbndrhnns opened this issue 3 years ago • 0 comments

It seems that the library ignores an override if it is not done at the declaration place:

  • App has an instance of Controllers at controllers which has an instance of Services at services
  • Still, the override is only successful in the second test.

Is this by design? Did I miss some docs about it? Am I doing it wrong?

Example:

import pytest
from dependency_injector import containers as c
from dependency_injector import providers as p


class MyController:
    def __init__(self, service):
        self._service = service

    def run(self):
        return self._service.result()


class MyService:
    val = "result"

    def result(self):
        return self.val


class FakeService(MyService):
    val = "fake"


class Services(c.DeclarativeContainer):
    my_service = p.ContextLocalSingleton(MyService)


class Controllers(c.DeclarativeContainer):
    services = p.Container(Services)
    my_controller = p.ContextLocalSingleton(MyController, service=services.my_service)


class App(c.DeclarativeContainer):
    controllers: Controllers = p.Container(Controllers)


@pytest.fixture
def services():
    return Services()


@pytest.fixture
def container(services):
    controllers = Controllers(services=services)
    return App(controllers=controllers)


def test_override_where_used(container):
    container.controllers.services.my_service.override(p.Singleton(FakeService))
    controller = container.controllers.my_controller()
    assert controller.run() == FakeService.val


def test_override_where_declared(container, services):
    services.my_service.override(p.Singleton(FakeService))
    controller = container.controllers.my_controller()
    assert controller.run() == FakeService.val

chbndrhnns avatar Sep 14 '22 09:09 chbndrhnns