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
if isinstance(s, six.binary_type) and exclude_binary:
        return False
    if isinstance(s, str):
        return True
    if include_unicode and isinstance(s, six.text_type):
        return True
    return False
def is_string_or_bytes(s):
    return is_string(s) or isinstance(s, six.string_types) or isinstance(s, bytes)
def is_base64(s):
    regex = r"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
    return is_string(s) and re.match(regex, s)
def md5(string: Union[str, bytes]) -> str:
    m = hashlib.md5()
    m.update(to_bytes(string))
    return m.hexdigest()
def select_attributes(obj: Dict, attributes: List[str]) -> Dict:
    """Select a subset of attributes from the given dict (returns a copy)"""
    attributes = attributes if is_list_or_tuple(attributes) else [attributes]
    return {k: v for k, v in obj.items() if k in attributes}
def remove_attributes(obj: Dict, attributes: List[str], recursive: bool = False) -> Dict:
    """Remove a set of attributes from the given dict (in-place)"""
    if recursive:
        def _remove(o, **kwargs):