'The main logic of decorator
Here is how those arguments works::
@out_decorator(*dec_args, *dec_kwargs)
def func(*wrap_args, **wrap_kwargs):
And in the ``wrapper``, we simply create ``self.target`` instance via
``with``::
target = self.get_target(*args, **kwargs)
with target(*dec_args, **dec_kwargs) as obj:'

def __call__(self, *dec_args, **dec_kwargs):

    (kw_name, dec_args, dec_kwargs) = self.process_decorator_args(*dec_args, **dec_kwargs)
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            target = self.get_target(*args, **kwargs)
            with target(*dec_args, **dec_kwargs) as obj:
                if (kw_name and (kw_name not in kwargs)):
                    kwargs[kw_name] = obj
                elif (kw_name and (kw_name in kwargs)):
                    raise TypeError("{0}()    got    multiple    values    for    argument    '{1}'".format(func.__name__, kw_name))
                else:
                    args = (args + (obj,))
                return func(*args, **kwargs)
        return wrapper
    return decorator
