question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Configuration raises AttributeError when provider is called

See original GitHub issue

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’

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:21 (14 by maintainers)

github_iconTop GitHub Comments

1reaction
rmk135commented, Jan 27, 2021

@Minitour ,

Here is a workaround for your problem:

def handle(event, context):
    container = Container()
    config = container.ingestion_config()  # <------ This line crashes in AWS Lambda
    ...

The root cause of that issue is kind of tricky. I’ll check later if there is a good way to fix it.

1reaction
rmk135commented, Jan 21, 2021

@StefanoFrazzetto

I’ve created an issue for the required option: #369

By the way, I still believe an exception should be raised when using a strict config. Maybe that’s something you could consider with 5.x.x?

I 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: #370

In version 5, strict=True should become a default.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Bountysource
Configuration raises AttributeError when provider is called.
Read more >
Correct handling of AttributeError in __getattr__ when using ...
Called when the default attribute access fails with an AttributeError [...] or __get__() of a name property raises AttributeError.
Read more >
Configuration provider - Dependency Injector
If configuration file is mandatory, use required argument. Configuration provider will raise an error if required file does not exist. You can also...
Read more >
Python Asyncio Part 3 – Asynchronous Context Managers and ...
Some sort of resource acquisition or setup is performed for FlowProvider and the result is bound to the name provider . Some extra...
Read more >
IonQ Backends — Qiskit IonQ Provider 0.0.1 documentation
IonQBackend(configuration, provider=None, **fields)[source]¶. IonQ Backend base class. ... Raises. AttributeError – if input field not a valid options.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found