Skip to content

Commit

Permalink
fix: return class in injectable decorator (#59)
Browse files Browse the repository at this point in the history
* fix: return class in injectable decorator

# Proposal
Linked to #58

The issue with the Injectable decorator returning a string instead of the class itself likely stems from the decorator definition.

In the definition of Injectable, cls is treated as if it could potentially be a string (cls: str = None), which suggests that the decorator might be designed to accept optional parameters or configurations. However, if not handled properly, this design could lead to unexpected behavior, such as treating a class definition as a string.

# Correcting the Injectable Decorator
The decorator needs to correctly handle both cases: when it is used with and without parameters. Here’s a more standard way of creating a decorator that can optionally accept arguments

# Explanation
1. Decorator Factory: The Injectable function can now correctly handle being called either as @Injectable or @Injectable(). It uses a nested decorator function to apply the actual class modifications.

2. Class Modifications: It checks if the class has an __init__ method defined and, if not, assigns a default one. It then parses dependencies, sets necessary attributes, and applies injection.

3. Handling Arguments: The outer function (Injectable) checks if it is given a class directly (cls is not None). If so, it directly returns the decorator applied to the class. Otherwise, it returns the decorator function itself, allowing for further customization or arguments.

* fix: use elipsis instead of pass
  • Loading branch information
Ignacio-Freire authored May 20, 2024
1 parent bc26d1e commit 21e6b04
Showing 1 changed file with 24 additions and 22 deletions.
46 changes: 24 additions & 22 deletions nest/core/decorators/injectable.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
from injector import inject

from nest.common.constants import DEPENDENCIES, INJECTABLE_NAME, INJECTABLE_TOKEN
from nest.core.decorators.utils import get_instance_variables, parse_dependencies


def Injectable(cls: str = None):
def __init__(self, *args, **kwargs):
...

if "__init__" in cls.__dict__:
pass
else:
cls.__init__ = __init__

dependencies = parse_dependencies(cls)

setattr(cls, DEPENDENCIES, dependencies)

setattr(cls, INJECTABLE_TOKEN, True)
setattr(cls, INJECTABLE_NAME, cls.__name__)

inject(cls)

return cls
from nest.core.decorators.utils import parse_dependencies


def Injectable(cls=None, *args, **kwargs):
def decorator(inner_cls):
if "__init__" not in inner_cls.__dict__:
def __init__(self, *args, **kwargs):
...
inner_cls.__init__ = __init__

dependencies = parse_dependencies(inner_cls)

setattr(inner_cls, DEPENDENCIES, dependencies)
setattr(inner_cls, INJECTABLE_TOKEN, True)
setattr(inner_cls, INJECTABLE_NAME, inner_cls.__name__)

inject(inner_cls)

return inner_cls

if cls is not None:
return decorator(cls)

return decorator

0 comments on commit 21e6b04

Please sign in to comment.