From c04b53320bc5f6015497866cf922711f8d3fa083 Mon Sep 17 00:00:00 2001 From: Peter Van Dyken Date: Sat, 11 Jan 2025 14:01:18 -0500 Subject: [PATCH] Start applying fixes for update --- .github/workflows/test.yml | 4 +- snakebids/__init__.py | 1 + snakebids/core/_querying.py | 3 +- snakebids/core/datasets.py | 2 +- snakebids/core/input_generation.py | 2 +- snakebids/resources/bids_tags.json | 6 ++ snakebids/tests/conftest.py | 5 +- snakebids/tests/test_generate_inputs.py | 77 +++++++++++-------- .../tests/test_plugins/test_snakemake.py | 16 ++-- 9 files changed, 66 insertions(+), 50 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f533ab61..a940653b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -52,7 +52,7 @@ jobs: needs: [ 'quality' ] strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13.-rc.3'] steps: - uses: khanlab/actions/.github/actions/action-setup_task-installPyProject@v0.3.6 id: setup @@ -68,7 +68,7 @@ jobs: needs: [ 'build-cache-env' ] strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13.-rc.3'] split: ['1', '2', '3', '4', '5'] fail-fast: false steps: diff --git a/snakebids/__init__.py b/snakebids/__init__.py index 8a16c48c..836ed906 100644 --- a/snakebids/__init__.py +++ b/snakebids/__init__.py @@ -3,6 +3,7 @@ __submodules__ = ["core", "paths"] + from snakebids import _warningformat # noqa: F401 # isort: split diff --git a/snakebids/core/_querying.py b/snakebids/core/_querying.py index da5daf64..571a4edd 100644 --- a/snakebids/core/_querying.py +++ b/snakebids/core/_querying.py @@ -7,8 +7,7 @@ import attrs import more_itertools as itx -from bids.layout import BIDSLayout, Query -from bids.layout.models import BIDSFile +from bids.layout import BIDSFile, BIDSLayout, Query from typing_extensions import Self, TypeAlias, override from snakebids.exceptions import ConfigError, PybidsError diff --git a/snakebids/core/datasets.py b/snakebids/core/datasets.py index 42458641..e36d2b46 100644 --- a/snakebids/core/datasets.py +++ b/snakebids/core/datasets.py @@ -11,7 +11,7 @@ import attr import more_itertools as itx -from bids import BIDSLayout +from bids.layout import BIDSLayout from pvandyken.deprecated import deprecated from typing_extensions import Self, TypedDict diff --git a/snakebids/core/input_generation.py b/snakebids/core/input_generation.py index c3f8f60f..a1b371ee 100644 --- a/snakebids/core/input_generation.py +++ b/snakebids/core/input_generation.py @@ -17,7 +17,7 @@ ) import more_itertools as itx -from bids import BIDSLayout, BIDSLayoutIndexer +from bids.layout import BIDSLayout, BIDSLayoutIndexer from snakebids.core._querying import ( FilterSpecError, diff --git a/snakebids/resources/bids_tags.json b/snakebids/resources/bids_tags.json index e11eb1fc..d71d202e 100644 --- a/snakebids/resources/bids_tags.json +++ b/snakebids/resources/bids_tags.json @@ -183,6 +183,12 @@ "before": "subset-", "match": "[a-zA-Z0-9]+" }, + "nucleus": { + "tag": "nucleus", + "before": "nuc-", + "match": "[a-zA-Z0-9]+" + + }, "desc": { "tag": "desc", "before": "desc-", diff --git a/snakebids/tests/conftest.py b/snakebids/tests/conftest.py index 283141c1..947f69d6 100644 --- a/snakebids/tests/conftest.py +++ b/snakebids/tests/conftest.py @@ -8,6 +8,7 @@ import pytest from hypothesis import database, settings from pyfakefs.fake_filesystem import FakeFilesystem +from upath import UPath import snakebids.paths.resources as specs from snakebids import resources, set_bids_spec @@ -51,9 +52,7 @@ def fakefs( @pytest.fixture -def fakefs_tmpdir( - request: pytest.FixtureRequest, fakefs: FakeFilesystem | None -) -> Path: +def tmpdir(request: pytest.FixtureRequest, fakefs: FakeFilesystem | None) -> Path: """Version of tmpdir compatible with fakefs If fakefs is disabled, a tmpdir is returned using the builtin tmpdir fixture. diff --git a/snakebids/tests/test_generate_inputs.py b/snakebids/tests/test_generate_inputs.py index 5278f361..ccc325f7 100644 --- a/snakebids/tests/test_generate_inputs.py +++ b/snakebids/tests/test_generate_inputs.py @@ -27,7 +27,7 @@ import attrs import more_itertools as itx import pytest -from bids import BIDSLayout +from bids.layout import BIDSLayout from hypothesis import HealthCheck, assume, example, given, settings from hypothesis import strategies as st from pyfakefs.fake_filesystem import FakeFilesystem @@ -55,6 +55,7 @@ allow_function_scoped, create_dataset, create_snakebids_config, + debug, example_if, get_bids_path, get_zip_list, @@ -208,13 +209,13 @@ def test_attribute_errors_from_pybids_qualified_and_raised(): class TestFilterBools: - @pytest.fixture(autouse=True) - def bids_fs(self, bids_fs: FakeFilesystem | None): - return bids_fs + # @pytest.fixture(autouse=True) + # def bids_fs(self, bids_fs: FakeFilesystem | None): + # return bids_fs - @pytest.fixture - def tmpdir(self, fakefs_tmpdir: Path): - return fakefs_tmpdir + # @pytest.fixture + # def tmpdir(self, tmpdir: Path): + # return tmpdir def disambiguate_components(self, dataset: BidsDataset): assert len(dataset) == 2 @@ -242,7 +243,7 @@ def set_difference(set_: set[str], comp: BidsComponent) -> set[str]: ) @given(dataset=sb_st.datasets()) def test_ambiguous_paths_with_extra_entities_leads_to_error( - self, tmpdir: Path, dataset: BidsDataset + self, tmpdir: Path, dataset: BidsDataset, mocker: MockerFixture ): root = tempfile.mkdtemp(dir=tmpdir) create_dataset(root, dataset) @@ -268,7 +269,7 @@ def test_ambiguous_paths_with_extra_entities_leads_to_error( ) @given(dataset=sb_st.datasets()) def test_ambiguous_paths_with_missing_entity_leads_to_error( - self, tmpdir: Path, dataset: BidsDataset + self, tmpdir: Path, dataset: BidsDataset, mocker: MockerFixture ): root = tempfile.mkdtemp(dir=tmpdir) create_dataset(root, dataset) @@ -519,15 +520,27 @@ def add_entity(component: BidsComponent, entity: str, value: str): assert result == BidsDataset({"template": dataset["template"]}) +@pytest.mark.disable_fakefs(True) class TestFilterMethods: - @pytest.fixture(autouse=True) - def bids_fs(self, bids_fs: FakeFilesystem | None): - return bids_fs + # @pytest.fixture(autouse=True) + # def bids_fs(self, bids_fs: FakeFilesystem | None): + # return bids_fs - @pytest.fixture - def tmpdir(self, fakefs_tmpdir: Path): - return fakefs_tmpdir + # @pytest.fixture + # def tmpdir(self, fakefs_tmpdir: Path): + # return fakefs_tmpdir + @debug( + component=BidsComponent( + name="template", + path="sub-{subject}/sub-{subject}_nuc-{nucleus}", + zip_lists={ + "subject": ["0"], + "nucleus": ["0"], + }, + ), + data=mock_data("0"), + ) @example( component=BidsComponent( name="template", @@ -861,10 +874,8 @@ def test_filter_with_invalid_method_raises_error(self, tmpdir: Path, method: str max_examples=1, ) @given(dataset=sb_st.datasets_one_comp(unique=True)) -def test_duplicate_wildcards_does_not_create_error( - dataset: BidsDataset, bids_fs: Path, fakefs_tmpdir: Path -): - root = tempfile.mkdtemp(dir=fakefs_tmpdir) +def test_duplicate_wildcards_does_not_create_error(dataset: BidsDataset, tmpdir: Path): + root = tempfile.mkdtemp(dir=tmpdir) rooted = BidsDataset.from_iterable( attrs.evolve(comp, path=os.path.join(root, comp.path)) for comp in dataset.values() @@ -1071,8 +1082,8 @@ def get_subset(of: Iterable[T]) -> list[T]: class TestCustomPaths: @pytest.fixture - def temp_dir(self, fakefs_tmpdir: Path, bids_fs: Path): - return fakefs_tmpdir + def temp_dir(self, tmpdir: Path, bids_fs: Path): + return tmpdir def generate_test_directory( self, entities: dict[str, list[str]], template: Path, tmpdir: Path @@ -1596,13 +1607,13 @@ def test_get_lists_from_bids(): class TestGenBidsLayout: - @pytest.fixture - def tmpdir(self, fakefs_tmpdir: Path): - return fakefs_tmpdir + # @pytest.fixture + # def tmpdir(self, tmpdir: Path): + # return tmpdir - @pytest.fixture(autouse=True) - def bids_fs(self, bids_fs: FakeFilesystem | None): - return bids_fs + # @pytest.fixture(autouse=True) + # def bids_fs(self, bids_fs: FakeFilesystem | None): + # return bids_fs @settings( max_examples=1, suppress_health_check=[HealthCheck.function_scoped_fixture] @@ -1719,8 +1730,8 @@ def __str__(self): # __fspath__ calls __str__ by default ], ) @given(dataset=sb_st.datasets(unique=True)) -def test_generate_inputs(dataset: BidsDataset, bids_fs: Path, fakefs_tmpdir: Path): - root = tempfile.mkdtemp(dir=fakefs_tmpdir) +def test_generate_inputs(dataset: BidsDataset, tmpdir: Path): + root = tempfile.mkdtemp(dir=tmpdir) rooted = BidsDataset.from_iterable( attrs.evolve(comp, path=os.path.join(root, comp.path)) for comp in dataset.values() @@ -1753,8 +1764,8 @@ class TestParticipantFiltering: MODE = Literal["include", "exclude"] @pytest.fixture - def tmpdir(self, bids_fs: Path, fakefs_tmpdir: Path): - return fakefs_tmpdir + def tmpdir(self, bids_fs: Path, tmpdir: Path): + return tmpdir def get_filter_params(self, mode: MODE, filters: list[str] | str): class FiltParams(TypedDict, total=False): @@ -1932,12 +1943,12 @@ def test_exclude_participant_does_not_make_all_other_filters_regex( @settings(max_examples=1, suppress_health_check=[HealthCheck.function_scoped_fixture]) @given(dataset=sb_st.datasets_one_comp(blacklist_entities=["extension"], unique=True)) def test_when_all_custom_paths_no_layout_indexed( - dataset: BidsDataset, bids_fs: Path, fakefs_tmpdir: Path, mocker: MockerFixture + dataset: BidsDataset, bids_fs: Path, tmpdir: Path, mocker: MockerFixture ): # Need to reset mocker at beginning because hypothesis may call this function # multiple times mocker.stopall() - root = tempfile.mkdtemp(dir=fakefs_tmpdir) + root = tempfile.mkdtemp(dir=tmpdir) rooted = BidsDataset.from_iterable( attrs.evolve(comp, path=os.path.join(root, comp.path)) for comp in dataset.values() diff --git a/snakebids/tests/test_plugins/test_snakemake.py b/snakebids/tests/test_plugins/test_snakemake.py index de4fd01c..40f33201 100644 --- a/snakebids/tests/test_plugins/test_snakemake.py +++ b/snakebids/tests/test_plugins/test_snakemake.py @@ -29,31 +29,31 @@ class TestFindSnakefileConfig: @allow_function_scoped @given(snakefile=st.sampled_from(SNAKEFILE_CHOICES)) - def test_finds_snakefile(self, fakefs_tmpdir: Path, snakefile: str): - tmp = Path(tempfile.mkdtemp(dir=fakefs_tmpdir)) + def test_finds_snakefile(self, tmpdir: Path, snakefile: str): + tmp = Path(tempfile.mkdtemp(dir=tmpdir)) snakefile_path = tmp / snakefile snakefile_path.parent.mkdir(parents=True, exist_ok=True) snakefile_path.touch() app = SnakemakeBidsApp(snakemake_dir=tmp, configfile_path=None) assert app.snakefile_path == snakefile_path - def test_errors_if_no_snakefile_found(self, fakefs_tmpdir: Path): - tmp = Path(tempfile.mkdtemp(dir=fakefs_tmpdir)) + def test_errors_if_no_snakefile_found(self, tmpdir: Path): + tmp = Path(tempfile.mkdtemp(dir=tmpdir)) with pytest.raises(ConfigError, match="Error: no Snakefile"): SnakemakeBidsApp(snakemake_dir=tmp, configfile_path=None) @allow_function_scoped @given(configfile=st.sampled_from(CONFIGFILE_CHOICES)) - def test_finds_config_file(self, fakefs_tmpdir: Path, configfile: str): - tmp = Path(tempfile.mkdtemp(dir=fakefs_tmpdir)) + def test_finds_config_file(self, tmpdir: Path, configfile: str): + tmp = Path(tempfile.mkdtemp(dir=tmpdir)) configfile_path = tmp / configfile configfile_path.parent.mkdir(parents=True, exist_ok=True) configfile_path.touch() app = SnakemakeBidsApp(snakemake_dir=tmp, snakefile_path=Path()) assert app.configfile_path == configfile_path - def test_errors_if_no_configfile_found(self, fakefs_tmpdir: Path): - tmp = Path(tempfile.mkdtemp(dir=fakefs_tmpdir)) + def test_errors_if_no_configfile_found(self, tmpdir: Path): + tmp = Path(tempfile.mkdtemp(dir=tmpdir)) with pytest.raises(ConfigError, match="Error: no config file"): SnakemakeBidsApp(snakemake_dir=tmp, snakefile_path=Path())