def get_decorator_from_wrapper(wrapper_func):
    """Return decorator function from a wrapper function.

    That is, this function allows a function A which is
    used to wrap a function B with extra behaviour to be
    used as a decorator with arguments.

    In other words, it turns the pattern below:
    # func_c = func_a(func_b, *args, **kwargs)

    Into the pattern below
    # @func_a(*args, **kwargs)
    # def func_b(...):
    # ...
    """

    def get_decorator(*args, **kwargs):
        """Return decorator function.

        Used to collect positional and keyword arguments.
        So they can be used by the decorator which it
        returns.
        """

        def get_wrapped_func(func):
            """Wrap function w/ args and return it."""
            wrapped_func = wrapper_func(func, *args, **kwargs)
            return wrapped_func

        return get_wrapped_func

    return get_decorator
Return decorator function from a wrapper function.

    That is, this function allows a function A which is
    used to wrap a function B with extra behaviour to be
    used as a decorator with arguments.

    In other words, it turns the pattern below:
    # func_c = func_a(func_b, *args, **kwargs)

    Into the pattern below
    # @func_a(*args, **kwargs)
    # def func_b(...):
    # ...
    
nodezator/ourstdlibs/behaviour.py