# Buggy code
def rebuild_censored_list():
    """Rebuild the censored list."""
    # set of censored items
    results = set()
    for value in itervalues(censored_items):
        if not value:
            continue
        if isinstance(value, collections.Iterable) and not isinstance(
            value, string_types
        ):
            for item in value:
                if item and item != "0":
                    results.add(item)
        elif value and value != "0":
            results.add(value)

    # set of censored items and urlencoded counterparts
    results |= {quote(item) for item in results}
    # convert set items to unicode and typecast to list
    results = list(
        {
            item.decode(default_encoding, "replace")
            if not isinstance(item, text_type)
            else item
            for item in results
        }
    )
    # sort the list in order of descending length so that entire item is censored
    # e.g. password and password_1 both get censored instead of getting ********_1
    results.sort(key=len, reverse=True)

    # replace
    censored[:] = results


# Traceback (KeyError)
root@medusa:/ # service medusa start
Starting medusa.
Traceback (most recent call last):
File "/usr/local/medusa/start.py", line 9, in <module>
main()
File "/usr/local/medusa/medusa/__main__.py", line 2157, in main
application.start(sys.argv[1:])
File "/usr/local/medusa/medusa/__main__.py", line 339, in start
self.initialize(console_logging=self.console_logging)
File "/usr/local/medusa/medusa/__main__.py", line 1093, in initialize
app_logger.rebuild_censored_list()
File "/usr/local/medusa/medusa/logger/__init__.py", line 90, in rebuild_censored_list
results |= {quote(item) for item in results}
File "/usr/local/medusa/medusa/logger/__init__.py", line 90, in <setcomp>
results |= {quote(item) for item in results}
File "/usr/local/lib/python2.7/urllib.py", line 1298, in quote
return ''.join(map(quoter, s))
KeyError: u'\u20ac'
/usr/local/etc/rc.d/medusa: WARNING: failed to start medusa

# Fixed code
def rebuild_censored_list():
    """Rebuild the censored list."""
    # set of censored items
    results = set()
    for value in itervalues(censored_items):
        if not value:
            continue
        if isinstance(value, collections.Iterable) and not isinstance(
            value, string_types
        ):
            for item in value:
                if item and item != "0":
                    results.add(item)
        elif value and value != "0":
            results.add(value)

    def quote_unicode(value):
        """Quote a unicode value by encoding it to bytes first."""
        if isinstance(value, text_type):
            return quote(value.encode(default_encoding, "replace"))
        return quote(value)

    # set of censored items and urlencoded counterparts
    results |= {quote_unicode(item) for item in results}
    # convert set items to unicode and typecast to list
    results = list(
        {
            item.decode(default_encoding, "replace")
            if not isinstance(item, text_type)
            else item
            for item in results
        }
    )
    # sort the list in order of descending length so that entire item is censored
    # e.g. password and password_1 both get censored instead of getting ********_1
    results.sort(key=len, reverse=True)

    # replace
    censored[:] = results