When generating API stubs with the scaffold utility using, e.g., `python -m localstack.aws.scaffold sns`,
the scaffold creates method names from operation names, which are ugly when acronyms (subsequent uppercase characters that belong together).

Example:
`CreateSMSSandboxPhoneNumber` -> `create_s_m_s_sandbox_phone_number`

it would be nicer to have `create_sms_sandbox_phone_number`

This is a limitation of this method: https://github.com/localstack/localstack/blob/1888e66b85d7e6a8ee457bc7a732984fcf7aa830/localstack/utils/common.py#L978-L979
"""Function decorator to protect a function from stack overflows -
    raises an exception if a (potential) infinite recursion is detected."""
    def _decorator(wrapped):
        @functools.wraps(wrapped)
        def func(*args, **kwargs):
            def _matches(frame):
                if frame.function != wrapped.__name__:
                    return False
                frame = frame.frame
                if not match_parameters:
                    return False
                
                prev_call_args = {
                    frame.f_code.co_varnames[i]: frame.f_locals[frame.f_code.co_varnames[i]]
                    for i in range(frame.f_code.co_argcount)
                }
                
                sig = inspect.signature(wrapped)
                this_call_args = dict(zip(sig.parameters.keys(), args))
                this_call_args.update(kwargs)
                return prev_call_args == this_call_args
            matching_frames = [frame[2] for frame in inspect.stack(context=1) if _matches(frame)]
            if matching_frames:
                raise RecursionError("(Potential) infinite recursion detected")
            return wrapped(*args, **kwargs)
        return func
    return _decorator
def is_string(s, include_unicode=True, exclude_binary=False):