From d9ede44c4888fa68d23aaa6eaa00f6abbaaf667c Mon Sep 17 00:00:00 2001 From: David Stansby Date: Fri, 8 Dec 2023 15:26:01 +0000 Subject: [PATCH 1/3] Unpin fsspec in dev requirements --- requirements/requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt index 2931335e..499d9fad 100644 --- a/requirements/requirements-dev.txt +++ b/requirements/requirements-dev.txt @@ -1,4 +1,4 @@ -fsspec==2023.6.0 +fsspec black cython >= 0.29.16 numpy >= 1.16.0 From 1072b2031f1b611e30ebb652f1cee008c28c5d88 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 31 Jan 2024 10:18:17 +0100 Subject: [PATCH 2/3] Accept "file" or ("file, "local"") for protocol A change in fsspec led to growing numbers of "../.." entries at the end of the filepaths. A call to resolve() is always needed in order to keep the file paths canonical. --- ome_zarr/io.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ome_zarr/io.py b/ome_zarr/io.py index 6529d76a..2543f6c4 100644 --- a/ome_zarr/io.py +++ b/ome_zarr/io.py @@ -165,7 +165,10 @@ def parts(self) -> List[str]: return self.__path.split("/") def subpath(self, subpath: str = "") -> str: - if self.__store.fs.protocol == "file": + if self.__store.fs.protocol == "file" or self.__store.fs.protocol == ( + "file", + "local", + ): filename = Path(self.__path) / subpath filename = filename.resolve() return str(filename) From 209385128ac6e2698e64ea6987844a54bb00c374 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 31 Jan 2024 10:27:31 +0100 Subject: [PATCH 3/3] Further refactor fsspec protocol detection --- ome_zarr/io.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/ome_zarr/io.py b/ome_zarr/io.py index 2543f6c4..bd3a5565 100644 --- a/ome_zarr/io.py +++ b/ome_zarr/io.py @@ -159,30 +159,45 @@ def get_json(self, subpath: str) -> JSONDict: return {} def parts(self) -> List[str]: - if self.__store.fs.protocol == "file": + if self._isfile(): return list(Path(self.__path).parts) else: return self.__path.split("/") def subpath(self, subpath: str = "") -> str: - if self.__store.fs.protocol == "file" or self.__store.fs.protocol == ( - "file", - "local", - ): + if self._isfile(): filename = Path(self.__path) / subpath filename = filename.resolve() return str(filename) - if self.__store.fs.protocol in ["http", "https"]: + elif self._ishttp(): url = str(self.__path) if not url.endswith("/"): url = f"{url}/" return urljoin(url, subpath) else: + # Might require a warning if self.__path.endswith("/"): return f"{self.__path}{subpath}" else: return f"{self.__path}/{subpath}" + def _isfile(self) -> bool: + """ + Return whether the current underlying implementation + points to a local file or not. + """ + return self.__store.fs.protocol == "file" or self.__store.fs.protocol == ( + "file", + "local", + ) + + def _ishttp(self) -> bool: + """ + Return whether the current underlying implementation + points to a URL + """ + return self.__store.fs.protocol in ["http", "https"] + def parse_url( path: Union[Path, str], mode: str = "r", fmt: Format = CurrentFormat()