-
-
Notifications
You must be signed in to change notification settings - Fork 337
Description
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'