Skip to content

Commit fb09637

Browse files
committed
Reducing usage of Bucket.new_blob; towards removal.
Updated Bucket.get_blob() and Bucket.delete_blob() to just take a string instead of string or Blob. Logic being that if the user already has a Blob, they can just call blob.delete() or blob._reload_properties() (more convenient method needed). Updated Bucket.delete_blobs() to check if each element in list of `blobs` is a string or a Blob. Updated Blob.delete() to call Bucket.delete_blob() with just a string and updated Blob.rename() to call Blob.delete() instead of re-implementing the mapping to Bucket.delete_blob(). Removed Test_Bucket.test_new_blob_existing, the last caller of Bucket.new_blob that sends a Blob instead of a string.
1 parent d668044 commit fb09637

5 files changed

Lines changed: 40 additions & 35 deletions

File tree

gcloud/storage/_helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def _reload_properties(self):
9494
:returns: The object you just reloaded data for.
9595
"""
9696
# Pass only '?projection=noAcl' here because 'acl' and related
97-
# are handled via custom endpoints..
97+
# are handled via custom endpoints.
9898
query_params = {'projection': 'noAcl'}
9999
self._properties = self.connection.api_request(
100100
method='GET', path=self.path, query_params=query_params)

gcloud/storage/blob.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,21 @@ def __init__(self, name, bucket=None, properties=None):
7474

7575
self.bucket = bucket
7676

77+
@staticmethod
78+
def path_helper(bucket_path, blob_name):
79+
"""Relative URL path for a blob.
80+
81+
:type bucket_path: string
82+
:param bucket_path: The URL path for a bucket.
83+
84+
:type blob_name: string
85+
:param blob_name: The name of the blob.
86+
87+
:rtype: string
88+
:returns: The relative URL path for ``blob_name``.
89+
"""
90+
return bucket_path + '/o/' + quote(blob_name, safe='')
91+
7792
@property
7893
def acl(self):
7994
"""Create our ACL on demand."""
@@ -109,7 +124,7 @@ def path(self):
109124
if not self.name:
110125
raise ValueError('Cannot determine path without a blob name.')
111126

112-
return self.bucket.path + '/o/' + quote(self.name, safe='')
127+
return self.path_helper(self.bucket.path, self.name)
113128

114129
@property
115130
def public_url(self):
@@ -179,7 +194,7 @@ def rename(self, new_name):
179194
:returns: The newly-copied blob.
180195
"""
181196
new_blob = self.bucket.copy_blob(self, self.bucket, new_name)
182-
self.bucket.delete_blob(self)
197+
self.delete()
183198
return new_blob
184199

185200
def delete(self):
@@ -191,7 +206,7 @@ def delete(self):
191206
(propagated from
192207
:meth:`gcloud.storage.bucket.Bucket.delete_blob`).
193208
"""
194-
return self.bucket.delete_blob(self)
209+
return self.bucket.delete_blob(self.name)
195210

196211
def download_to_file(self, file_obj):
197212
"""Download the contents of this blob into a file-like object.

gcloud/storage/bucket.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ def path(self):
163163

164164
return self.path_helper(self.name)
165165

166-
def get_blob(self, blob):
166+
def get_blob(self, blob_name):
167167
"""Get a blob object by name.
168168
169169
This will return None if the blob doesn't exist::
@@ -176,15 +176,13 @@ def get_blob(self, blob):
176176
>>> print bucket.get_blob('/does-not-exist.txt')
177177
None
178178
179-
:type blob: string or :class:`gcloud.storage.blob.Blob`
180-
:param blob: The name of the blob to retrieve.
179+
:type blob_name: string
180+
:param blob_name: The name of the blob to retrieve.
181181
182182
:rtype: :class:`gcloud.storage.blob.Blob` or None
183183
:returns: The blob object if it exists, otherwise None.
184184
"""
185-
# Coerce this -- either from a Blob or a string.
186-
blob = self.new_blob(blob)
187-
185+
blob = Blob(bucket=self, name=blob_name)
188186
try:
189187
response = self.connection.api_request(method='GET',
190188
path=blob.path)
@@ -303,10 +301,10 @@ def delete(self, force=False):
303301

304302
self.connection.api_request(method='DELETE', path=self.path)
305303

306-
def delete_blob(self, blob):
304+
def delete_blob(self, blob_name):
307305
"""Deletes a blob from the current bucket.
308306
309-
If the blob isn't found, raise a
307+
If the blob isn't found (backend 404), raises a
310308
:class:`gcloud.exceptions.NotFound`.
311309
312310
For example::
@@ -323,21 +321,17 @@ def delete_blob(self, blob):
323321
... except NotFound:
324322
... pass
325323
324+
:type blob_name: string
325+
:param blob_name: A blob name to delete.
326326
327-
:type blob: string or :class:`gcloud.storage.blob.Blob`
328-
:param blob: A blob name or Blob object to delete.
329-
330-
:rtype: :class:`gcloud.storage.blob.Blob`
331-
:returns: The blob that was just deleted.
332327
:raises: :class:`gcloud.exceptions.NotFound` (to suppress
333328
the exception, call ``delete_blobs``, passing a no-op
334329
``on_error`` callback, e.g.::
335330
336331
>>> bucket.delete_blobs([blob], on_error=lambda blob: None)
337332
"""
338-
blob = self.new_blob(blob)
339-
self.connection.api_request(method='DELETE', path=blob.path)
340-
return blob
333+
blob_path = Blob.path_helper(self.path, blob_name)
334+
self.connection.api_request(method='DELETE', path=blob_path)
341335

342336
def delete_blobs(self, blobs, on_error=None):
343337
"""Deletes a list of blobs from the current bucket.
@@ -357,7 +351,10 @@ def delete_blobs(self, blobs, on_error=None):
357351
"""
358352
for blob in blobs:
359353
try:
360-
self.delete_blob(blob)
354+
blob_name = blob
355+
if not isinstance(blob_name, six.string_types):
356+
blob_name = blob.name
357+
self.delete_blob(blob_name)
361358
except NotFound:
362359
if on_error is not None:
363360
on_error(blob)

gcloud/storage/test_blob.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,17 +1031,17 @@ def __init__(self, connection):
10311031
self._blobs = {}
10321032
self._deleted = []
10331033

1034-
def get_blob(self, blob):
1035-
return self._blobs.get(blob)
1034+
def get_blob(self, blob_name):
1035+
return self._blobs.get(blob_name)
10361036

10371037
def copy_blob(self, blob, destination_bucket, new_name):
10381038
destination_bucket._blobs[new_name] = self._blobs[blob.name]
10391039
return blob.__class__(None, bucket=destination_bucket,
10401040
properties={'name': new_name})
10411041

1042-
def delete_blob(self, blob):
1043-
del self._blobs[blob.name]
1044-
self._deleted.append(blob.name)
1042+
def delete_blob(self, blob_name):
1043+
del self._blobs[blob_name]
1044+
self._deleted.append(blob_name)
10451045

10461046

10471047
class _Signer(object):

gcloud/storage/test_bucket.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,6 @@ def test_iterator_explicit(self):
306306
self.assertEqual(kw['path'], '/b/%s/o' % NAME)
307307
self.assertEqual(kw['query_params'], EXPECTED)
308308

309-
def test_new_blob_existing(self):
310-
from gcloud.storage.blob import Blob
311-
bucket = self._makeOne()
312-
existing = Blob(None, bucket=bucket)
313-
self.assertTrue(bucket.new_blob(existing) is existing)
314-
315309
def test_new_blob_str(self):
316310
from gcloud.storage.blob import Blob
317311
BLOB_NAME = 'blob-name'
@@ -410,9 +404,8 @@ def test_delete_blob_hit(self):
410404
BLOB_NAME = 'blob-name'
411405
connection = _Connection({})
412406
bucket = self._makeOne(connection, NAME)
413-
blob = bucket.delete_blob(BLOB_NAME)
414-
self.assertTrue(blob.bucket is bucket)
415-
self.assertEqual(blob.name, BLOB_NAME)
407+
result = bucket.delete_blob(BLOB_NAME)
408+
self.assertTrue(result is None)
416409
kw, = connection._requested
417410
self.assertEqual(kw['method'], 'DELETE')
418411
self.assertEqual(kw['path'], '/b/%s/o/%s' % (NAME, BLOB_NAME))

0 commit comments

Comments
 (0)