From 177651973361265fc21d913ccf90f4a952c979aa Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Fri, 13 Mar 2026 09:56:21 +0100 Subject: [PATCH 1/2] Fix file glob not correctly reading sdfs with prefixed files --- src/sdf_xarray/__init__.py | 2 +- tests/test_dataset.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sdf_xarray/__init__.py b/src/sdf_xarray/__init__.py index 55068ec..87d0464 100644 --- a/src/sdf_xarray/__init__.py +++ b/src/sdf_xarray/__init__.py @@ -103,7 +103,7 @@ def _resolve_glob(path_glob: PathLike | Iterable[PathLike]): try: p = Path(path_glob) - paths = list(p.parent.glob(p.name)) if p.name == "*.sdf" else list(p) + paths = list(p.parent.glob(p.name)) if p.name.endswith("*.sdf") else list(p) except TypeError: paths = list({Path(p) for p in path_glob}) diff --git a/tests/test_dataset.py b/tests/test_dataset.py index 537ce9c..57c0748 100644 --- a/tests/test_dataset.py +++ b/tests/test_dataset.py @@ -212,6 +212,18 @@ def test_resolve_glob_from_string_pattern(): assert result == expected +def test_resolve_glob_from_multiple_names_string_pattern(tmp_path): + mock_test_files_dir = tmp_path + (mock_test_files_dir / "normal_0000.sdf").touch() + (mock_test_files_dir / "normal_0001.sdf").touch() + (mock_test_files_dir / "other_0000.sdf").touch() + + pattern = str(mock_test_files_dir / "normal_*.sdf") + result = _resolve_glob(pattern) + expected = sorted(mock_test_files_dir.glob("normal_*.sdf")) + assert result == expected + + def test_resolve_glob_from_path_glob(): pattern = TEST_FILES_DIR.glob("*.sdf") result = _resolve_glob(pattern) From 50e66857743e603c335e8bfce0d51d0fe5e47d8f Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Fri, 13 Mar 2026 13:39:30 +0100 Subject: [PATCH 2/2] Refactor _resolve_glob to do more checks --- src/sdf_xarray/__init__.py | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/sdf_xarray/__init__.py b/src/sdf_xarray/__init__.py index 87d0464..9b243bd 100644 --- a/src/sdf_xarray/__init__.py +++ b/src/sdf_xarray/__init__.py @@ -96,21 +96,35 @@ def _process_latex_name(variable_name: str) -> str: return variable_name -def _resolve_glob(path_glob: PathLike | Iterable[PathLike]): - """ - Normalise input path_glob into a sorted list of absolute, resolved Path objects. +def _resolve_glob(path_glob: PathLike | Iterable[PathLike]) -> list[Path]: + """Resolve an input path/glob to sorted absolute SDF file paths. + + Accepts either a single path-like glob pattern (e.g. ``"*.sdf"``) or a + list of path-like file names. """ - try: + if isinstance(path_glob, PathLike): p = Path(path_glob) - paths = list(p.parent.glob(p.name)) if p.name.endswith("*.sdf") else list(p) - except TypeError: + if p.is_dir(): + raise TypeError( + "Directory paths are not supported; pass a glob pattern" + f"(e.g. {(p / '*.sdf').as_posix()}) or a list of file paths" + f"(e.g. {[(p / '0000.sdf').as_posix(), (p / '0001.sdf').as_posix()]})." + ) + paths = list(p.parent.glob(p.name)) + else: paths = list({Path(p) for p in path_glob}) - paths = sorted(p.resolve() for p in paths) - if not paths: + resolved_paths = sorted(p.resolve() for p in paths) + if not resolved_paths: raise FileNotFoundError(f"No files matched pattern or input: {path_glob!r}") - return paths + + for p in resolved_paths: + if not p.is_file(): + raise FileNotFoundError(f"{p.as_posix()} does not exist or is not a file.") + if p.suffix.lower() != ".sdf": + raise FileNotFoundError(f"{p.as_posix()} is not an SDF file.") + return resolved_paths def _build_datatree_from_dataset(