Python decorator for optional arguments decorator
The code looks rather complicated. Instead of trying to understand it, I'd just like to point to NickC's answer to the linked SO question.

If I add **kwargs to his optional_arg_decorator like this...

def optional_arg_decorator(fn):
    def wrapped_decorator(*args, **kwargs):
        if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
            return fn(args[0])

        else:
            def real_decorator(decoratee):
                return fn(decoratee, *args, **kwargs)

            return real_decorator

    return wrapped_decorator    


...and adapt your decorators like this, I'm getting the same output from the test cases.        

from functools import wraps

@optional_arg_decorator
def my_text_decorator(f, start_val="-=[", end_val="]=-"):
    @wraps(f)
    def wrapper(*args, **kwargs):
        return "".join([f.__name__, ' ', start_val,
                        f(*args, **kwargs), end_val])
    return wrapper

@optional_arg_decorator
def my_text_decorator2(f, start_val, end_val="]=-"):
    @wraps(f)
    def wrapper(*args, **kwargs):
        return "".join([f.__name__, ' ', start_val,
                        f(*args, **kwargs), end_val])
    return wrapper