# Buggy code
def compute_collision_identifier(self, function_or_class):
    """The identifier is used to detect excessive duplicate exports.

    The identifier is used to determine when the same function or class is
    exported many times. This can yield false positives.

    Args:
        function_or_class: The function or class to compute an identifier
            for.

    Returns:
        The identifier. Note that different functions or classes can give
            rise to same identifier. However, the same function should
            hopefully always give rise to the same identifier. TODO(rkn):
            verify if this is actually the case. Note that if the
            identifier is incorrect in any way, then we may give warnings
            unnecessarily or fail to give warnings, but the application's
            behavior won't change.
    """
    import io

    string_file = io.StringIO()
    if sys.version_info[1] >= 7:
        dis.dis(function_or_class, file=string_file, depth=2)
    else:
        dis.dis(function_or_class, file=string_file)
    collision_identifier = function_or_class.__name__ + ":" + string_file.getvalue()

    # Return a hash of the identifier in case it is too large.
    return hashlib.sha1(collision_identifier.encode("ascii")).digest()


# Traceback (UnicodeEncodeError)
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-6-b5dd33a57b06> in <module>
----> 1 fut = test.remote()

~/l/anaconda3/lib/python3.6/site-packages/ray/remote_function.py in _remote_proxy(*args, **kwargs)
93         @wraps(function)
94         def _remote_proxy(*args, **kwargs):
---> 95             return self._remote(args=args, kwargs=kwargs)
96
97         self.remote = _remote_proxy

~/l/anaconda3/lib/python3.6/site-packages/ray/remote_function.py in _remote(self, args, kwargs, num_return_vals, is_direct_call, num_cpus, num_gpus, memory, object_store_memory, resources, max_retries)
174
175             self._last_export_session_and_job = worker.current_session_and_job
--> 176             worker.function_actor_manager.export(self)
177
178         kwargs = {} if kwargs is None else kwargs

~/l/anaconda3/lib/python3.6/site-packages/ray/function_manager.py in export(self, remote_function)
149                 "function": pickled_function,
150                 "collision_identifier": self.compute_collision_identifier(
--> 151                     function),
152                 "max_calls": remote_function._max_calls
153             })

~/l/anaconda3/lib/python3.6/site-packages/ray/function_manager.py in compute_collision_identifier(self, function_or_class)
121
122         # Return a hash of the identifier in case it is too large.
--> 123         return hashlib.sha1(collision_identifier.encode("ascii")).digest()
124
125     def export(self, remote_function):

UnicodeEncodeError: 'ascii' codec can't encode character '\u03c6' in position 101: ordinal not in range(128)

# Fixed code
def compute_collision_identifier(self, function_or_class):
    """The identifier is used to detect excessive duplicate exports.

    The identifier is used to determine when the same function or class is
    exported many times. This can yield false positives.

    Args:
        function_or_class: The function or class to compute an identifier
            for.

    Returns:
        The identifier. Note that different functions or classes can give
            rise to same identifier. However, the same function should
            hopefully always give rise to the same identifier. TODO(rkn):
            verify if this is actually the case. Note that if the
            identifier is incorrect in any way, then we may give warnings
            unnecessarily or fail to give warnings, but the application's
            behavior won't change.
    """
    import io

    string_file = io.StringIO()
    if sys.version_info[1] >= 7:
        dis.dis(function_or_class, file=string_file, depth=2)
    else:
        dis.dis(function_or_class, file=string_file)
    collision_identifier = function_or_class.__name__ + ":" + string_file.getvalue()

    # Return a hash of the identifier in case it is too large.
    return hashlib.sha1(collision_identifier.encode("utf-8")).digest()