def remove_unpickables(instance):
    # This function tries to do the same as:
    # load_from_dto(dto_generator(obj), skip_recoverables = True )
    # in a far faster way


    already_removed_hash = {} # For those that can be hashed
    already_removed_nothash = {} # For those that can't be hashed:
                            # {
                            #    type(instance) : {
                            #           str(instance) : [instances]
                            #    }
                            # }

    def removing_unpickables(instance):
        type_instance = type(instance)

        if type_instance in _basic_normal_types:
            return instance

        if type_instance in _recoverable_exceptions:
            return None

        if issubclass(type_instance, _default_exceptions):
            return None

        if hasattr(instance, '__slots__') and not hasattr(instance, '__getstate__'):
            return None

        if type_instance in _convert_to_str:
            return str(instance)

        try:
            if already_removed_hash.has_key(instance):
                return instance
            else:
                was_hashable = True
                already_removed_hash[instance] = None
        except __HOLE__:
            was_hashable = False # Not hashable

        if not was_hashable:
            type_dict = already_removed_nothash.get(type_instance)
            str_instance = str(instance)
            if type_dict is None:
                already_removed_nothash[type_instance] = { str_instance : [instance] }
            else:
                inst_list = type_dict.get(str_instance)
                if inst_list is None:
                    type_dict[str_instance] = [instance]
                else:
                    for inst in inst_list:
                        try:
                            if instance == inst:
                                return instance
                        except:
                            pass

                    inst_list.append(instance)

        if type_instance == tuple:
            return tuple(( removing_unpickables(element) for element in instance ))
        elif type_instance == list:
            return [ removing_unpickables(element) for element in instance ]
        elif type_instance == dict:
            new_dict = {}
            for key, value in instance.iteritems():
                new_dict[removing_unpickables(key)] = removing_unpickables(value)
            return new_dict
        elif type_instance ==  _new.instance or hasattr(instance,'__reduce__') or hasattr(instance, '__reduce_ex__'):
            attributes = ( attr for attr in dir(instance)
                            #if not attr.startswith('__') or not attr.endswith('__')
                        )

            for attr in attributes:
                if hasattr(instance.__class__, attr):
                    data_type = getattr(instance.__class__, attr)
                    if type(data_type) == property:
                        continue
                    continue

                if isinstance(instance, Exception) and attr == 'message':
                    continue

                attr_value = getattr(instance, attr)
                setattr(instance, attr, removing_unpickables(attr_value))

            return instance
        else:
            return None

    result = removing_unpickables(instance)
    return result
dataset/ETHPy150Open weblabdeusto/weblabdeusto/server/src/voodoo/mapper.py/remove_unpickables