# Buggy code
def join(self, other, func):
    if other._partitions != self._partitions:
        if other.count() > self.count():
            return self.save_as(
                str(uuid.uuid1()), self.__client.job_id, partition=other._partitions
            ).join(other, func)
        else:
            return self.join(
                other.save_as(
                    str(uuid.uuid1()), self.__client.job_id, partition=self._partitions
                ),
                func,
            )
    return self.__client.join(self, other, func)


# Traceback (TypeError)
Traceback (most recent call last):
File "test.py", line 19, in <module>
test.run()
File "test.py", line 15, in run
table = self.data.mapValues(lambda x: self.fun(x))
File "/data/projects/fate/python/arch/api/cluster/eggroll.py", line 108, in mapValues
return self.__client.map_values(self, func)
File "/data/projects/fate/python/arch/api/cluster/eggroll.py", line 290, in map_values
func_id, func_bytes = self.serialize_and_hash_func(func)
File "/data/projects/fate/python/arch/api/cluster/eggroll.py", line 195, in serialize_and_hash_func
pickled_function = cloudpickle.dumps(func)
File "/data/projects/fate/python/arch/api/utils/cloudpickle.py", line 892, in dumps
cp.dump(obj)
File "/data/projects/fate/python/arch/api/utils/cloudpickle.py", line 271, in dump
return Pickler.dump(self, obj)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 409, in dump
self.save(obj)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 476, in save
f(self, obj) # Call unbound method with explicit self
File "/data/projects/fate/python/arch/api/utils/cloudpickle.py", line 412, in save_function
self.save_function_tuple(obj)
File "/data/projects/fate/python/arch/api/utils/cloudpickle.py", line 559, in save_function_tuple
save(state)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 476, in save
f(self, obj) # Call unbound method with explicit self
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 821, in save_dict
self._batch_setitems(obj.items())
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 847, in _batch_setitems
save(v)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 476, in save
f(self, obj) # Call unbound method with explicit self
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 781, in save_list
self._batch_appends(obj)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 808, in _batch_appends
save(tmp[0])
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 521, in save
self.save_reduce(obj=obj, *rv)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 634, in save_reduce
save(state)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 476, in save
f(self, obj) # Call unbound method with explicit self
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 821, in save_dict
self._batch_setitems(obj.items())
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 852, in _batch_setitems
save(v)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 521, in save
self.save_reduce(obj=obj, *rv)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 634, in save_reduce
save(state)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 476, in save
f(self, obj) # Call unbound method with explicit self
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 821, in save_dict
self._batch_setitems(obj.items())
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 847, in _batch_setitems
save(v)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 521, in save
self.save_reduce(obj=obj, *rv)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 634, in save_reduce
save(state)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 476, in save
f(self, obj) # Call unbound method with explicit self
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 821, in save_dict
self._batch_setitems(obj.items())
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 847, in _batch_setitems
save(v)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 521, in save
self.save_reduce(obj=obj, *rv)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 634, in save_reduce
save(state)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 476, in save
f(self, obj) # Call unbound method with explicit self
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 821, in save_dict
self._batch_setitems(obj.items())
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 847, in _batch_setitems
save(v)
File "/data/projects/common/miniconda3/lib/python3.6/pickle.py", line 496, in save
rv = reduce(self.proto)
File "stringsource", line 2, in grpc._cython.cygrpc.Channel.__reduce_cython__
TypeError: no default __reduce__ due to non-trivial __cinit__

# Fixed code
def join(self, other, func):
    if other._partitions != self._partitions:
        if other.count() > self.count():
            return self.save_as(
                str(uuid.uuid1()),
                _EggRoll.get_instance().job_id,
                partition=other._partitions,
            ).join(other, func)
        else:
            return self.join(
                other.save_as(
                    str(uuid.uuid1()),
                    _EggRoll.get_instance().job_id,
                    partition=self._partitions,
                ),
                func,
            )
    return _EggRoll.get_instance().join(self, other, func)