Exemplo n.º 1
0
    def resolve(self, obj, *resolving_arguments):
        """Takes an object such as a function or class method and resolves it's
        parameters from objects in the container.

        Arguments:
            obj {object} -- The object you want to resolve objects from via this container.

        Returns:
            object -- The object you tried resolving but with the correct dependencies injected.
        """
        provider_list = []
        passing_arguments = list(resolving_arguments)

        for _, value in self.get_parameters(obj):
            if ':' in str(value):
                provider_list.append(self._find_annotated_parameter(value))
            elif self.resolve_parameters:
                provider_list.append(self._find_parameter(value))
            elif resolving_arguments:
                try:
                    provider_list.append(passing_arguments.pop(0))
                except IndexError:
                    raise ContainerError(
                        'Not enough dependencies passed. Resolving object needs {} dependencies.'
                        .format(len(inspect.signature(obj).parameters)))
            else:
                raise ContainerError(
                    "This container is not set to resolve parameters. You can set this in the container"
                    " constructor using the 'resolve_parameters=True' keyword argument."
                )
        try:
            return obj(*provider_list)
        except TypeError as e:
            raise ContainerError(str(e))
Exemplo n.º 2
0
    def load(self, directories, instantiate=False):
        """Load all classes found in a list of directories into the container.

        Arguments:
            directories {list} -- List of directories to search.

        Keyword Arguments:
            instantiate {bool} -- Whether or not to instantiate the class (default: {False})

        Raises:
            ContainerError -- Thrown when the container is not loaded into the class.
            AutoloadContainerOverwrite -- Thrown when the container already has the key binding.
        """

        self.instantiate = instantiate
        if not self.app:
            raise ContainerError(
                'Container not specified. Pass the container into the constructor')

        for (module_loader, name, ispkg) in pkgutil.iter_modules(directories):
            search_path = module_loader.path
            for obj in inspect.getmembers(self._get_module_members(module_loader, name)):

                # If the object is a class and the objects module starts with the search path
                if inspect.isclass(obj[1]) and obj[1].__module__.split('.')[:-1] == search_path.split('/'):
                    if self.app.has(obj[1].__name__) and not self.app.make(obj[1].__name__).__module__.startswith(search_path):
                        raise AutoloadContainerOverwrite(
                            'Container already has the key: {}. Cannot overwrite a container key that exists outside of your application.'.format(obj[1].__name__))
                    self.app.bind(obj[1].__name__, self._can_instantiate(obj))
Exemplo n.º 3
0
Arquivo: app.py Projeto: theodesp/core
    def _find_annotated_parameter(self, parameter):
        """Find a given annotation in the container.

        Arguments:
            parameter {object} -- The object to find in the container.

        Raises:
            ContainerError -- Thrown when the dependency is not found in the container.

        Returns:
            object -- Returns the object found in the container.
        """

        for dummy, provider_class in self.providers.items():
            
            if parameter.annotation == provider_class or parameter.annotation == provider_class.__class__:
                obj = provider_class
                self.fire_hook('resolve', parameter, obj)
                return obj
            elif inspect.isclass(provider_class) and issubclass(provider_class, parameter.annotation) or issubclass(provider_class.__class__, parameter.annotation):
                obj = provider_class
                self.fire_hook('resolve', parameter, obj)
                return obj

        raise ContainerError(
            'The dependency with the {0} annotation could not be resolved by the container'.format(parameter))
Exemplo n.º 4
0
    def _find_parameter(self, keyword):
        """Find a parameter in the container.

        Arguments:
            parameter {inspect.Paramater} -- Parameter to search for.

        Raises:
            ContainerError -- Thrown when the dependency is not found in the container.

        Returns:
            object -- Returns the object found in the container
        """
        parameter = str(keyword)

        if parameter != 'self' and parameter in self.providers:
            obj = self.providers[parameter]
            self.fire_hook('resolve', parameter, obj)
            return obj
        elif '=' in parameter:
            return keyword.default

        raise ContainerError(
            'The parameter dependency with the key of {0} could not be found in the container'.format(
                parameter)
        )
Exemplo n.º 5
0
 def _find_parameter(self, parameter):
     """
     Find a parameter in the container
     """
     parameter = str(parameter)
     if parameter is not 'self' and parameter in self.providers:
         return self.providers[parameter]
     
     raise ContainerError(
         'The dependency with the key of {0} could not be found in the container'.format(parameter)
     )
Exemplo n.º 6
0
    def _find_annotated_parameter(self, parameter):
        """
        Find a given annotation in the container
        """
        for provider, provider_class in self.providers.items():

            if parameter.annotation == provider_class or parameter.annotation == provider_class.__class__:
                return provider_class
            elif inspect.isclass(provider_class) and issubclass(provider_class, parameter.annotation):
                return provider_class
        
        raise ContainerError('The dependency with the {0} annotation could not be resolved by the container'.format(parameter))
Exemplo n.º 7
0
    def _find_parameter(self, parameter):
        """Find a parameter in the container.

        Arguments:
            parameter {string} -- Parameter to search for.

        Raises:
            ContainerError -- Thrown when the dependency is not found in the container.

        Returns:
            object -- Returns the object found in the container
        """
        parameter = str(parameter)
        if parameter is not 'self' and parameter in self.providers:
            obj = self.providers[parameter]
            self.fire_hook('resolve', parameter, obj)
            return obj
        raise ContainerError(
            'The dependency with the key of {0} could not be found in the container'
            .format(parameter))
Exemplo n.º 8
0
    def load(self, directories, instantiate=False):
        self.instantiate = instantiate
        if not self.app:
            raise ContainerError(
                'Container not specified. Pass the container into the constructor'
            )

        for (module_loader, name, ispkg) in pkgutil.iter_modules(directories):
            search_path = module_loader.path
            for obj in inspect.getmembers(
                    self._get_module_members(module_loader, name)):

                # If the object is a class and the objects module starts with the search path
                if inspect.isclass(obj[1]) and obj[1].__module__.startswith(
                        search_path.replace('/', '.')):
                    if self.app.has(obj[1].__name__) and not self.app.make(
                            obj[1].__name__).__module__.startswith(
                                search_path):
                        raise AutoloadContainerOverwrite(
                            'Container already has the key: {}. Cannot overwrite a container key that exists outside of your application.'
                            .format(obj[1].__name__))
                    self.app.bind(obj[1].__name__, self._can_instantiate(obj))
Exemplo n.º 9
0
    def resolve(self, obj, *resolving_arguments):
        """Takes an object such as a function or class method and resolves it's
        parameters from objects in the container.

        Arguments:
            obj {object} -- The object you want to resolve objects from via this container.

        Returns:
            object -- The object you tried resolving but with the correct dependencies injected.
        """
        objects = []
        passing_arguments = list(resolving_arguments)
        if self.remember and obj in self._remembered:
            objects = self._remembered[obj]
            try:
                return obj(*objects)
            except TypeError as e:
                raise ContainerError(str(e))
        elif self.remember and not passing_arguments and inspect.ismethod(obj) and "{}.{}.{}".format(obj.__module__, obj.__self__.__class__.__name__, obj.__name__) in self._remembered:
            location = "{}.{}.{}".format(obj.__module__, obj.__self__.__class__.__name__, obj.__name__)
            objects = self._remembered[location]
            try:
                return obj(*objects)
            except TypeError as e:
                raise ContainerError(str(e))
        else:
            for _, value in self.get_parameters(obj):
                if ':' in str(value):
                    param = self._find_annotated_parameter(value)
                    if inspect.isclass(param):
                        param = self.resolve(param)
                    objects.append(param)
                elif '=' in str(value):
                    objects.append(value.default)
                elif '*' in str(value):
                    continue
                elif self.resolve_parameters:
                    objects.append(self._find_parameter(value))
                elif resolving_arguments:
                    try:
                        objects.append(passing_arguments.pop(0))
                    except IndexError:
                        raise ContainerError('Not enough dependencies passed. Resolving object needs {} dependencies.'.format(len(inspect.signature(obj).parameters)))
                else:
                    raise ContainerError(
                        "This container is not set to resolve parameters. You can set this in the container"
                        " constructor using the 'resolve_parameters=True' keyword argument.")
        try:
            if self.remember:
                if not inspect.ismethod(obj):
                    self._remembered[obj] = objects
                else:
                    signature = "{}.{}.{}".format(obj.__module__, obj.__self__.__class__.__name__, obj.__name__)
                    self._remembered[signature] = objects
            return obj(*objects)
        except (TypeError,) as e:
            import sys
            import traceback
            exception = ContainerError(str(e))
            exc_type, exc_obj, exc_tb = sys.exc_info()
            exception.__class__.extras = [exc_type, exc_obj, exc_tb]
            exception.__class__.tb = traceback.extract_tb(exc_tb)
            exception.__class__.file = obj.__code__.co_filename
            raise exception from e
Exemplo n.º 10
0
 def __init__(self, z):
     y = x
     self.z = z
     raise ContainerError('Something Broke!')