Keep relative archive bindings stable - #28
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
This PR makes a store's archive binding stable when the caller supplies a relative path.
save(path)andVectorStore.open(path)now anchor a relative path to the working directory in effect at that call. The resultingfile_pathis absolute, so latersave()andreload()operations continue using the same lexical path even if the application changes its working directory.Extensionless paths still receive the
.npzsuffix. Path anchoring does not resolve symlinks or remove..components, so those parts keep their normal filesystem meaning.Why this is needed
The persistence API describes
file_pathas the store's current binding. Before this change, a relative binding was saved as a relativePath. Every later pathless save or reload interpreted that value against the process's current working directory.That allowed unrelated application state to redirect persistence. A store saved to
"vectors.npz"in one directory could write a newvectors.npzsomewhere else afteros.chdir(). A store opened from a relative path could likewise reload a different archive or fail because the new directory had no matching file.Anchoring once gives the binding a stable identity for the lifetime of the store. It also makes
file_pathan accurate, self-contained description of where the store will read or write.Implementation details
The existing private path-normalization boundary now applies extension handling and then calls
Path.absolute(). Python definesPath.absolute()as making a path absolute without normalization or symlink resolution. This is a better fit thanPath.resolve(), which would inspect and canonicalize the filesystem target and change the behavior of symlinked or deliberately lexical paths.Both
save(path)andopen(path)already pass through this boundary, so no new path state or abstraction is needed. A successful explicit Save As still replaces the binding; a failed Save As still preserves the previous binding. Absolute inputs retain their supplied lexical form.User impact
Applications that use absolute persistence paths behave as before. Applications that use relative paths now remain attached to the directory where
save(path)oropen(path)was called, even after a working-directory change.The observable change is that
store.file_pathis absolute after binding from a relative path. Code that compares this property with a relativePathshould compare it with the corresponding absolute path instead.An explicit later
save(relative_path)remains a Save As operation and anchors that new path against the working directory at the time of that call. Archive format version 1 is unchanged, and existing archives require no migration.Documentation
file_pathis absolute, and how working-directory changes affect pathless operations.Verification
uv lock --checkruff check .ruff format --check .mypy src/ benchmarks/chdir, reloads afterchdir, absolutefile_pathvalues, extensionless relative paths, and lexical symlink preservation.Release note
This is the second PR planned for 0.7.0. It does not change the package version or changelog; final release notes will be prepared after the complete 0.7 milestone is merged.