diff --git a/funlib/persistence/arrays/datasets.py b/funlib/persistence/arrays/datasets.py index fd324d3..e12e155 100644 --- a/funlib/persistence/arrays/datasets.py +++ b/funlib/persistence/arrays/datasets.py @@ -13,15 +13,6 @@ logger = logging.getLogger(__name__) - -class ArrayNotFoundError(Exception): - """Exception raised when an array is not found in the dataset.""" - - def __init__(self, message: str = "Array not found in the dataset"): - self.message = message - super().__init__(self.message) - - def open_ds( store, mode: str = "r", @@ -107,10 +98,7 @@ def open_ds( else get_default_metadata_format() ) - try: - data = zarr.open(store, mode=mode, **kwargs) - except zarr.errors.PathNotFoundError: - raise ArrayNotFoundError(f"Nothing found at path {store}") + data = zarr.open(store, mode=mode, **kwargs) metadata = metadata_format.parse( data.shape, @@ -239,7 +227,7 @@ def prepare_ds( try: existing_array = open_ds(store, mode="r", **kwargs) - except ArrayNotFoundError: + except FileNotFoundError: existing_array = None if existing_array is not None: @@ -349,18 +337,14 @@ def prepare_ds( ) # create the dataset - try: - ds = zarr.open_array( - store=store, - shape=shape, - chunks=chunk_shape, - dtype=dtype, - dimension_separator="/", - mode=mode, - **kwargs, - ) - except zarr.errors.ArrayNotFoundError: - raise ArrayNotFoundError(f"Nothing found at path {store}") + ds = zarr.open_array( + store=store, + shape=shape, + chunks=chunk_shape, + dtype=dtype, + mode=mode, + **kwargs, + ) default_metadata_format = get_default_metadata_format() our_metadata = { diff --git a/funlib/persistence/arrays/metadata.py b/funlib/persistence/arrays/metadata.py index e3ed064..53c77a8 100644 --- a/funlib/persistence/arrays/metadata.py +++ b/funlib/persistence/arrays/metadata.py @@ -305,7 +305,7 @@ def recurse( # base case if len(keys) == 0: # this key returns the data we want - if isinstance(data, (dict, zarr.attrs.Attributes)): + if isinstance(data, (dict, zarr.core.attributes.Attributes)): return data.get(str(current_key), None) elif isinstance(data, list): assert isinstance(current_key, int), current_key diff --git a/pyproject.toml b/pyproject.toml index 0e1f0e1..f8b29f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,12 +13,12 @@ authors = [ ] dynamic = ['version'] -requires-python = ">=3.10" +requires-python = ">=3.11" classifiers = ["Programming Language :: Python :: 3"] keywords = [] dependencies = [ - "zarr>=2,<3", + "zarr>=3,<4", # ImportError: cannot import name 'cbuffer_sizes' from 'numcodecs.blosc' # We can pin zarr to >2.18.7 but then we have to drop python 3.10 # pin numcodecs to avoid breaking change @@ -63,3 +63,6 @@ explicit_package_bases = true [[tool.mypy.overrides]] module = ["zarr.*", "iohub.*"] ignore_missing_imports = true + +[tool.uv.sources] +iohub = { git = "https://github.com/czbiohub-sf/iohub", rev = "zarr3-dev" } diff --git a/tests/conftest.py b/tests/conftest.py index 95b3e0f..647b065 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -35,19 +35,17 @@ def can_connect_to_psql(): psql_param, ) ) -def provider_factory(request, tmpdir): +def provider_factory(request, tmp_path): # provides a factory function to generate graph provider # can provide either mongodb graph provider or file graph provider # if file graph provider, will generate graph in a temporary directory # to avoid artifacts - tmpdir = Path(tmpdir) - def sqlite_provider_factory( mode, directed=None, total_roi=None, node_attrs=None, edge_attrs=None ): return SQLiteGraphDataBase( - tmpdir / "test_sqlite_graph.db", + tmp_path / "test_sqlite_graph.db", position_attribute="position", mode=mode, directed=directed, diff --git a/tests/test_datasets.py b/tests/test_datasets.py index caf80e4..6a24d64 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -2,7 +2,7 @@ import pytest from funlib.geometry import Coordinate, Roi -from funlib.persistence.arrays.datasets import ArrayNotFoundError, open_ds, prepare_ds +from funlib.persistence.arrays.datasets import open_ds, prepare_ds from funlib.persistence.arrays.metadata import MetaDataFormat stores = { @@ -16,8 +16,8 @@ @pytest.mark.parametrize("store", stores.keys()) -def test_metadata(tmpdir, store): - store = tmpdir / store +def test_metadata(tmp_path, store): + store = tmp_path / store # test prepare_ds creates array if it does not exist and mode is write array = prepare_ds( @@ -34,10 +34,10 @@ def test_metadata(tmpdir, store): @pytest.mark.parametrize("store", stores.keys()) @pytest.mark.parametrize("dtype", [np.float32, np.uint8, np.uint64]) -def test_helpers(tmpdir, store, dtype): +def test_helpers(tmp_path, store, dtype): shape = Coordinate(1, 1, 10, 20, 30) chunk_shape = Coordinate(2, 3, 10, 10, 10) - store = tmpdir / store + store = tmp_path / store metadata = MetaDataFormat().parse( shape, { @@ -50,7 +50,7 @@ def test_helpers(tmpdir, store, dtype): ) # test prepare_ds fails if array does not exist and mode is read - with pytest.raises(ArrayNotFoundError): + with pytest.raises(FileNotFoundError): prepare_ds( store, shape, @@ -218,9 +218,9 @@ def test_helpers(tmpdir, store, dtype): @pytest.mark.parametrize("store", stores.keys()) @pytest.mark.parametrize("dtype", [np.float32, np.uint8, np.uint64]) -def test_open_ds(tmpdir, store, dtype): +def test_open_ds(tmp_path, store, dtype): shape = Coordinate(1, 1, 10, 20, 30) - store = tmpdir / store + store = tmp_path / store metadata = MetaDataFormat().parse( shape, { @@ -233,7 +233,7 @@ def test_open_ds(tmpdir, store, dtype): ) # test open_ds fails if array does not exist and mode is read - with pytest.raises(ArrayNotFoundError): + with pytest.raises(FileNotFoundError): open_ds( store, offset=metadata.offset, diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 371e4d6..8b61a3d 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -91,7 +91,7 @@ def test_empty_metadata(): assert metadata.types == ["space", "space", "space", "space", "space"] -def test_default_metadata_format(tmpdir): +def test_default_metadata_format(tmp_path): set_default_metadata_format(metadata_formats["simple"]) metadata = metadata_formats["simple"].parse( (10, 2, 100, 100, 100), @@ -99,7 +99,7 @@ def test_default_metadata_format(tmpdir): ) prepare_ds( - tmpdir / "test.zarr/test", + tmp_path / "test.zarr/test", (10, 2, 100, 100, 100), offset=metadata.offset, voxel_size=metadata.voxel_size, @@ -110,7 +110,7 @@ def test_default_metadata_format(tmpdir): mode="w", ) - zarr_attrs = dict(**zarr.open(str(tmpdir / "test.zarr/test")).attrs) + zarr_attrs = dict(**zarr.open(tmp_path / "test.zarr/test").attrs) assert zarr_attrs["offset"] == [100, 200, 400] assert zarr_attrs["resolution"] == [1, 2, 3] assert zarr_attrs["extras/axes"] == ["sample^", "channel^", "t", "y", "x"]