Skip to content

Fix append mode to create missing cloud files - #599

Merged
pjbull merged 2 commits into
drivendataorg:masterfrom
terminalchai:fix/append-create-missing
Oct 6, 2026
Merged

pjbull merged 2 commits into
drivendataorg:masterfrom
terminalchai:fix/append-create-missing

Conversation

@terminalchai

Copy link
Copy Markdown
Contributor

Allow CloudPath.open() in append mode to create a missing cloud file, matching Python's local-file behavior. The shared missing-file guard now rejects read modes only. Existing append content is preserved and uploads continue through the existing close handler.

Closes #585.

Validation:

  • Before the fix, all eight append regression cases failed on the local S3 rig with CloudPathFileNotFoundError; the four missing-file read cases passed.
  • After the fix, all 120 regression cases pass across ten mocked/local provider rigs, including S3, GCS, Azure Blob, ADLS Gen2, custom S3, and HTTP/HTTPS.
  • Full mocked suite after rebasing onto the streaming I/O merge (1846ae2): 2,165 passed, 127 skipped. All 120 regression cases also pass with CLOUDPATHLIB_FILE_CACHE_MODE=streaming, confirming the new append/update cache fallback works. Before that upstream merge, the file I/O and caching suites passed all 540 cases.
  • Repository-wide Black and flake8 checks pass; mypy reports no issues; git diff --check passes.
  • Black used --target-version py310 because the installed version does not recognize the repository's Python 3.15 target.
  • Disabled unrelated globally installed pytest plugins and explicitly loaded pytest-cases, xdist, and pytest-rerunfailures. Mocked runs used four workers and did not access live cloud accounts.
  • Live cloud backends were not tested locally.

Added a user-facing entry under HISTORY.md's UNRELEASED heading.

Prepared with AI assistance. Issue #585 exists but does not yet have maintainer sign-off; the contribution guide requests sign-off before external contributions proceed. Opening as a draft pending maintainer sign-off and any requested live-backend validation.

@terminalchai
terminalchai deployed to reviewed-live-cloud October 4, 2026 20:42 — with GitHub Actions Active
@terminalchai
terminalchai deployed to reviewed-live-cloud October 4, 2026 20:42 — with GitHub Actions Active
@terminalchai
terminalchai deployed to reviewed-live-cloud October 4, 2026 20:42 — with GitHub Actions Active
@terminalchai
terminalchai deployed to reviewed-live-cloud October 4, 2026 20:42 — with GitHub Actions Active
@terminalchai
terminalchai deployed to reviewed-live-cloud October 4, 2026 20:42 — with GitHub Actions Active
@pjbull
pjbull marked this pull request as ready for review October 5, 2026 15:17
@codecov

codecov Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.3%. Comparing base (1846ae2) to head (df114ba).

Additional details and impacted files
@@           Coverage Diff            @@
##           master    #599     +/-   ##
========================================
- Coverage    96.1%   95.3%   -0.8%     
========================================
  Files          30      30             
  Lines        2977    2977             
========================================
- Hits         2861    2839     -22     
- Misses        116     138     +22     
Files with missing lines Coverage Δ
cloudpathlib/cloudpath.py 96.5% <100.0%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread tests/test_cloudpath_file_io.py Outdated
def test_read_missing_file_still_raises(rig, mode):
p = rig.create_cloud_path("missing.txt")

with pytest.raises(FileNotFoundError):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be the more specific CloudPathFileNotFoundError, no?

Comment thread HISTORY.md Outdated
## UNRELEASED

- Added streaming I/O via `FileCacheMode.streaming` for S3, Azure Blob Storage, Google Cloud Storage, and HTTP/HTTPS. In this mode `CloudPath.open()` returns the standard `io` file objects (`BufferedReader`/`BufferedWriter`/`TextIOWrapper`) backed by ranged reads and multipart uploads instead of the local cache, so only the bytes you read are downloaded and written data is uploaded as you write it. Read streams are seekable; append and update modes fall back to the cache and remove the cache file on close. `buffering` has its builtin `open()` meaning and sets the ranged-request size (default 5 MiB). A new `streaming_max_concurrency` client option (default 4) bounds background read-ahead and part uploads per stream; the buffer size, concurrency, and multipart part size can also be set with the `CLOUDPATHLIB_STREAMING_BUFFER_SIZE`, `CLOUDPATHLIB_STREAMING_MAX_CONCURRENCY`, and `CLOUDPATHLIB_[<PROVIDER>_]STREAMING_PART_SIZE` environment variables. Opening a file for append or update in streaming mode warns that it falls back to the cache. `copy`/`rename`/`replace` stream between clients, `fspath` raises `CloudPathNotImplementedError`, and failures raise `cloudpathlib.exceptions` types including the new `CloudPathStreamingError`. See the [Streaming I/O](https://cloudpathlib.drivendata.org/stable/streaming_io/) docs. (PR [#535](https://github.com/drivendataorg/cloudpathlib/pull/535))
- Fixed append mode (`a`, `ab`, `a+`, and `ab+`) to create missing cloud files, matching Python file behavior. Appending to existing files still preserves their content. (Issue [#585](https://github.com/drivendataorg/cloudpathlib/issues/585))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is more of a "changed" than a "fixed"

Assert CloudPathFileNotFoundError for missing-file read modes and classify
append creation as a Changed changelog entry.

Addresses review comments 4185731244 and 4185809794 on PR drivendataorg#599.
@terminalchai
terminalchai deployed to reviewed-live-cloud October 5, 2026 23:43 — with GitHub Actions Active
@terminalchai
terminalchai deployed to reviewed-live-cloud October 5, 2026 23:43 — with GitHub Actions Active
@terminalchai
terminalchai deployed to reviewed-live-cloud October 5, 2026 23:43 — with GitHub Actions Active
@pjbull
pjbull merged commit 7a0712b into drivendataorg:master Oct 6, 2026
41 of 47 checks passed

This branch was successfully deployed

1 active deployment
reviewed-live-cloud — df114bad Deployed Oct 5, 2026 by terminalchai via Live Tests (azure) #28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Opening file for writing in append mode on inexistant file fails

2 participants