Skip to content

Commit 6a4a8a7

Browse files
authored
Allow 'destination.content_type' to be None in 'Blob.compose'. (googleapis#6031)
Closes googleapis#5834.
1 parent dc5d144 commit 6a4a8a7

3 files changed

Lines changed: 43 additions & 9 deletions

File tree

storage/google/cloud/storage/blob.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,13 +1374,7 @@ def compose(self, sources, client=None):
13741374
``NoneType``
13751375
:param client: Optional. The client to use. If not passed, falls back
13761376
to the ``client`` stored on the blob's bucket.
1377-
1378-
:raises: :exc:`ValueError` if this blob does not have its
1379-
:attr:`content_type` set.
13801377
"""
1381-
if self.content_type is None:
1382-
raise ValueError("Destination 'content_type' not set.")
1383-
13841378
client = self._require_client(client)
13851379
query_params = {}
13861380

storage/tests/system.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,26 @@ def test_compose_create_new_blob(self):
779779
composed = destination.download_as_string()
780780
self.assertEqual(composed, SOURCE_1 + SOURCE_2)
781781

782+
def test_compose_create_new_blob_wo_content_type(self):
783+
SOURCE_1 = b'AAA\n'
784+
source_1 = self.bucket.blob('source-1')
785+
source_1.upload_from_string(SOURCE_1)
786+
self.case_blobs_to_delete.append(source_1)
787+
788+
SOURCE_2 = b'BBB\n'
789+
source_2 = self.bucket.blob('source-2')
790+
source_2.upload_from_string(SOURCE_2)
791+
self.case_blobs_to_delete.append(source_2)
792+
793+
destination = self.bucket.blob('destination')
794+
795+
destination.compose([source_1, source_2])
796+
self.case_blobs_to_delete.append(destination)
797+
798+
self.assertIsNone(destination.content_type)
799+
composed = destination.download_as_string()
800+
self.assertEqual(composed, SOURCE_1 + SOURCE_2)
801+
782802
def test_compose_replace_existing_blob(self):
783803
BEFORE = b'AAA\n'
784804
original = self.bucket.blob('original')

storage/tests/unit/test_blob.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,15 +2113,35 @@ def test_compose_wo_content_type_set(self):
21132113
SOURCE_1 = 'source-1'
21142114
SOURCE_2 = 'source-2'
21152115
DESTINATION = 'destinaton'
2116-
connection = _Connection()
2116+
RESOURCE = {}
2117+
after = ({'status': http_client.OK}, RESOURCE)
2118+
connection = _Connection(after)
21172119
client = _Client(connection)
21182120
bucket = _Bucket(client=client)
21192121
source_1 = self._make_one(SOURCE_1, bucket=bucket)
21202122
source_2 = self._make_one(SOURCE_2, bucket=bucket)
21212123
destination = self._make_one(DESTINATION, bucket=bucket)
2124+
# no destination.content_type set
21222125

2123-
with self.assertRaises(ValueError):
2124-
destination.compose(sources=[source_1, source_2])
2126+
destination.compose(sources=[source_1, source_2])
2127+
2128+
self.assertIsNone(destination.content_type)
2129+
2130+
kw = connection._requested
2131+
self.assertEqual(len(kw), 1)
2132+
self.assertEqual(kw[0], {
2133+
'method': 'POST',
2134+
'path': '/b/name/o/%s/compose' % DESTINATION,
2135+
'query_params': {},
2136+
'data': {
2137+
'sourceObjects': [
2138+
{'name': source_1.name},
2139+
{'name': source_2.name},
2140+
],
2141+
'destination': {},
2142+
},
2143+
'_target_object': destination,
2144+
})
21252145

21262146
def test_compose_minimal_w_user_project(self):
21272147
SOURCE_1 = 'source-1'

0 commit comments

Comments
 (0)