Skip to content

Commit 6a47028

Browse files
committed
Merge pull request #1052 from dhermes/fix-1007
Moving rename() from Blob to Bucket.
2 parents 5a4e766 + 54fc24a commit 6a47028

File tree

4 files changed

+56
-47
lines changed

4 files changed

+56
-47
lines changed

gcloud/storage/blob.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -227,32 +227,6 @@ def exists(self, client=None):
227227
except NotFound:
228228
return False
229229

230-
def rename(self, new_name, client=None):
231-
"""Renames this blob using copy and delete operations.
232-
233-
Effectively, copies blob to the same bucket with a new name, then
234-
deletes the blob.
235-
236-
.. warning::
237-
This method will first duplicate the data and then delete the
238-
old blob. This means that with very large objects renaming
239-
could be a very (temporarily) costly or a very slow operation.
240-
241-
:type new_name: string
242-
:param new_name: The new name for this blob.
243-
244-
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
245-
:param client: Optional. The client to use. If not passed, falls back
246-
to the ``client`` stored on the blob's bucket.
247-
248-
:rtype: :class:`Blob`
249-
:returns: The newly-copied blob.
250-
"""
251-
new_blob = self.bucket.copy_blob(self, self.bucket, new_name,
252-
client=client)
253-
self.delete(client=client)
254-
return new_blob
255-
256230
def delete(self, client=None):
257231
"""Deletes a blob from Cloud Storage.
258232

gcloud/storage/bucket.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ def copy_blob(self, blob, destination_bucket, new_name=None,
434434
client=None):
435435
"""Copy the given blob to the given bucket, optionally with a new name.
436436
437-
:type blob: string or :class:`gcloud.storage.blob.Blob`
437+
:type blob: :class:`gcloud.storage.blob.Blob`
438438
:param blob: The blob to be copied.
439439
440440
:type destination_bucket: :class:`gcloud.storage.bucket.Bucket`
@@ -461,6 +461,35 @@ def copy_blob(self, blob, destination_bucket, new_name=None,
461461
new_blob._set_properties(copy_result)
462462
return new_blob
463463

464+
def rename_blob(self, blob, new_name, client=None):
465+
"""Rename the given blob using copy and delete operations.
466+
467+
Effectively, copies blob to the same bucket with a new name, then
468+
deletes the blob.
469+
470+
.. warning::
471+
472+
This method will first duplicate the data and then delete the
473+
old blob. This means that with very large objects renaming
474+
could be a very (temporarily) costly or a very slow operation.
475+
476+
:type blob: :class:`gcloud.storage.blob.Blob`
477+
:param blob: The blob to be renamed.
478+
479+
:type new_name: string
480+
:param new_name: The new name for this blob.
481+
482+
:type client: :class:`gcloud.storage.client.Client` or ``NoneType``
483+
:param client: Optional. The client to use. If not passed, falls back
484+
to the ``client`` stored on the current bucket.
485+
486+
:rtype: :class:`Blob`
487+
:returns: The newly-renamed blob.
488+
"""
489+
new_blob = self.copy_blob(blob, self, new_name, client=client)
490+
blob.delete(client=client)
491+
return new_blob
492+
464493
@property
465494
def cors(self):
466495
"""Retrieve CORS policies configured for this bucket.

gcloud/storage/test_blob.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -232,21 +232,6 @@ def test_exists_hit(self):
232232
bucket._blobs[BLOB_NAME] = 1
233233
self.assertTrue(blob.exists())
234234

235-
def test_rename(self):
236-
BLOB_NAME = 'blob-name'
237-
NEW_NAME = 'new-name'
238-
connection = _Connection()
239-
client = _Client(connection)
240-
bucket = _Bucket(client=client)
241-
blob = self._makeOne(BLOB_NAME, bucket=bucket)
242-
bucket._blobs[BLOB_NAME] = 1
243-
new_blob = blob.rename(NEW_NAME)
244-
self.assertEqual(blob.name, BLOB_NAME)
245-
self.assertEqual(new_blob.name, NEW_NAME)
246-
self.assertFalse(BLOB_NAME in bucket._blobs)
247-
self.assertEqual(bucket._deleted, [(BLOB_NAME, None)])
248-
self.assertTrue(NEW_NAME in bucket._blobs)
249-
250235
def test_delete(self):
251236
from six.moves.http_client import NOT_FOUND
252237
BLOB_NAME = 'blob-name'
@@ -1058,11 +1043,6 @@ def __init__(self, client=None):
10581043
self._copied = []
10591044
self._deleted = []
10601045

1061-
def copy_blob(self, blob, destination_bucket, new_name, client=None):
1062-
self._copied.append((blob, destination_bucket, new_name, client))
1063-
destination_bucket._blobs[new_name] = self._blobs[blob.name]
1064-
return blob.__class__(new_name, bucket=destination_bucket)
1065-
10661046
def delete_blob(self, blob_name, client=None):
10671047
del self._blobs[blob_name]
10681048
self._deleted.append((blob_name, client))

gcloud/storage/test_bucket.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,32 @@ class _Blob(object):
519519
self.assertEqual(kw['method'], 'POST')
520520
self.assertEqual(kw['path'], COPY_PATH)
521521

522+
def test_rename_blob(self):
523+
BUCKET_NAME = 'BUCKET_NAME'
524+
BLOB_NAME = 'blob-name'
525+
NEW_BLOB_NAME = 'new-blob-name'
526+
527+
DATA = {'name': NEW_BLOB_NAME}
528+
connection = _Connection(DATA)
529+
client = _Client(connection)
530+
bucket = self._makeOne(client=client, name=BUCKET_NAME)
531+
532+
class _Blob(object):
533+
534+
def __init__(self, name, bucket_name):
535+
self.name = name
536+
self.path = '/b/%s/o/%s' % (bucket_name, name)
537+
self._deleted = []
538+
539+
def delete(self, client=None):
540+
self._deleted.append(client)
541+
542+
blob = _Blob(BLOB_NAME, BUCKET_NAME)
543+
renamed_blob = bucket.rename_blob(blob, NEW_BLOB_NAME, client=client)
544+
self.assertTrue(renamed_blob.bucket is bucket)
545+
self.assertEqual(renamed_blob.name, NEW_BLOB_NAME)
546+
self.assertEqual(blob._deleted, [client])
547+
522548
def test_etag(self):
523549
ETAG = 'ETAG'
524550
properties = {'etag': ETAG}

0 commit comments

Comments
 (0)