def METHOD_NAME(prev_shard, cur_shard):
    """Test if prev_shard and cur_shard are equal (so no communicator need to be inserted)
    sharding_specs could be wrapped recursively in tuple/list/dict
    to test the equality of the two, unwrap the container and assign correctly the group
    Args:
        prev_shard: sharding spec possibly wrapped
        cur_shard: sharding spec possibly wrapped
    Returns
        whether two shards are equivalent in the sense no communicator is needed
    """
    if isinstance(prev_shard, (list, tuple)):
        return all(list(METHOD_NAME(p_shard, c_shard) for p_shard, c_shard in zip(prev_shard, cur_shard)))
    elif isinstance(prev_shard, dict):
        return all(list(METHOD_NAME(prev_shard[key], cur_shard[key]) for key in prev_shard.keys()))
    elif isinstance(prev_shard, slice):
        # a slice object cannot be sharded, return equal
        return True
    else:
        if (
            prev_shard is None
            or cur_shard is None
            or not isinstance(prev_shard, MeshShardingSpec)
            or not isinstance(cur_shard, MeshShardingSpec)
        ):
            return True
        prev_group = prev_shard.group
        cur_group = cur_shard.group
        prev_ranks = prev_shard.ranks
        cur_ranks = cur_shard.ranks
        prev_group = "tensor" if prev_group is None else prev_group
        cur_group = "tensor" if cur_group is None else cur_group
        if prev_group is not None and isinstance(prev_group, str):
            prev_group, prev_ranks = parallel_group_and_ranks(prev_group)
            prev_shard.ranks = prev_ranks
            prev_shard.group = prev_group
        if cur_group is not None and isinstance(cur_group, str):
            cur_group, cur_ranks = parallel_group_and_ranks(cur_group)
            cur_shard.ranks = cur_ranks
            cur_shard.group = cur_group
        return prev_shard == cur_shard