Skip to content

Conversation

@pjbull
Copy link
Member

@pjbull pjbull commented Oct 28, 2025

No description provided.

@pjbull pjbull requested a review from Copilot October 28, 2025 22:28
@github-actions
Copy link
Contributor

@codecov
Copy link

codecov bot commented Oct 28, 2025

Codecov Report

❌ Patch coverage is 72.62658% with 173 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.5%. Comparing base (28f1d94) to head (1a54e14).

Files with missing lines Patch % Lines
cloudpathlib/cloud_io.py 79.4% 40 Missing ⚠️
cloudpathlib/http/httpclient.py 36.7% 31 Missing ⚠️
cloudpathlib/gs/gsclient.py 54.3% 21 Missing ⚠️
cloudpathlib/azure/azblobclient.py 54.5% 20 Missing ⚠️
cloudpathlib/s3/s3client.py 64.5% 11 Missing ⚠️
cloudpathlib/azure/azure_io.py 80.0% 9 Missing ⚠️
cloudpathlib/s3/s3_io.py 80.8% 9 Missing ⚠️
cloudpathlib/http/http_io.py 76.4% 8 Missing ⚠️
cloudpathlib/gs/gs_io.py 83.7% 7 Missing ⚠️
cloudpathlib/client.py 66.6% 6 Missing ⚠️
... and 2 more

❗ There is a different number of reports uploaded between BASE (28f1d94) and HEAD (1a54e14). Click for more details.

HEAD has 22 uploads less than BASE
Flag BASE (28f1d94) HEAD (1a54e14)
28 6
Additional details and impacted files
@@           Coverage Diff            @@
##           master    #535     +/-   ##
========================================
- Coverage    94.0%   88.5%   -5.5%     
========================================
  Files          28      33      +5     
  Lines        2203    2833    +630     
========================================
+ Hits         2071    2510    +439     
- Misses        132     323    +191     
Files with missing lines Coverage Δ
cloudpathlib/__init__.py 85.1% <100.0%> (+0.5%) ⬆️
cloudpathlib/azure/__init__.py 100.0% <100.0%> (ø)
cloudpathlib/enums.py 100.0% <100.0%> (ø)
cloudpathlib/gs/__init__.py 100.0% <100.0%> (ø)
cloudpathlib/http/__init__.py 100.0% <100.0%> (ø)
cloudpathlib/local/implementations/azure.py 97.7% <100.0%> (+0.1%) ⬆️
cloudpathlib/local/implementations/gs.py 97.3% <100.0%> (+0.1%) ⬆️
cloudpathlib/local/implementations/s3.py 100.0% <100.0%> (ø)
cloudpathlib/s3/__init__.py 100.0% <100.0%> (ø)
cloudpathlib/cloudpath.py 94.2% <83.8%> (-0.7%) ⬇️
... and 11 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds streaming I/O support to cloudpathlib, enabling direct file streaming from/to cloud storage (S3, Azure Blob Storage, GCS, and HTTP/HTTPS) without local caching. Key changes include:

  • New FileCacheMode.streaming enum value for direct streaming without caching
  • CloudBufferedIO and CloudTextIO classes implementing standard Python I/O interfaces
  • Provider-specific raw I/O adapters for efficient range requests and multipart uploads

Reviewed Changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 28 comments.

Show a summary per file
File Description
cloudpathlib/enums.py Added streaming enum value to FileCacheMode
cloudpathlib/cloud_io.py New module with CloudBufferedIO, CloudTextIO, and _CloudStorageRaw base classes
cloudpathlib/cloudpath.py Updated CloudImplementation to track raw I/O classes; modified open() and __fspath__() for streaming mode
cloudpathlib/client.py Added abstract methods for streaming I/O operations
cloudpathlib/s3/s3_io.py S3-specific streaming I/O implementation
cloudpathlib/azure/azure_io.py Azure-specific streaming I/O implementation
cloudpathlib/gs/gs_io.py GCS-specific streaming I/O implementation
cloudpathlib/http/http_io.py HTTP-specific streaming I/O implementation
tests/test_cloud_io.py Comprehensive test suite for streaming I/O functionality
tests/conftest.py Updated test fixtures to use CloudImplementation with raw I/O classes
tests/test_cloudpath_instantiation.py Updated test to access dependencies_loaded via cloud_implementation
tests/mock_clients/mock_s3.py Added mock methods for range requests and multipart uploads
tests/mock_clients/mock_gs.py Added mock methods for range downloads and uploads
tests/mock_clients/mock_azureblob.py Added mock methods for range downloads and block uploads
tests/http_fixtures.py Added Range request handling to HTTP test server
docs/docs/streaming_io.md Comprehensive documentation for streaming I/O feature
docs/docs/caching.ipynb Updated caching documentation to include streaming mode

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

rig = CloudProviderTestRig(
path_class=LocalS3Path,
client_class=LocalS3Client,
cloud_implementation=local_s3_implementation,
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

Incorrect variable used: local_s3_implementation should be local_s3_cloud_implementation. This passes the wrong CloudImplementation object (the one from local.implementations.s3 module instead of the test-specific one created on line 559).

Suggested change
cloud_implementation=local_s3_implementation,
cloud_implementation=local_s3_cloud_implementation,

Copilot uses AI. Check for mistakes.

def validate_completeness(self) -> None:
expected = ["client_class", "path_class"]
expected = ["client_class", "path_class", "raw_io_class"]
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

The validation now requires raw_io_class to be present, but this is a breaking change. Existing custom implementations won't have this attribute set, causing them to fail validation. Consider making raw_io_class optional for backward compatibility, or only validate it when streaming mode is enabled.

Suggested change
expected = ["client_class", "path_class", "raw_io_class"]
expected = ["client_class", "path_class"]

Copilot uses AI. Check for mistakes.
# Flush the buffer first (which will call write() on the raw stream)
try:
self._buffer.flush()
except Exception:
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
# Try to access the internal _closed attribute
if hasattr(self._buffer, "_closed"):
object.__setattr__(self._buffer, "_closed", True)
except Exception:
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except Exception:
except Exception:
# Ignore errors when setting _closed; not critical for buffer cleanup.

Copilot uses AI. Check for mistakes.
path.client.file_cache_mode = original_mode
try:
path.unlink()
except Exception:
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
finally:
try:
path.unlink()
except Exception:
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
finally:
try:
path.unlink()
except Exception:
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
finally:
try:
path.unlink()
except Exception:
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
finally:
try:
path.unlink()
except Exception:
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
finally:
try:
path.unlink()
except Exception:
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
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.

2 participants