Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken wiring of sync inject-decorated methods #672

Open
martlaf opened this issue Feb 28, 2023 · 4 comments · May be fixed by #673
Open

Broken wiring of sync inject-decorated methods #672

martlaf opened this issue Feb 28, 2023 · 4 comments · May be fixed by #673

Comments

@martlaf
Copy link

martlaf commented Feb 28, 2023

Hi,

following use case seems broken in versions >= 4.39.0:

from dependency_injector import containers, providers
from dependency_injector.wiring import inject, Provide


class Service:
    @staticmethod
    def run():
        print("hello world!")


class Container(containers.DeclarativeContainer):
    service = providers.Factory(Service)


class MyClass:
    @inject
    def __init__(self, service=Provide[Container.service]):
        service.run()


container = Container()
container.wire(modules=[MyClass])
MyClass()

Output in version 4.38.0:

hello world!

Output in versions >4.38.0

Traceback (most recent call last):
  File "C:\Users\myself\file.py", line 23, in <module>
    MyClass()
  File "src/dependency_injector/_cwiring.pyx", line 28, in dependency_injector._cwiring._get_sync_patched._patched
  File "C:\Users\myself\file.py", line 18, in __init__
    service.run()
AttributeError: 'Provide' object has no attribute 'run'

What seem to happen is that since the _get_sync_patched decorator has been moved to the cython part of the package, the signature of the @inject-decorated func/methods are now cython (type(MyClass.__init__) resolves to cython_function_or_method), therefore inspect.isfunction()/inspect.ismethod() resolve to False, and so those functions are never patched during container wiring.

Might be related to #589.

Finally, I have successfully tested here using the same patch that was applied in 4.39.1 for _get_async_patched coroutine that wasn't properly signed from cython coroutine, so creating the _get_sync_patched in wiring.py that calls _cwiring's _sync_inject, which effectively conserves behavior when running wiring.

@martlaf martlaf linked a pull request Feb 28, 2023 that will close this issue
@sgenya
Copy link

sgenya commented Apr 9, 2023

@rmk135 Would it be possible to release a fix for this bug in an upcoming release?

@yakimka
Copy link

yakimka commented Aug 28, 2023

Any updates?

@Astral1020
Copy link

Any updates? I have same issue, For now I just using dependency-injector==4.38.0

@tsdaemon
Copy link

I have a similar issue. Is there a workaround?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants