From 6e44a9f11f6ed433138d89335d3b6da35db99d3f Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 13:24:37 +0000 Subject: [PATCH 1/5] chore(main): release 3.5.0 --- CHANGELOG.md | 23 +++++++++++++++++++++++ google/cloud/storage/version.py | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 727a3a8cc..f8eaee23b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,29 @@ [1]: https://pypi.org/project/google-cloud-storage/#history +## [3.5.0](https://github.com/googleapis/python-storage/compare/v3.4.0...v3.5.0) (2025-10-08) + + +### Features + +* Add async bidiRpc files in python-storage ([#1545](https://github.com/googleapis/python-storage/issues/1545)) ([8b988ad](https://github.com/googleapis/python-storage/commit/8b988ade0aae184f6404ac85391bc305e8dd1d94)) +* **experimental:** Add _AsyncReadObjectStream and it's stubs ([#1547](https://github.com/googleapis/python-storage/issues/1547)) ([3c8a21d](https://github.com/googleapis/python-storage/commit/3c8a21d6467f3a2407dd64d231ba89ffb9940187)) +* **experimental:** Add AsyncAbstractObjectStream ([#1546](https://github.com/googleapis/python-storage/issues/1546)) ([71e0904](https://github.com/googleapis/python-storage/commit/71e0904d9b311ba520188ced0a60d1fc7eb10072)) +* **experimental:** Implement `__init__` method for _AsyncReadObjectStream ([#1548](https://github.com/googleapis/python-storage/issues/1548)) ([c31a516](https://github.com/googleapis/python-storage/commit/c31a516def72a1504b05c44dd8fad5a7eef52552)) +* **experimental:** Read handle refresh ([#1559](https://github.com/googleapis/python-storage/issues/1559)) ([b975732](https://github.com/googleapis/python-storage/commit/b975732f24b1e54bfd0a2c8918f3043e6e1634b6)) +* **zb-experimental:** Add all other methods open close send recv in _AsyncReadObjectStream ([#1549](https://github.com/googleapis/python-storage/issues/1549)) ([fc8461b](https://github.com/googleapis/python-storage/commit/fc8461b5d1ae8cae749a0e0a262e055fe8ea9439)) +* **zb-experimental:** Add AsyncMultiRangeDownloader ([#1550](https://github.com/googleapis/python-storage/issues/1550)) ([4766164](https://github.com/googleapis/python-storage/commit/4766164e560e170af18de68870c085f2202c7b9a)) +* **zb-experimental:** Add AsyncMultiRangeDownloader and it's init method. ([4766164](https://github.com/googleapis/python-storage/commit/4766164e560e170af18de68870c085f2202c7b9a)) +* **zb-experimental:** Add support for closing MRD ([#1554](https://github.com/googleapis/python-storage/issues/1554)) ([9c8856a](https://github.com/googleapis/python-storage/commit/9c8856af3b4fa95269855509c08968c2d29412e9)) +* **zb-experimental:** Implement `close` in AsyncMultiRangeDownloader ([aba4c6b](https://github.com/googleapis/python-storage/commit/aba4c6b7bd34f8ceb8284f0cb2137cfd0ef81b63)) +* **zb-experimental:** Implement `close` in AsyncMultiRangeDownloader ([#1555](https://github.com/googleapis/python-storage/issues/1555)) ([aba4c6b](https://github.com/googleapis/python-storage/commit/aba4c6b7bd34f8ceb8284f0cb2137cfd0ef81b63)) +* **zb-experimental:** Implement download_ranges ([#1551](https://github.com/googleapis/python-storage/issues/1551)) ([e26888f](https://github.com/googleapis/python-storage/commit/e26888fa6885330a3d938b09b3a028c2fd6c605d)) + + +### Bug Fixes + +* Send entire object checksums via upload methods ([#1561](https://github.com/googleapis/python-storage/issues/1561)) ([acb918e](https://github.com/googleapis/python-storage/commit/acb918e20f7092e13d72fc63fe4ae2560bfecd40)) + ## [3.4.0](https://github.com/googleapis/python-storage/compare/v3.3.1...v3.4.0) (2025-09-15) diff --git a/google/cloud/storage/version.py b/google/cloud/storage/version.py index 6b822f0c1..13194aa56 100644 --- a/google/cloud/storage/version.py +++ b/google/cloud/storage/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "3.4.0" +__version__ = "3.5.0" From 16743a522e0b35426392a2d5453d6b21038f4157 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Wed, 8 Oct 2025 13:26:47 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- google/cloud/storage/blob.py | 46 +++++++++---------- tests/system/test_blob.py | 3 +- .../asyncio/test_async_read_object_stream.py | 21 +++++++-- tests/unit/test_blob.py | 2 +- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/google/cloud/storage/blob.py b/google/cloud/storage/blob.py index 0d6bef271..381ce5c9d 100644 --- a/google/cloud/storage/blob.py +++ b/google/cloud/storage/blob.py @@ -235,6 +235,7 @@ def __init__( if generation is not None: self._properties["generation"] = generation + @property def bucket(self): """Bucket which contains the object. @@ -2178,12 +2179,12 @@ def _initiate_resumable_upload( unless otherwise directed. :type crc32c_checksum_value: str - :param crc32c_checksum_value: (Optional) This should be the checksum of + :param crc32c_checksum_value: (Optional) This should be the checksum of the entire contents of `file`. Applicable while uploading object greater than `_MAX_MULTIPART_SIZE` bytes. It can be obtained by running - + `gcloud storage hash /path/to/your/file` or @@ -2204,7 +2205,7 @@ def _initiate_resumable_upload( Above code block prints 8 char string of base64 encoded big-endian bytes of 32 bit CRC32c integer. - + More details on CRC32c can be found in Appendix B: https://datatracker.ietf.org/doc/html/rfc4960#appendix-B and base64: https://datatracker.ietf.org/doc/html/rfc4648#section-4 @@ -2396,12 +2397,12 @@ def _do_resumable_upload( unless otherwise directed. :type crc32c_checksum_value: str - :param crc32c_checksum_value: (Optional) This should be the checksum of + :param crc32c_checksum_value: (Optional) This should be the checksum of the entire contents of `stream`. Applicable while uploading object greater than `_MAX_MULTIPART_SIZE` bytes. It can be obtained by running - + `gcloud storage hash /path/to/your/file` or @@ -2422,7 +2423,7 @@ def _do_resumable_upload( Above code block prints 8 char string of base64 encoded big-endian bytes of 32 bit CRC32c integer. - + More details on CRC32c can be found in Appendix B: https://datatracker.ietf.org/doc/html/rfc4960#appendix-B and base64: https://datatracker.ietf.org/doc/html/rfc4648#section-4 @@ -2578,12 +2579,12 @@ def _do_upload( unless otherwise directed. :type crc32c_checksum_value: str - :param crc32c_checksum_value: (Optional) This should be the checksum of + :param crc32c_checksum_value: (Optional) This should be the checksum of the entire contents of `file_obj`. Applicable while uploading object greater than `_MAX_MULTIPART_SIZE` bytes. It can be obtained by running - + `gcloud storage hash /path/to/your/file` or @@ -2604,7 +2605,7 @@ def _do_upload( Above code block prints 8 char string of base64 encoded big-endian bytes of 32 bit CRC32c integer. - + More details on CRC32c can be found in Appendix B: https://datatracker.ietf.org/doc/html/rfc4960#appendix-B and base64: https://datatracker.ietf.org/doc/html/rfc4648#section-4 @@ -2795,12 +2796,12 @@ def _prep_and_do_upload( unless otherwise directed. :type crc32c_checksum_value: str - :param crc32c_checksum_value: (Optional) This should be the checksum of + :param crc32c_checksum_value: (Optional) This should be the checksum of the entire contents of `file_obj`. Applicable while uploading object greater than `_MAX_MULTIPART_SIZE` bytes. It can be obtained by running - + `gcloud storage hash /path/to/your/file` or @@ -2821,7 +2822,7 @@ def _prep_and_do_upload( Above code block prints 8 char string of base64 encoded big-endian bytes of 32 bit CRC32c integer. - + More details on CRC32c can be found in Appendix B: https://datatracker.ietf.org/doc/html/rfc4960#appendix-B and base64: https://datatracker.ietf.org/doc/html/rfc4648#section-4 @@ -2978,12 +2979,12 @@ def upload_from_file( to configure them. :type crc32c_checksum_value: str - :param crc32c_checksum_value: (Optional) This should be the checksum of + :param crc32c_checksum_value: (Optional) This should be the checksum of the entire contents of `file_obj`. Applicable while uploading object greater than `_MAX_MULTIPART_SIZE` bytes. It can be obtained by running - + `gcloud storage hash /path/to/your/file` or @@ -3004,7 +3005,7 @@ def upload_from_file( Above code block prints 8 char string of base64 encoded big-endian bytes of 32 bit CRC32c integer. - + More details on CRC32c can be found in Appendix B: https://datatracker.ietf.org/doc/html/rfc4960#appendix-B and base64: https://datatracker.ietf.org/doc/html/rfc4648#section-4 @@ -3068,7 +3069,6 @@ def upload_from_filename( checksum="auto", retry=DEFAULT_RETRY, crc32c_checksum_value=None, - ): """Upload this blob's contents from the content of a named file. @@ -3163,14 +3163,14 @@ def upload_from_filename( See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for information on retry types and how to configure them. - + :type crc32c_checksum_value: str - :param crc32c_checksum_value: (Optional) This should be the checksum of + :param crc32c_checksum_value: (Optional) This should be the checksum of the entire contents of `filename`. Applicable while uploading object greater than `_MAX_MULTIPART_SIZE` bytes. It can be obtained by running - + `gcloud storage hash /path/to/your/file` or @@ -3191,7 +3191,7 @@ def upload_from_filename( Above code block prints 8 char string of base64 encoded big-endian bytes of 32 bit CRC32c integer. - + More details on CRC32c can be found in Appendix B: https://datatracker.ietf.org/doc/html/rfc4960#appendix-B and base64: https://datatracker.ietf.org/doc/html/rfc4648#section-4 @@ -3314,12 +3314,12 @@ def upload_from_string( to configure them. :type crc32c_checksum_value: str - :param crc32c_checksum_value: (Optional) This should be the checksum of + :param crc32c_checksum_value: (Optional) This should be the checksum of the entire contents of `file_obj`. Applicable while uploading object greater than `_MAX_MULTIPART_SIZE` bytes. It can be obtained by running - + `gcloud storage hash /path/to/your/file` or @@ -3340,7 +3340,7 @@ def upload_from_string( Above code block prints 8 char string of base64 encoded big-endian bytes of 32 bit CRC32c integer. - + More details on CRC32c can be found in Appendix B: https://datatracker.ietf.org/doc/html/rfc4960#appendix-B and base64: https://datatracker.ietf.org/doc/html/rfc4648#section-4 diff --git a/tests/system/test_blob.py b/tests/system/test_blob.py index add994d17..59c665cfa 100644 --- a/tests/system/test_blob.py +++ b/tests/system/test_blob.py @@ -62,10 +62,11 @@ def test_large_file_write_from_stream_w_user_provided_wrong_checksum( info = file_data["big_9MiB"] with pytest.raises(exceptions.BadRequest) as excep_info: with open(info["path"], "rb") as file_obj: - blob.upload_from_file(file_obj,crc32c_checksum_value="A0tD7w==") + blob.upload_from_file(file_obj, crc32c_checksum_value="A0tD7w==") blobs_to_delete.append(blob) assert excep_info.value.code == 400 + def test_touch_and_write_large_file_w_user_provided_checksum( shared_bucket, blobs_to_delete, diff --git a/tests/unit/asyncio/test_async_read_object_stream.py b/tests/unit/asyncio/test_async_read_object_stream.py index ae5a48d76..4e4c93dd3 100644 --- a/tests/unit/asyncio/test_async_read_object_stream.py +++ b/tests/unit/asyncio/test_async_read_object_stream.py @@ -275,10 +275,17 @@ async def test_recv_without_open_should_raise_error( # assert assert str(exc.value) == "Stream is not open" -@mock.patch("google.cloud.storage._experimental.asyncio.async_read_object_stream.AsyncBidiRpc") -@mock.patch("google.cloud.storage._experimental.asyncio.async_grpc_client.AsyncGrpcClient.grpc_client") + +@mock.patch( + "google.cloud.storage._experimental.asyncio.async_read_object_stream.AsyncBidiRpc" +) +@mock.patch( + "google.cloud.storage._experimental.asyncio.async_grpc_client.AsyncGrpcClient.grpc_client" +) @pytest.mark.asyncio -async def test_recv_updates_read_handle_on_refresh(mock_client, mock_cls_async_bidi_rpc): +async def test_recv_updates_read_handle_on_refresh( + mock_client, mock_cls_async_bidi_rpc +): """ Verify that the `recv` method correctly updates the stream's handle when a new one is provided in a server response. @@ -289,11 +296,15 @@ async def test_recv_updates_read_handle_on_refresh(mock_client, mock_cls_async_b socket_like_rpc.open = AsyncMock() initial_handle = _storage_v2.BidiReadHandle(handle=b"initial-handle-token") - response_with_initial_handle = _storage_v2.BidiReadObjectResponse(read_handle=initial_handle) + response_with_initial_handle = _storage_v2.BidiReadObjectResponse( + read_handle=initial_handle + ) response_without_handle = _storage_v2.BidiReadObjectResponse(read_handle=None) refreshed_handle = _storage_v2.BidiReadHandle(handle=b"new-refreshed-handle-token") - response_with_refreshed_handle = _storage_v2.BidiReadObjectResponse(read_handle=refreshed_handle) + response_with_refreshed_handle = _storage_v2.BidiReadObjectResponse( + read_handle=refreshed_handle + ) socket_like_rpc.recv.side_effect = [ response_with_initial_handle, diff --git a/tests/unit/test_blob.py b/tests/unit/test_blob.py index 4404cdf56..f3b6da5d1 100644 --- a/tests/unit/test_blob.py +++ b/tests/unit/test_blob.py @@ -3572,7 +3572,7 @@ def _do_upload_mock_call_helper( kwargs, { "timeout": expected_timeout, - 'crc32c_checksum_value': None, + "crc32c_checksum_value": None, "checksum": None, "retry": retry, "command": None, From ac74e8d2589d41cfcfcf0e016409852048fc2f1b Mon Sep 17 00:00:00 2001 From: Chandra Shekhar Sirimala Date: Wed, 8 Oct 2025 18:57:41 +0530 Subject: [PATCH 3/5] Update CHANGELOG.md Don't bump minor version for experimental changes. --- CHANGELOG.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8eaee23b..d8a14eb6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,22 +7,6 @@ ## [3.5.0](https://github.com/googleapis/python-storage/compare/v3.4.0...v3.5.0) (2025-10-08) -### Features - -* Add async bidiRpc files in python-storage ([#1545](https://github.com/googleapis/python-storage/issues/1545)) ([8b988ad](https://github.com/googleapis/python-storage/commit/8b988ade0aae184f6404ac85391bc305e8dd1d94)) -* **experimental:** Add _AsyncReadObjectStream and it's stubs ([#1547](https://github.com/googleapis/python-storage/issues/1547)) ([3c8a21d](https://github.com/googleapis/python-storage/commit/3c8a21d6467f3a2407dd64d231ba89ffb9940187)) -* **experimental:** Add AsyncAbstractObjectStream ([#1546](https://github.com/googleapis/python-storage/issues/1546)) ([71e0904](https://github.com/googleapis/python-storage/commit/71e0904d9b311ba520188ced0a60d1fc7eb10072)) -* **experimental:** Implement `__init__` method for _AsyncReadObjectStream ([#1548](https://github.com/googleapis/python-storage/issues/1548)) ([c31a516](https://github.com/googleapis/python-storage/commit/c31a516def72a1504b05c44dd8fad5a7eef52552)) -* **experimental:** Read handle refresh ([#1559](https://github.com/googleapis/python-storage/issues/1559)) ([b975732](https://github.com/googleapis/python-storage/commit/b975732f24b1e54bfd0a2c8918f3043e6e1634b6)) -* **zb-experimental:** Add all other methods open close send recv in _AsyncReadObjectStream ([#1549](https://github.com/googleapis/python-storage/issues/1549)) ([fc8461b](https://github.com/googleapis/python-storage/commit/fc8461b5d1ae8cae749a0e0a262e055fe8ea9439)) -* **zb-experimental:** Add AsyncMultiRangeDownloader ([#1550](https://github.com/googleapis/python-storage/issues/1550)) ([4766164](https://github.com/googleapis/python-storage/commit/4766164e560e170af18de68870c085f2202c7b9a)) -* **zb-experimental:** Add AsyncMultiRangeDownloader and it's init method. ([4766164](https://github.com/googleapis/python-storage/commit/4766164e560e170af18de68870c085f2202c7b9a)) -* **zb-experimental:** Add support for closing MRD ([#1554](https://github.com/googleapis/python-storage/issues/1554)) ([9c8856a](https://github.com/googleapis/python-storage/commit/9c8856af3b4fa95269855509c08968c2d29412e9)) -* **zb-experimental:** Implement `close` in AsyncMultiRangeDownloader ([aba4c6b](https://github.com/googleapis/python-storage/commit/aba4c6b7bd34f8ceb8284f0cb2137cfd0ef81b63)) -* **zb-experimental:** Implement `close` in AsyncMultiRangeDownloader ([#1555](https://github.com/googleapis/python-storage/issues/1555)) ([aba4c6b](https://github.com/googleapis/python-storage/commit/aba4c6b7bd34f8ceb8284f0cb2137cfd0ef81b63)) -* **zb-experimental:** Implement download_ranges ([#1551](https://github.com/googleapis/python-storage/issues/1551)) ([e26888f](https://github.com/googleapis/python-storage/commit/e26888fa6885330a3d938b09b3a028c2fd6c605d)) - - ### Bug Fixes * Send entire object checksums via upload methods ([#1561](https://github.com/googleapis/python-storage/issues/1561)) ([acb918e](https://github.com/googleapis/python-storage/commit/acb918e20f7092e13d72fc63fe4ae2560bfecd40)) From 894e37a8793ad3864af36c227a0a5eed9645db15 Mon Sep 17 00:00:00 2001 From: Chandra Shekhar Sirimala Date: Wed, 8 Oct 2025 19:06:28 +0530 Subject: [PATCH 4/5] Update just the minor version. Update just the minor version. Don't update minor version for experimental features. --- CHANGELOG.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8a14eb6d..144092d1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,11 @@ [1]: https://pypi.org/project/google-cloud-storage/#history -## [3.5.0](https://github.com/googleapis/python-storage/compare/v3.4.0...v3.5.0) (2025-10-08) - +## [3.4.1](https://github.com/googleapis/python-storage/compare/v3.4.0...v3.5.0) (2025-10-08) ### Bug Fixes -* Send entire object checksums via upload methods ([#1561](https://github.com/googleapis/python-storage/issues/1561)) ([acb918e](https://github.com/googleapis/python-storage/commit/acb918e20f7092e13d72fc63fe4ae2560bfecd40)) +* Fixes [#1561](https://github.com/googleapis/python-storage/issues/1561) by adding an option to specify the entire object checksum for resumable uploads via the `upload_from_string`, `upload_from_file`, and `upload_from_filename` methods ([acb918e](https://github.com/googleapis/python-storage/commit/acb918e20f7092e13d72fc63fe4ae2560bfecd40)) ## [3.4.0](https://github.com/googleapis/python-storage/compare/v3.3.1...v3.4.0) (2025-09-15) From 7d9f7c775cee1a4acda2a5336c52db10d4153c2c Mon Sep 17 00:00:00 2001 From: Chandra Shekhar Sirimala Date: Wed, 8 Oct 2025 19:08:55 +0530 Subject: [PATCH 5/5] Update version.py from 3.5.0 to 3.4.1 Update just the patch version. Don't update (bump up) minor version for experimental features. --- google/cloud/storage/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google/cloud/storage/version.py b/google/cloud/storage/version.py index 13194aa56..71133df01 100644 --- a/google/cloud/storage/version.py +++ b/google/cloud/storage/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "3.5.0" +__version__ = "3.4.1"