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.

Injection not working for class methods

See original GitHub issue

I am not quite sure if this is expected behavior or not. Methods annotated as @classmethod end up getting extra parameters injected. The following code demonstrates. I discovered this while using Closing, but filled out the example a bit as I discovered that it is a general issue for Provide.

import sys
from dependency_injector import containers, providers
from dependency_injector.wiring import Provide, Closing


def my_factory():
    return 'test-factory'


def my_resource():
    yield 'test-resource'
    print('Closing')


class Container(containers.DeclarativeContainer):

    factory = providers.Factory(my_factory)
    resource = providers.Resource(my_resource)


def do_function_thing(r:str=Closing[Provide[Container.resource]]) -> None:
    print('from function', r)


class MyClass():

    def do_instance_thing(self, r:str=Closing[Provide[Container.resource]]) -> None:
        print('from instance', r)

    @classmethod
    def do_class_thing(cls, r:str=Closing[Provide[Container.resource]]) -> None:
        print('from class', r)

    @classmethod
    def non_closing_class_thing(cls, r:str=Provide[Container.factory]) -> None:
        print('non-closing from class', r)


container = Container()
container.init_resources()
container.wire(modules=[sys.modules[__name__]])


do_function_thing()
c = MyClass()
c.do_instance_thing()

# both of these end up getting multiple values for r:
c.non_closing_class_thing()
c.do_class_thing()

The resulting output is:

from function test-resource
Closing
from instance test-resource
Closing
Traceback (most recent call last):
  File "clstest.py", line 49, in <module>
    c.non_closing_class_thing()
  File "/Users/scott/repos/github.com/scott2b/Starlight/.venv/lib/python3.8/site-packages/dependency_injector/wiring.py", line 296, in _patched
    result = fn(*args, **to_inject)
TypeError: non_closing_class_thing() got multiple values for argument 'r'

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:19 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
rmk135commented, Nov 4, 2020

Thank you @scott2b .

1reaction
rmk135commented, Nov 4, 2020

Yep, that’s kind of known thing that classmethod should be on the very top of decorators. What actually happens is that classmethod returns an object that is treated special way by the class. If it’s not on the top, the class recognizes it as usual method. What DI does is “undecorating” of the method to get the original, decorating the original with injecting decorator and then decorating it back as classmethod.

Read more comments on GitHub >

github_iconTop Results From Across the Web

dependency injection not working in data class "an object ...
I need to do this via dependency injection instead, and got the injection to work in my class, however, I can't use a...
Read more >
Dependency injection - .NET | Microsoft Learn
Examine the following MessageWriter class with a Write method that other classes ... Dependency injection addresses these problems through:.
Read more >
Dependency Injection
Method Injection : In this type of injection, the client class implements an interface which declares the method(s) to supply the dependency and...
Read more >
Contexts and Dependency Injection
This behavior is defined by CDI. But producer methods and fields and observer methods are discovered even if the declaring class is not...
Read more >
Inject (Java EE 6 )
Ordering of injection among fields and among methods in the same class is not ... Circular dependencies between two constructors is an obvious...
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