Skip to content

Configuration raises AttributeError when provider is called #358

@StefanoFrazzetto

Description

@StefanoFrazzetto

Hi, I just run into this issue with the Configuration provider. After scratching my head for a bit, I managed to find a workaround, but I was wondering if this is actually a bug or just something wrong I am doing. Any help would be appreciated!

Steps to reproduce

containers.py

from dependency_injector import providers, containers

class MyService(object):
    def __init__(self, **kwargs):
        self.key = kwargs.pop('key')

    def trigger(self):
        pass

class MyDevice(object):
    def __init__(self, **kwargs):
        # doesn't raise an error because it's an instance of
        # dependency_injector.providers.Singleton
        self.service = kwargs.pop('service')

    def do_something(self):
        # raises "AttributeError: 'NoneType' object has no attribute 'get'"
        self.service().trigger()

class ServiceContainer(containers.DeclarativeContainer):
    config = providers.Configuration()

    myservice = providers.Singleton(MyService, config=config.myservice)


class Container(containers.DeclarativeContainer):
    config = providers.Configuration()

    services = providers.Container(ServiceContainer, config=config.services)

    mydevice = providers.Factory(MyDevice)

If I run app.py

import sys

from containers import Container

container = Container()
container.config.from_yaml('config.yaml')
container.init_resources()
container.wire(modules=[sys.modules[__name__]])

mydevice = container.mydevice(service=container.services.myservice)
mydevice.do_something()

with config.yaml

foo:
  bar: 42

it raises the following error

File "/home/stefano/personal/test-error/containers.py", line 15, in do_something
self.service().trigger()
File "src/dependency_injector/providers.pyx", line 168, in dependency_injector.providers.Provider.call
File "src/dependency_injector/providers.pyx", line 2245, in dependency_injector.providers.Singleton._provide
File "src/dependency_injector/providers.pxd", line 550, in dependency_injector.providers.__factory_call
File "src/dependency_injector/providers.pxd", line 536, in dependency_injector.providers.__callable_call
File "src/dependency_injector/providers.pxd", line 495, in dependency_injector.providers.__call
File "src/dependency_injector/providers.pxd", line 387, in dependency_injector.providers.__provide_keyword_args
File "src/dependency_injector/providers.pxd", line 310, in dependency_injector.providers.__get_value
File "src/dependency_injector/providers.pyx", line 168, in dependency_injector.providers.Provider.call
File "src/dependency_injector/providers.pyx", line 1232, in dependency_injector.providers.ConfigurationOption._provide
File "src/dependency_injector/providers.pyx", line 1467, in dependency_injector.providers.Configuration.get
AttributeError: 'NoneType' object has no attribute 'get'

Workaround
To avoid the issue, I have to pass the whole config to ServiceContainer

class ServiceContainer(containers.DeclarativeContainer):
    config = providers.Configuration()

    myservice = providers.Singleton(MyService, config=config.services.myservice)


class Container(containers.DeclarativeContainer):
    config = providers.Configuration()

    services = providers.Container(ServiceContainer, config=config)

    mydevice = providers.Factory(MyDevice)

Running the application now, raises the following (as expected)

File "/home/stefano/personal/test-error/containers.py", line 18, in do_something
self.service().trigger()
File "src/dependency_injector/providers.pyx", line 168, in dependency_injector.providers.Provider.call
File "src/dependency_injector/providers.pyx", line 2245, in dependency_injector.providers.Singleton._provide
File "src/dependency_injector/providers.pxd", line 550, in dependency_injector.providers.__factory_call
File "src/dependency_injector/providers.pxd", line 536, in dependency_injector.providers.__callable_call
File "src/dependency_injector/providers.pxd", line 526, in dependency_injector.providers.__call
File "/home/stefano/personal/test-error/containers.py", line 5, in init
self.key = kwargs.pop('key')
KeyError: 'key'

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions