From af831f57edf491d3dec25a8f2420a87c79eff06a Mon Sep 17 00:00:00 2001 From: Isaac To Date: Mon, 27 Apr 2026 23:01:27 -0700 Subject: [PATCH] RF: Derive LocalZarrEntry.filepath from zarr_basepath and parts Previously LocalZarrEntry stored both filepath and (zarr_basepath, parts), two representations of the same fact kept in sync only by convention inside _get_subpath and parent. Convert filepath to a @property derived as zarr_basepath.joinpath(*parts), removing the possibility of internal inconsistency. zarr_basepath is now the only on-disk state field; parts (inherited from BasePath) is the single source of truth for the entry's position within the zarr. The only direct construction site, ZarrAsset.filetree, drops the now unneeded filepath= argument. --- dandi/files/zarr.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/dandi/files/zarr.py b/dandi/files/zarr.py index b9668e2b0..67a9ddc86 100644 --- a/dandi/files/zarr.py +++ b/dandi/files/zarr.py @@ -275,11 +275,14 @@ def _ts_validate_zarr3_array( class LocalZarrEntry(BasePath): """A file or directory within a `ZarrAsset`""" - #: The path to the actual file or directory on disk - filepath: Path #: The path to the root of the Zarr file tree zarr_basepath: Path + @property + def filepath(self) -> Path: + """The path to the actual file or directory on disk""" + return self.zarr_basepath.joinpath(*self.parts) + def _get_subpath(self, name: str) -> LocalZarrEntry: if not name or "/" in name: raise ValueError(f"Invalid path component: {name!r}") @@ -288,16 +291,14 @@ def _get_subpath(self, name: str) -> LocalZarrEntry: elif name == "..": return self.parent else: - return replace( - self, filepath=self.filepath / name, parts=self.parts + (name,) - ) + return replace(self, parts=self.parts + (name,)) @property def parent(self) -> LocalZarrEntry: if self.is_root(): return self else: - return replace(self, filepath=self.filepath.parent, parts=self.parts[:-1]) + return replace(self, parts=self.parts[:-1]) def exists(self) -> bool: return os.path.lexists(self.filepath) @@ -390,9 +391,7 @@ def filetree(self) -> LocalZarrEntry: The `LocalZarrEntry` for the root of the hierarchy of files within the Zarr asset """ - return LocalZarrEntry( - filepath=self.filepath, zarr_basepath=self.filepath, parts=() - ) + return LocalZarrEntry(zarr_basepath=self.filepath, parts=()) def stat(self) -> ZarrStat: """Return various details about the Zarr asset"""