def test_view_of_view(matrix_type, subset_func, subset_func2):
    adata = gen_adata((30, 15), X_type=matrix_type)
    adata.raw = adata
    if subset_func is single_subset:
        pytest.xfail("Other subset generating functions have trouble with this")
    var_s1 = subset_func(adata.var_names, min_size=4)
    var_view1 = adata[:, var_s1]
    var_s2 = subset_func2(var_view1.var_names)
    var_view2 = var_view1[:, var_s2]
    assert var_view2._adata_ref is adata
    obs_s1 = subset_func(adata.obs_names, min_size=4)
    obs_view1 = adata[obs_s1, :]
    obs_s2 = subset_func2(obs_view1.obs_names)
    assert adata[obs_s1, :][:, var_s1][obs_s2, :]._adata_ref is adata

    view_of_actual_copy = adata[:, var_s1].copy()[obs_s1, :].copy()[:, var_s2].copy()

    view_of_view_copy = adata[:, var_s1][obs_s1, :][:, var_s2].copy()

    assert_equal(view_of_actual_copy, view_of_view_copy, exact=True)
def _search_not(self, base, search_filter, candidates=None):
        # Create empty candidates list as we need to use self.directory for
        # each search
        candidates = list()
        this_filter = list()

        index = 0
        search_filter.remove("!")
        for condition in search_filter:
            if not isinstance(condition, list):
                this_filter.append(condition)
            index +=1

        # Remove this_filter items from search_filter list
        for condition in this_filter:
            search_filter.remove(condition)

        try:
            search_filter = list(search_filter[0])
            for sub_filter in search_filter:
                if not isinstance(sub_filter, list):
                    candidates = self.operation.get(sub_filter)(base,
                                                                search_filter,
                                                                candidates)
                else:
                    candidates = self.operation.get(sub_filter[0])(base,
                                                                   sub_filter,
                                                                   candidates)
        except IndexError:
            pass

        candidates = self._invert_results(candidates)

        for item in this_filter:
            if ">=" in item:
                k, v = item.split(">=")
                candidates = Connection._match_less_than(base, k, v,
                                                            self.directory)
            elif "<=" in item:
                k, v = item.split("<=")
                candidates = Connection._match_greater_than(base, k, v,
                                                         self.directory)
            # Emulate AD functionality, same as "="
            elif "~=" in item:
                k, v = item.split("~=")
                candidates = Connection._match_notequal_to(base, k, v,
                                                         self.directory)
            elif "=" in item:
                k, v = item.split("=")
                candidates = Connection._match_notequal_to(base, k, v,
                                                         self.directory)
        return candidates