def decorator(func):
    """Helper function to create decorators with optional arguments"""

    def _wrapper(*args, **kwargs):
        if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
            # We only have the function as parameter, so directly call the
            # decorator function
            return func(*args, **kwargs)

        # We have parameters, so we define a functor to use as decorator
        def _functor(user_func):
            return func(user_func, *args, **kwargs)

        return _functor

    # Be a well-behaved decorator by copying name, documentation and attributes
    _wrapper.__name__ = func.__name__
    _wrapper.__doc__ = func.__doc__
    _wrapper.__dict__.update(func.__dict__)
    return _wrapper