# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['witch_doctor']

package_data = \
{'': ['*']}

setup_kwargs = {
    'name': 'witch-doctor',
    'version': '1.2.0',
    'description': 'Dependency injection for python',
    'long_description': '<img src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.pinimg.com%2Foriginals%2Fe6%2Fff%2F86%2Fe6ff86db1ad224c37d328579786e13f3.jpg&f=1&nofb=1&ipt=448de94a888dd920ca7383f804f09f69d49ad4d226d9bee06115bbc9b188e1d2&ipo=images" alt="drawing" style="width:400px;display: block;  margin-left: auto;margin-right: auto;"/>\nBy: CenturyBoys\n\n# Witch-doctor\n\nA simple dependency injection for python\n\n## Register \n\nWitch Doctor provides a method to register interfaces, implementation, injection type, instance args and container name. \n\n- The interface and implementation inheritance will be checked and will raise a TypeError if was some issue.\n- The injection type will be checked and will raise a TypeError if was some issue. There are two types the singleton and factory types, the singleton will return the same instance for all injection and the factory will return a new instance for each injection.\n- If no values was giving will not pass the args to the class constructor.\n- The container name will segregate the injections by scopes.\n\n```python\nclass WitchDoctor:\n    @classmethod\n    def register(  # pylint: disable=R0913\n        cls,\n        interface: Type[ABC],\n        class_ref: Any,\n        injection_type: InjectionType,\n        args: List[any] = None,\n        container: str = DEFAULT,\n    ):\n        """\n        WitchDoctor.register will check inherit of the interface and class_ref.\n        Will raise a TypeError on validation error\\n\n        :param interface: Interface that inherits from ABC\n        :param class_ref: A implementation of the interface\n        :param injection_type: The injection type that must be used for this register. Allowed Factory or Singleton\n        :param args: List of args tha will be used to instantiate the class object\n        :param container: Container name where the reference will be saved.\n        """\n        pass\n```\n\n## Container\n\nYou can register your injections using containers. The method `contianer` will provide a container register with the same signature as teh register without the container param. To use the created container you need to load it using `load_container`.\nThe base work load will set all registers in the DEFAULT group\n\n```python\nfrom abc import ABC, abstractmethod\n\nfrom witch_doctor import WitchDoctor, InjectionType\n\nclass IStubFromABCClass(ABC):\n    @abstractmethod\n    def sum(self, a: int, b: int):\n        pass\n    \nclass StubFromABCClass(IStubFromABCClass):\n    def sum(self, a: int, b: int):\n        return a + b\n\ncontainer = WitchDoctor.container("prod")\nWitchDoctor.register(IStubFromABCClass, StubFromABCClass, InjectionType.SINGLETON)   \nWitchDoctor.load_container("prod")\n\n```\n## Injection \n\nWitch Doctor can be used as decorator. The function signature will ber check and if some values was not provide Witch Doctor will search on the registered interfaces to inject the dependencies.\n\n```python\nclass WitchDoctor:\n    @classmethod\n    def injection(cls, function: Callable):\n        """\n        WitchDoctor.injection is a function decorator that will match the\n        function params signature and inject the  dependencies.\n        Will raise AttributeError is some args was pass throw\\n\n\n        :type function: Callable\n        """\n        pass\n```\n\n## Usage example\n\n```python\nfrom abc import ABC, abstractmethod\n\nfrom witch_doctor import WitchDoctor, InjectionType\n\n\n# Abstract class\nclass IStubFromABCClass(ABC):\n    @abstractmethod\n    def sum(self, a: int, b: int):\n        pass\n\n    \n# Implementation\nclass StubFromABCClass(IStubFromABCClass):\n    def __init__(self, a: int):\n        self.a = a\n\n    def sum(self, a: int, b: int):\n        return a + b + self.a\n\n# Usage\n@WitchDoctor.injection\ndef func_t(a: int, b: int, c: IStubFromABCClass):\n    return c.sum(a, b)\n\n# Containers\ncontainer = WitchDoctor.container()\ncontainer(IStubFromABCClass, StubFromABCClass, InjectionType.FACTORY, args=[10])\n\ncontainer = WitchDoctor.container("prod")\ncontainer(IStubFromABCClass, StubFromABCClass, InjectionType.SINGLETON, args=[20])\n\n# Loading and using\nWitchDoctor.load_container()\n\nresult_a1 = func_t(a=1, b=2)\nresult_a2 = func_t(a=2, b=2)\n\nassert result_a1 == 13\nassert result_a2 == 14\n\nWitchDoctor.load_container("prod")\n\nresult_a1 = func_t(a=1, b=2)\nresult_a2 = func_t(a=2, b=2)\n\nassert result_a1 == 23\nassert result_a2 == 24\n```\n\n\n## Resolve \n\nWitch Doctor can be used by the method resolve. The class signature will ber check and search on the registered interfaces to inject the dependencies.\n\n\n```python\nclass WitchDoctor:\n    @classmethod\n    def resolve(cls, interface: T) -> Type[T]:\n        """\n        WitchDoctor.resolve will return an instance of the registered class_ref interface.\n        Will raise a TypeError if interface is not registered\\n\n        :param interface: A implementation of the interface\n        """\n        pass\n```\n\n## Usage example\n\n```python\nfrom abc import ABC, abstractmethod\n\nfrom witch_doctor import WitchDoctor, InjectionType\n\n\n# Abstract class\nclass IStubFromABCClass(ABC):\n    @abstractmethod\n    def sum(self, a: int, b: int):\n        pass\n\n    \n# Implementation\nclass StubFromABCClass(IStubFromABCClass):\n    def __init__(self, a: int):\n        self.a = a\n\n    def sum(self, a: int, b: int):\n        return a + b + self.a\n\n# Usage\n@WitchDoctor.injection\ndef func_t(a: int, b: int, c: IStubFromABCClass):\n    return c.sum(a, b)\n\n# Containers\ncontainer = WitchDoctor.container()\ncontainer(IStubFromABCClass, StubFromABCClass, InjectionType.FACTORY, args=[10])\n\n# Loading and using\nWitchDoctor.load_container()\n\nresult_a1 = WitchDoctor.resolve(IStubFromABCClass)\nresult_a2 = WitchDoctor.resolve(IStubFromABCClass)\n\n\n```',
    'author': 'Marco Sievers de Almeida Ximit Gaia',
    'author_email': 'im.ximit@gmail.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'None',
    'packages': packages,
    'package_data': package_data,
    'python_requires': '>=3.10,<4.0',
}


setup(**setup_kwargs)
