Fix `beam cp` downloads to a directory outside the current one
beam cp can't download into a directory outside the current one, on any OS:
$ cd ~/project
$ beam cp beam://my-volume/runs/metrics.csv ~/Downloads
Failed: '/Users/me/Downloads/metrics.csv' is not in the subpath of '/Users/me/project' OR one path is relative and the other is absolute.
(That is Python 3.12's wording; older versions word the ValueError differently.)
Cause. Beta9Handler.download() labels the progress bar with local_path.relative_to(Path.cwd()). copy() resolves the destination to an absolute path, so relative_to raises ValueError whenever it isn't under the current directory. This happens before anything is downloaded, and also when no progress bar is shown.
Fix. Use the relative path when the file lands inside the current directory, as now, and the full path otherwise.
Tests. sdk/tests/test_multipart_download.py stubs beta9_download and checks two cases: a download outside the current directory (the file path and the progress label), and one inside it, which keeps the relative label. They're in their own file so this PR doesn't conflict with #2078, which also edits test_multipart.py.
Verification
- Same scenarios as the new tests, run on
RemotePathandBeta9Handlertaken frommultipart.py: the download outside the current directory raises theValueErrorabove onmain, with or without a progress bar, and all four checks pass with this change. ruff format --checkandruff checkpass on both files. I couldn't run the full SDK suite locally, so CI is the first full run.- Merges cleanly with #2078.
Summary by cubic
Fixes beam cp downloads to a directory outside the current working directory. Beta9Handler.download() previously called relative_to(Path.cwd()) to label the progress bar, which raises ValueError when the destination isn't under the current directory, aborting the download. The fix falls back to the full destination path in that case, and adds tests for both inside and outside cases.