python-dependency-injector: Configuration raises AttributeError when provider is called
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’
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 21 (14 by maintainers)
Commits related to this issue
- Add strict config in ServiceContainer Update dependency-injector to v4.10.0 https://github.com/ets-labs/python-dependency-injector/issues/358 — committed to StefanoFrazzetto/symbiotic by deleted user 3 years ago
@Minitour ,
Here is a workaround for your problem:
The root cause of that issue is kind of tricky. I’ll check later if there is a good way to fix it.
@StefanoFrazzetto
I’ve created an issue for the
required
option: #369I think I can add this in version 4 since
strict
is a new feature. I’ll use your code sample from https://github.com/ets-labs/python-dependency-injector/issues/358#issuecomment-761611148. Here is an issue for this: #370In version 5,
strict=True
should become a default.Got it, will take a look later today.
This is not a bug, but a feature. It’s done that way to be able to put in a code multiple locations like:
In that case settings from
config.local.yaml
will override the settings fromconfig.yaml
. Ifconfig.local.yaml
does not exist, no error is expected.Hey @StefanoFrazzetto , got it, thanks for extra info. I see a bug now, fixing.