Injection on a decorator
See original GitHub issueHi, I really like this package and am using it in production. I was tying to mess around with decorators because I want to add side effects to a function, adding a secret_number
in the example. I was expecting decorated_function_1
to work but it didn’t and I can’t wrap my head around it. Is this an expected behavior? Could injection be supported like in my_decorator_1
?
I also added few examples of things I tried and only decorated_function_4
actually works.
from functools import wraps
from dependency_injector import containers, providers
from dependency_injector.wiring import Provide, inject
class Container(containers.DeclarativeContainer):
config = providers.Configuration()
@inject
def my_decorator_1(func, secret_number: int = Provide[Container.config.secret_number]):
@wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result + secret_number
return wrapper
@inject
def my_decorator_2(secret_number: int = Provide[Container.config.secret_number]):
def inner_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result + secret_number
return wrapper
return inner_decorator
def my_decorator_3():
@inject
def inner_decorator(func, secret_number: int = Provide[Container.config.secret_number]):
@wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result + secret_number
return wrapper
return inner_decorator
def my_decorator_4(func):
@wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
secret_number = kwargs['secret_number']
return result + secret_number
return wrapper
@my_decorator_1
def decorated_function_1():
return 42
@inject
@my_decorator_1
def decorated_function_1a():
return 42
@my_decorator_2()
def decorated_function_2():
return 42
@my_decorator_3()
def decorated_function_3():
return 42
@inject
@my_decorator_3()
def decorated_function_3a():
return 42
@inject
@my_decorator_4
def decorated_function_4(secret_number: int = Provide[Container.config.secret_number]):
return 42
@my_decorator_4
@inject
def decorated_function_4a(secret_number: int = Provide[Container.config.secret_number]):
return 42
def main():
test_funcs = [
decorated_function_1,
decorated_function_1a,
decorated_function_2,
decorated_function_3,
decorated_function_3a,
decorated_function_4,
decorated_function_4a,
]
for test_f in test_funcs:
try:
result = test_f()
print(f"Function {test_f} returned {result}")
except Exception as exc:
print(f"Function {test_f} raised {exc.__class__.__name__} '{exc}'")
if __name__ == '__main__':
import sys
container = Container()
container.init_resources()
container.config.secret_number.from_env("SECRET_INT", 24)
container.wire(modules=[sys.modules[__name__]])
main()
The output is:
Function <function decorated_function_1 at 0x7f93d8a4d310> raised TypeError 'unsupported operand type(s) for +: 'int' and 'Provide''
Function <function decorated_function_1a at 0x7f93d8a4d4c0> raised TypeError 'unsupported operand type(s) for +: 'int' and 'Provide''
Function <function decorated_function_2 at 0x7f93d8a4d670> raised TypeError 'unsupported operand type(s) for +: 'int' and 'Provide''
Function <function decorated_function_3 at 0x7f93d8a4d820> raised TypeError 'unsupported operand type(s) for +: 'int' and 'Provide''
Function <function decorated_function_3a at 0x7f93d8a4daf0> raised TypeError 'unsupported operand type(s) for +: 'int' and 'Provide''
Function <function decorated_function_4 at 0x7f93d8a4dca0> returned 66
Function <function decorated_function_4a at 0x7f93d8a4de50> raised KeyError ''secret_number''
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:9 (6 by maintainers)
Top Results From Across the Web
Dependency Injection using Decorators | by Chidume Nnamdi
Injection is the passing of a dependency to a dependent object. ... These decorator functions (@Inject, @Injectable) uses the Reflect library to add ......
Read more >Angular & Dependency Injection: tricks with Decorators
Angular & Dependency Injection: tricks with Decorators ... The Self Decorator limits the search for the dependency to the current injector.
Read more >Dependency Injection Decorators | LoopBack Documentation
The @inject decorator allows you to inject dependencies bound to any implementation of the Context object, such as an Application instance or a...
Read more >TypeScript class decorators incl. Dependency Injection example
Use a parameter decorator to mark the classes to be injected (here: @inject() ; commonly done in the constructor of that class, called ......
Read more >Angular | Inject service into decorator - Stack Overflow
Decorators are a TypeScript feature that work outside of Angular's dependency injection system. The only solution that I know of is to ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Running the example above we get the expected behaviour
If you try to remove this double
@wraps
call inhelper
the function name breaks:if I move the
@wraps
to the decorator(this I think should be the correct way) it breaks@inject
I have the fix! Working on merging it to develop.