kodemore / kink

Dependency injection container made for Python
MIT License
397 stars 25 forks source link

Bug on files with `annotations` import #24

Closed mario-evo closed 2 years ago

mario-evo commented 2 years ago

Hello! Great project you got going in here - very useful.
I think I may have found a bug, @inject seems to fail when annotations is imported. This is a mini example of what I have found.

from __future__ import annotations
from kink import inject

@inject
class ClassB(object):
    def __init__(self) -> None:
        pass

@inject
class ClassA(object):
    def __init__(self, class_b: ClassB):
        self._class_b = class_b

example = ClassA()

Running the above blows up:

Traceback (most recent call last):
  File "example.py", line 16, in <module>
    example = ClassA()
  File "/home/x/.local/lib/python3.8/site-packages/kink/inject.py", line 119, in _decorated
    all_kwargs = _resolve_kwargs(args, kwargs)
  File "/home/x/.local/lib/python3.8/site-packages/kink/inject.py", line 103, in _resolve_kwargs
    raise ExecutionError(
kink.errors.execution_error.ExecutionError: Cannot execute function without required parameters. Did you forget to bind the following parameters: `class_b`?

But if the from __future__ import annotations import is removed everything works as expected. I tried the above with both python3.8 and python3.9 and I'm on Ubuntu 20.04 .

dkraczkowski commented 2 years ago

@mario-evo Thanks for spotting this out. I will have a look at this before the end of the week and will see what I can do.

dkraczkowski commented 2 years ago

@mario-evo, I have found the issue; the problem is within forward-references and how they are represented in python when you use from __future__ import annotations. Long story short, they are represented as a string, and string is not recognized as a valid type.

I have a fix prepared and should be ready for today.

dkraczkowski commented 2 years ago

@mario-evo https://github.com/kodemore/kink/pull/26/files#diff-232d01f8e8b2876becd2d1f5cbb531af4e928007f9f829b4b32440c4e1d2aae7. There is a limitation to this solution. Keep in mind if classes are not defined in the root scope of the module, kink cannot recognize them properly and auto-wire them.

The new version will be deployed shortly.

mario-evo commented 2 years ago

@dkraczkowski Thanks for the support! :beer: