# Buggy code
def remove_values(value, no_log_strings):
    """Remove strings in no_log_strings from value.  If value is a container
    type, then remove a lot more"""
    if isinstance(value, (text_type, binary_type)):
        # Need native str type
        native_str_value = value
        if isinstance(value, text_type):
            value_is_text = True
            if PY2:
                native_str_value = to_bytes(
                    value, encoding="utf-8", errors="surrogate_or_strict"
                )
        elif isinstance(value, binary_type):
            value_is_text = False
            if PY3:
                native_str_value = to_text(
                    value, encoding="utf-8", errors="surrogate_or_strict"
                )

        if native_str_value in no_log_strings:
            return "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
        for omit_me in no_log_strings:
            native_str_value = native_str_value.replace(omit_me, "*" * 8)

        if value_is_text and isinstance(native_str_value, binary_type):
            value = to_text(
                native_str_value, encoding="utf-8", errors="surrogate_then_replace"
            )
        elif not value_is_text and isinstance(native_str_value, text_type):
            value = to_bytes(
                native_str_value, encoding="utf-8", errors="surrogate_then_replace"
            )
        else:
            value = native_str_value
    elif isinstance(value, SEQUENCETYPE):
        return [remove_values(elem, no_log_strings) for elem in value]
    elif isinstance(value, Mapping):
        return dict((k, remove_values(v, no_log_strings)) for k, v in value.items())
    elif isinstance(value, tuple(chain(NUMBERTYPES, (bool, NoneType)))):
        stringy_value = to_native(value, encoding="utf-8", errors="surrogate_or_strict")
        if stringy_value in no_log_strings:
            return "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
        for omit_me in no_log_strings:
            if omit_me in stringy_value:
                return "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
    elif isinstance(value, datetime.datetime):
        value = value.isoformat()
    else:
        raise TypeError("Value of unknown type: %s, %s" % (type(value), value))
    return value


# Traceback (RuntimeError)
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: RuntimeError: maximum recursion depth exceeded in cmp
fatal: [trd-gw]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Traceback (most recent call last):
File \"/tmp/ansible_4P2WOB/ansible_module_junos_facts.py\", line 757, in <module>
main()
File \"/tmp/ansible_4P2WOB/ansible_module_junos_facts.py\", line 753, in main
module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
File \"/tmp/ansible_4P2WOB/ansible_modlib.zip/ansible/module_utils/basic.py\", line 1983, in exit_json
File \"/tmp/ansible_4P2WOB/ansible_modlib.zip/ansible/module_utils/basic.py\", line 1973, in _return_formatted
File \"/tmp/ansible_4P2WOB/ansible_modlib.zip/ansible/module_utils/basic.py\", line 414, in remove_values
File \"/tmp/ansible_4P2WOB/ansible_modlib.zip/ansible/module_utils/basic.py\", line 414, in <genexpr>
File \"/tmp/ansible_4P2WOB/ansible_modlib.zip/ansible/module_utils/basic.py\", line 414, in remove_values
File \"/tmp/ansible_4P2WOB/ansible_modlib.zip/ansible/module_utils/basic.py\", line 414, in <genexpr>
File \"/tmp/ansible_4P2WOB/ansible_modlib.zip/ansible/module_utils/basic.py\", line 414, in remove_values
File \"/tmp/ansible_4P2WOB/ansible_modlib.zip/ansible/module_utils/basic.py\", line 414, in <genexpr>
[---- SNIP ----]
File \"/tmp/ansible_4P2WOB/ansible_modlib.zip/ansible/module_utils/basic.py\", line 411, in remove_values
File \"/usr/lib/python2.7/abc.py\", line 141, in __instancecheck__
subtype in cls._abc_negative_cache):
File \"/usr/lib/python2.7/_weakrefset.py\", line 75, in __contains__
return wr in self.data
RuntimeError: maximum recursion depth exceeded in cmp
", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 0}

# Fixed code
def remove_values(value, no_log_strings):
    """Remove strings in no_log_strings from value.  If value is a container
    type, then remove a lot more"""
    deferred_removals = deque()

    no_log_strings = [
        to_native(s, errors="surrogate_or_strict") for s in no_log_strings
    ]
    new_value = _remove_values_conditions(value, no_log_strings, deferred_removals)

    while deferred_removals:
        old_data, new_data = deferred_removals.popleft()
        if isinstance(new_data, Mapping):
            for old_key, old_elem in old_data.items():
                new_elem = _remove_values_conditions(
                    old_elem, no_log_strings, deferred_removals
                )
                new_data[old_key] = new_elem
        else:
            for elem in old_data:
                new_elem = _remove_values_conditions(
                    elem, no_log_strings, deferred_removals
                )
                if isinstance(new_data, MutableSequence):
                    new_data.append(new_elem)
                elif isinstance(new_data, MutableSet):
                    new_data.add(new_elem)
                else:
                    raise TypeError(
                        "Unknown container type encountered when removing private values from output"
                    )

    return new_value