# Buggy code
def _hashable_policy(policy, policy_list):
    """
    Takes a policy and returns a list, the contents of which are all hashable and sorted.
    Example input policy:
    {'Version': '2012-10-17',
     'Statement': [{'Action': 's3:PutObjectAcl',
                    'Sid': 'AddCannedAcl2',
                    'Resource': 'arn:aws:s3:::test_policy/*',
                    'Effect': 'Allow',
                    'Principal': {'AWS': ['arn:aws:iam::XXXXXXXXXXXX:user/username1', 'arn:aws:iam::XXXXXXXXXXXX:user/username2']}
                   }]}
    Returned value:
    [('Statement',  ((('Action', (u's3:PutObjectAcl',)),
                      ('Effect', (u'Allow',)),
                      ('Principal', ('AWS', ((u'arn:aws:iam::XXXXXXXXXXXX:user/username1',), (u'arn:aws:iam::XXXXXXXXXXXX:user/username2',)))),
                      ('Resource', (u'arn:aws:s3:::test_policy/*',)), ('Sid', (u'AddCannedAcl2',)))),
     ('Version', (u'2012-10-17',)))]

    """
    if isinstance(policy, list):
        for each in policy:
            tupleified = _hashable_policy(each, [])
            if isinstance(tupleified, list):
                tupleified = tuple(tupleified)
            policy_list.append(tupleified)
    elif isinstance(policy, string_types) or isinstance(policy, binary_type):
        # convert root account ARNs to just account IDs
        if policy.startswith("arn:aws:iam::") and policy.endswith(":root"):
            policy = policy.split(":")[4]
        return [(to_text(policy))]
    elif isinstance(policy, dict):
        sorted_keys = list(policy.keys())
        sorted_keys.sort()
        for key in sorted_keys:
            tupleified = _hashable_policy(policy[key], [])
            if isinstance(tupleified, list):
                tupleified = tuple(tupleified)
            policy_list.append((key, tupleified))

    # ensure we aren't returning deeply nested structures of length 1
    if len(policy_list) == 1 and isinstance(policy_list[0], tuple):
        policy_list = policy_list[0]
    if isinstance(policy_list, list):
        if PY3_COMPARISON:
            policy_list.sort(key=cmp_to_key(py3cmp))
        else:
            policy_list.sort()
    return policy_list


# Traceback (TypeError)
Traceback (most recent call last):
File \"/home/user/.ansible/tmp/ansible-tmp-1552879529.5581675-97499234813119/AnsiballZ_aws_waf_condition.py\", line 113, in <module>
_ansiballz_main()
File \"/home/user/.ansible/tmp/ansible-tmp-1552879529.5581675-97499234813119/AnsiballZ_aws_waf_condition.py\", line 105, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File \"/home/user/.ansible/tmp/ansible-tmp-1552879529.5581675-97499234813119/AnsiballZ_aws_waf_condition.py\", line 48, in invoke_module
imp.load_module('__main__', mod, module, MOD_DESC)
File \"/usr/lib/python3.7/imp.py\", line 234, in load_module
return load_source(name, filename, file)
File \"/usr/lib/python3.7/imp.py\", line 169, in load_source
module = _exec(spec, sys.modules[name])
File \"<frozen importlib._bootstrap>\", line 630, in _exec
File \"<frozen importlib._bootstrap_external>\", line 728, in exec_module
File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed
File \"/tmp/ansible_aws_waf_condition_payload_we998wf4/__main__.py\", line 659, in <module>
File \"/tmp/ansible_aws_waf_condition_payload_we998wf4/__main__.py\", line 649, in main
File \"/tmp/ansible_aws_waf_condition_payload_we998wf4/__main__.py\", line 595, in ensure_condition_present
File \"/tmp/ansible_aws_waf_condition_payload_we998wf4/__main__.py\", line 574, in find_and_update_condition
File \"/tmp/ansible_aws_waf_condition_payload_we998wf4/__main__.py\", line 565, in find_missing
File \"/tmp/ansible_aws_waf_condition_payload_we998wf4/ansible_aws_waf_condition_payload.zip/ansible/module_utils/ec2.py\", line 605, in compare_policies
File \"/tmp/ansible_aws_waf_condition_payload_we998wf4/ansible_aws_waf_condition_payload.zip/ansible/module_utils/ec2.py\", line 563, in _hashable_policy
File \"/tmp/ansible_aws_waf_condition_payload_we998wf4/ansible_aws_waf_condition_payload.zip/ansible/module_utils/ec2.py\", line 556, in _hashable_policy
TypeError: startswith first arg must be bytes or a tuple of bytes, not str

# Fixed code
def _hashable_policy(policy, policy_list):
    """
    Takes a policy and returns a list, the contents of which are all hashable and sorted.
    Example input policy:
    {'Version': '2012-10-17',
     'Statement': [{'Action': 's3:PutObjectAcl',
                    'Sid': 'AddCannedAcl2',
                    'Resource': 'arn:aws:s3:::test_policy/*',
                    'Effect': 'Allow',
                    'Principal': {'AWS': ['arn:aws:iam::XXXXXXXXXXXX:user/username1', 'arn:aws:iam::XXXXXXXXXXXX:user/username2']}
                   }]}
    Returned value:
    [('Statement',  ((('Action', (u's3:PutObjectAcl',)),
                      ('Effect', (u'Allow',)),
                      ('Principal', ('AWS', ((u'arn:aws:iam::XXXXXXXXXXXX:user/username1',), (u'arn:aws:iam::XXXXXXXXXXXX:user/username2',)))),
                      ('Resource', (u'arn:aws:s3:::test_policy/*',)), ('Sid', (u'AddCannedAcl2',)))),
     ('Version', (u'2012-10-17',)))]

    """
    if isinstance(policy, list):
        for each in policy:
            tupleified = _hashable_policy(each, [])
            if isinstance(tupleified, list):
                tupleified = tuple(tupleified)
            policy_list.append(tupleified)
    elif isinstance(policy, string_types) or isinstance(policy, binary_type):
        policy = to_text(policy)
        # convert root account ARNs to just account IDs
        if policy.startswith("arn:aws:iam::") and policy.endswith(":root"):
            policy = policy.split(":")[4]
        return [policy]
    elif isinstance(policy, dict):
        sorted_keys = list(policy.keys())
        sorted_keys.sort()
        for key in sorted_keys:
            tupleified = _hashable_policy(policy[key], [])
            if isinstance(tupleified, list):
                tupleified = tuple(tupleified)
            policy_list.append((key, tupleified))

    # ensure we aren't returning deeply nested structures of length 1
    if len(policy_list) == 1 and isinstance(policy_list[0], tuple):
        policy_list = policy_list[0]
    if isinstance(policy_list, list):
        if PY3_COMPARISON:
            policy_list.sort(key=cmp_to_key(py3cmp))
        else:
            policy_list.sort()
    return policy_list