Skip to content

Commit d457ce3

Browse files
fix: from_string method of blob and bucket class (#290)
Fixes #286
1 parent 5ab6b0d commit d457ce3

File tree

3 files changed

+42
-18
lines changed

3 files changed

+42
-18
lines changed

google/cloud/storage/blob.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1607,14 +1607,15 @@ def _do_multipart_upload(
16071607
msg = _READ_LESS_THAN_SIZE.format(size, len(data))
16081608
raise ValueError(msg)
16091609

1610+
client = self._require_client(client)
16101611
transport = self._get_transport(client)
16111612
if "metadata" in self._properties and "metadata" not in self._changes:
16121613
self._changes.add("metadata")
16131614
info = self._get_upload_arguments(content_type)
16141615
headers, object_metadata, content_type = info
16151616

16161617
base_url = _MULTIPART_URL_TEMPLATE.format(
1617-
hostname=self.client._connection.API_BASE_URL, bucket_path=self.bucket.path
1618+
hostname=client._connection.API_BASE_URL, bucket_path=self.bucket.path
16181619
)
16191620
name_value_pairs = []
16201621

@@ -1771,6 +1772,7 @@ def _initiate_resumable_upload(
17711772
that was created
17721773
* The ``transport`` used to initiate the upload.
17731774
"""
1775+
client = self._require_client(client)
17741776
if chunk_size is None:
17751777
chunk_size = self.chunk_size
17761778
if chunk_size is None:
@@ -1785,7 +1787,7 @@ def _initiate_resumable_upload(
17851787
headers.update(extra_headers)
17861788

17871789
base_url = _RESUMABLE_URL_TEMPLATE.format(
1788-
hostname=self.client._connection.API_BASE_URL, bucket_path=self.bucket.path
1790+
hostname=client._connection.API_BASE_URL, bucket_path=self.bucket.path
17891791
)
17901792
name_value_pairs = []
17911793

google/cloud/storage/client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ def download_blob_to_file(self, blob_or_uri, file_obj, start=None, end=None):
581581
try:
582582
blob_or_uri.download_to_file(file_obj, client=self, start=start, end=end)
583583
except AttributeError:
584-
blob = Blob.from_string(blob_or_uri)
584+
blob = Blob.from_string(blob_or_uri, self)
585585
blob.download_to_file(file_obj, client=self, start=start, end=end)
586586

587587
def list_blobs(

tests/unit/test_blob.py

+37-15
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,7 @@ def _mock_transport(self, status_code, headers, content=b""):
18181818
def _do_multipart_success(
18191819
self,
18201820
mock_get_boundary,
1821+
client=None,
18211822
size=None,
18221823
num_retries=None,
18231824
user_project=None,
@@ -1840,12 +1841,13 @@ def _do_multipart_success(
18401841
blob._properties["metadata"] = metadata
18411842
self.assertEqual(len(blob._changes), 0)
18421843

1843-
# Create mocks to be checked for doing transport.
1844-
transport = self._mock_transport(http_client.OK, {})
1845-
18461844
# Create some mock arguments.
1847-
client = mock.Mock(_http=transport, _connection=_Connection, spec=["_http"])
1848-
client._connection.API_BASE_URL = "https://storage.googleapis.com"
1845+
if not client:
1846+
# Create mocks to be checked for doing transport.
1847+
transport = self._mock_transport(http_client.OK, {})
1848+
1849+
client = mock.Mock(_http=transport, _connection=_Connection, spec=["_http"])
1850+
client._connection.API_BASE_URL = "https://storage.googleapis.com"
18491851
data = b"data here hear hier"
18501852
stream = io.BytesIO(data)
18511853
content_type = u"application/xml"
@@ -1872,7 +1874,7 @@ def _do_multipart_success(
18721874
)
18731875

18741876
# Check the mocks and the returned value.
1875-
self.assertIs(response, transport.request.return_value)
1877+
self.assertIs(response, client._http.request.return_value)
18761878
if size is None:
18771879
data_read = data
18781880
self.assertEqual(stream.tell(), len(data))
@@ -1929,7 +1931,7 @@ def _do_multipart_success(
19291931
+ b"\r\n--==0==--"
19301932
)
19311933
headers = {"content-type": b'multipart/related; boundary="==0=="'}
1932-
transport.request.assert_called_once_with(
1934+
client._http.request.assert_called_once_with(
19331935
"POST", upload_url, data=payload, headers=headers, timeout=expected_timeout
19341936
)
19351937

@@ -1987,6 +1989,13 @@ def test__do_multipart_upload_with_generation_not_match(self, mock_get_boundary)
19871989
mock_get_boundary, if_generation_not_match=4, if_metageneration_not_match=4
19881990
)
19891991

1992+
@mock.patch(u"google.resumable_media._upload.get_boundary", return_value=b"==0==")
1993+
def test__do_multipart_upload_with_client(self, mock_get_boundary):
1994+
transport = self._mock_transport(http_client.OK, {})
1995+
client = mock.Mock(_http=transport, _connection=_Connection, spec=["_http"])
1996+
client._connection.API_BASE_URL = "https://storage.googleapis.com"
1997+
self._do_multipart_success(mock_get_boundary, client=client)
1998+
19901999
@mock.patch(u"google.resumable_media._upload.get_boundary", return_value=b"==0==")
19912000
def test__do_multipart_upload_with_metadata(self, mock_get_boundary):
19922001
self._do_multipart_success(mock_get_boundary, metadata={"test": "test"})
@@ -2010,6 +2019,7 @@ def test__do_multipart_upload_bad_size(self):
20102019

20112020
def _initiate_resumable_helper(
20122021
self,
2022+
client=None,
20132023
size=None,
20142024
extra_headers=None,
20152025
chunk_size=None,
@@ -2051,14 +2061,17 @@ def _initiate_resumable_helper(
20512061
return_value=object_metadata, spec=[]
20522062
)
20532063

2054-
# Create mocks to be checked for doing transport.
20552064
resumable_url = "http://test.invalid?upload_id=hey-you"
2056-
response_headers = {"location": resumable_url}
2057-
transport = self._mock_transport(http_client.OK, response_headers)
2058-
2059-
# Create some mock arguments and call the method under test.
2060-
client = mock.Mock(_http=transport, _connection=_Connection, spec=[u"_http"])
2061-
client._connection.API_BASE_URL = "https://storage.googleapis.com"
2065+
if not client:
2066+
# Create mocks to be checked for doing transport.
2067+
response_headers = {"location": resumable_url}
2068+
transport = self._mock_transport(http_client.OK, response_headers)
2069+
2070+
# Create some mock arguments and call the method under test.
2071+
client = mock.Mock(
2072+
_http=transport, _connection=_Connection, spec=[u"_http"]
2073+
)
2074+
client._connection.API_BASE_URL = "https://storage.googleapis.com"
20622075
data = b"hello hallo halo hi-low"
20632076
stream = io.BytesIO(data)
20642077
content_type = u"text/plain"
@@ -2149,7 +2162,7 @@ def _initiate_resumable_helper(
21492162
else:
21502163
self.assertIsNone(retry_strategy.max_cumulative_retry)
21512164
self.assertEqual(retry_strategy.max_retries, num_retries)
2152-
self.assertIs(transport, transport)
2165+
self.assertIs(client._http, transport)
21532166
# Make sure we never read from the stream.
21542167
self.assertEqual(stream.tell(), 0)
21552168

@@ -2237,6 +2250,15 @@ def test__initiate_resumable_upload_with_generation_not_match(self):
22372250
def test__initiate_resumable_upload_with_predefined_acl(self):
22382251
self._initiate_resumable_helper(predefined_acl="private")
22392252

2253+
def test__initiate_resumable_upload_with_client(self):
2254+
resumable_url = "http://test.invalid?upload_id=hey-you"
2255+
response_headers = {"location": resumable_url}
2256+
transport = self._mock_transport(http_client.OK, response_headers)
2257+
2258+
client = mock.Mock(_http=transport, _connection=_Connection, spec=[u"_http"])
2259+
client._connection.API_BASE_URL = "https://storage.googleapis.com"
2260+
self._initiate_resumable_helper(client=client)
2261+
22402262
def _make_resumable_transport(
22412263
self, headers1, headers2, headers3, total_bytes, data_corruption=False
22422264
):

0 commit comments

Comments
 (0)