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 patch_migrate():
    """A workaround for SQLite's inability to alter things

    SQLite abilities to alter tables are very limited (please read
    http://www.sqlite.org/lang_altertable.html for more details).
    E. g. one can't drop a column or a constraint in SQLite. The
    workaround for this is to recreate the original table omitting
    the corresponding constraint (or column).

    sqlalchemy-migrate library has recreate_table() method that
    implements this workaround, but it does it wrong:

        - information about unique constraints of a table
          is not retrieved. So if you have a table with one
          unique constraint and a migration adding another one
          you will end up with a table that has only the
          latter unique constraint, and the former will be lost

        - dropping of unique constraints is not supported at all

    The proper way to fix this is to provide a pull-request to
    sqlalchemy-migrate, but the project seems to be dead. So we
    can go on with monkey-patching of the lib at least for now.

    """

    # this patch is needed to ensure that recreate_table() doesn't drop
    # existing unique constraints of the table when creating a new one
    helper_cls = sqlite.SQLiteHelper
    helper_cls.recreate_table = _recreate_table
    helper_cls._get_unique_constraints = _get_unique_constraints

    # this patch is needed to be able to drop existing unique constraints
    constraint_cls = sqlite.SQLiteConstraintDropper
    constraint_cls.visit_migrate_unique_constraint = \
        _visit_migrate_unique_constraint
    constraint_cls.__bases__ = (ansisql.ANSIColumnDropper,
                                sqlite.SQLiteConstraintGenerator)