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
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.
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.
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.
Tests results
❯ pytest
============================================ test session starts ============================================
platform linux -- Python 3.11.7, pytest-8.2.0, pluggy-1.5.0
rootdir: /projects/personal/PyNest
configfile: pyproject.toml
plugins: anyio-4.3.0
collected 20 items
tests/test_core/test_database/test_odm.py ... [ 15%]
tests/test_core/test_database/test_orm.py .... [ 35%]
tests/test_core/test_decorators/test_controller.py ..... [ 60%]
tests/test_core/test_pynest_application.py ... [ 75%]
tests/test_core/test_pynest_container.py .. [ 85%]
tests/test_core/test_pynest_factory.py ... [100%]
============================================= warnings summary ==============================================
tests/test_core/test_decorators/test_controller.py:6
cannot collect test class 'TestController' because it has a __init__ constructor (from: tests/test_core/test_decorators/test_controller.py)
@Controller(prefix="api/v1/user", tag="test")
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================================= 20 passed, 1 warning in 0.26s =======================================
Proposal
Linked to issue https://github.com/PythonNest/PyNest/issues/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
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.
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.
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.
Tests results