Skip to content

Commit

Permalink
Folding Blob.from_dict and Bucket.from_dict into constructors.
Browse files Browse the repository at this point in the history
See googleapis#545 for context.
  • Loading branch information
dhermes committed Jan 27, 2015
1 parent 03eb130 commit 647e819
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 61 deletions.
20 changes: 2 additions & 18 deletions gcloud/storage/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ def __init__(self, bucket=None, name=None, properties=None):
:type properties: dict
:param properties: All the other data provided by Cloud Storage.
"""
if name is None and properties is not None:
name = properties.get('name')
super(Blob, self).__init__(name=name, properties=properties)
self.bucket = bucket

Expand All @@ -87,24 +89,6 @@ def acl(self):
self._acl = ObjectACL(self)
return self._acl

@classmethod
def from_dict(cls, blob_dict, bucket=None):
"""Instantiate a :class:`Blob` from data returned by the JSON API.
:type blob_dict: dict
:param blob_dict: A dictionary of data returned from getting an
Cloud Storage object.
:type bucket: :class:`gcloud.storage.bucket.Bucket`
:param bucket: The bucket to which this blob belongs (and by
proxy, which connection to use).
:rtype: :class:`Blob`
:returns: A blob based on the data provided.
"""

return cls(bucket=bucket, name=blob_dict['name'], properties=blob_dict)

def __repr__(self):
if self.bucket:
bucket_name = self.bucket.name
Expand Down
21 changes: 5 additions & 16 deletions gcloud/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"""Create / interact with gcloud storage buckets."""

import os
import six

from gcloud.storage._helpers import _PropertyMixin
from gcloud.storage._helpers import _scalar_property
Expand All @@ -23,7 +24,6 @@
from gcloud.storage.acl import DefaultObjectACL
from gcloud.storage.iterator import Iterator
from gcloud.storage.blob import Blob
import six


class _BlobIterator(Iterator):
Expand All @@ -50,7 +50,7 @@ def get_items_from_response(self, response):
"""
self.prefixes = tuple(response.get('prefixes', ()))
for item in response.get('items', []):
yield Blob.from_dict(item, bucket=self.bucket)
yield Blob(properties=item, bucket=self.bucket)


class Bucket(_PropertyMixin):
Expand Down Expand Up @@ -88,22 +88,11 @@ class Bucket(_PropertyMixin):
_acl = _default_object_acl = None

def __init__(self, connection=None, name=None, properties=None):
if name is None and properties is not None:
name = properties.get('name')
super(Bucket, self).__init__(name=name, properties=properties)
self._connection = connection

@classmethod
def from_dict(cls, bucket_dict, connection=None):
"""Construct a new bucket from a dictionary of data from Cloud Storage.
:type bucket_dict: dict
:param bucket_dict: The dictionary of data to construct a bucket from.
:rtype: :class:`Bucket`
:returns: A bucket constructed from the data provided.
"""
return cls(connection=connection, name=bucket_dict['name'],
properties=bucket_dict)

def __repr__(self):
return '<Bucket: %s>' % self.name

Expand Down Expand Up @@ -169,7 +158,7 @@ def get_blob(self, blob):
try:
response = self.connection.api_request(method='GET',
path=blob.path)
return Blob.from_dict(response, bucket=self)
return Blob(properties=response, bucket=self)
except exceptions.NotFound:
return None

Expand Down
6 changes: 3 additions & 3 deletions gcloud/storage/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def get_bucket(self, bucket_name):
"""
bucket = self.new_bucket(bucket_name)
response = self.api_request(method='GET', path=bucket.path)
return Bucket.from_dict(response, connection=self)
return Bucket(properties=response, connection=self)

def lookup(self, bucket_name):
"""Get a bucket by name, returning None if not found.
Expand Down Expand Up @@ -430,7 +430,7 @@ def create_bucket(self, bucket):
bucket = self.new_bucket(bucket)
response = self.api_request(method='POST', path='/b',
data={'name': bucket.name})
return Bucket.from_dict(response, connection=self)
return Bucket(properties=response, connection=self)

def delete_bucket(self, bucket, force=False):
"""Delete a bucket.
Expand Down Expand Up @@ -575,7 +575,7 @@ def get_items_from_response(self, response):
:param response: The JSON API response for a page of buckets.
"""
for item in response.get('items', []):
yield Bucket.from_dict(item, connection=self.connection)
yield Bucket(properties=item, connection=self.connection)


def _get_expiration_seconds(expiration):
Expand Down
2 changes: 1 addition & 1 deletion gcloud/storage/iterator.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MyIterator(Iterator):
def get_items_from_response(self, response):
items = response.get('items', [])
for item in items:
yield MyItemClass.from_dict(item, other_arg=True)
yield MyItemClass(properties=item, other_arg=True)
You then can use this to get **all** the results from a resource::
Expand Down
20 changes: 8 additions & 12 deletions gcloud/storage/test_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@

class Test_Blob(unittest2.TestCase):

def _getTargetClass(self):
from gcloud.storage.blob import Blob
return Blob

def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
from gcloud.storage.blob import Blob
return Blob(*args, **kw)

def test_ctor_defaults(self):
blob = self._makeOne()
Expand All @@ -44,24 +41,22 @@ def test_ctor_explicit(self):
self.assertEqual(blob.properties, properties)
self.assertTrue(blob._acl is None)

def test_from_dict_defaults(self):
def test_ctor_no_name_defaults(self):
BLOB_NAME = 'blob-name'
properties = {'key': 'value', 'name': BLOB_NAME}
klass = self._getTargetClass()
blob = klass.from_dict(properties)
blob = self._makeOne(properties=properties)
self.assertEqual(blob.bucket, None)
self.assertEqual(blob.connection, None)
self.assertEqual(blob.name, BLOB_NAME)
self.assertEqual(blob.properties, properties)
self.assertTrue(blob._acl is None)

def test_from_dict_explicit(self):
def test_ctor_no_name_explicit(self):
BLOB_NAME = 'blob-name'
connection = _Connection()
bucket = _Bucket(connection)
properties = {'key': 'value', 'name': BLOB_NAME}
klass = self._getTargetClass()
blob = klass.from_dict(properties, bucket)
blob = self._makeOne(properties=properties, bucket=bucket)
self.assertTrue(blob.bucket is bucket)
self.assertTrue(blob.connection is connection)
self.assertEqual(blob.name, BLOB_NAME)
Expand Down Expand Up @@ -878,7 +873,8 @@ def get_blob(self, blob):

def copy_blob(self, blob, destination_bucket, new_name):
destination_bucket._blobs[new_name] = self._blobs[blob.name]
return blob.from_dict({'name': new_name}, bucket=destination_bucket)
return blob.__class__(properties={'name': new_name},
bucket=destination_bucket)

def delete_blob(self, blob):
del self._blobs[blob.name]
Expand Down
17 changes: 6 additions & 11 deletions gcloud/storage/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,9 @@ def test_get_items_from_response_non_empty(self):

class Test_Bucket(unittest2.TestCase):

def _getTargetClass(self):
from gcloud.storage.bucket import Bucket
return Bucket

def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
from gcloud.storage.bucket import Bucket
return Bucket(*args, **kw)

def test_ctor_defaults(self):
bucket = self._makeOne()
Expand All @@ -88,23 +85,21 @@ def test_ctor_explicit(self):
self.assertTrue(bucket._acl is None)
self.assertTrue(bucket._default_object_acl is None)

def test_from_dict_defaults(self):
def test_ctor_no_name_defaults(self):
NAME = 'name'
properties = {'key': 'value', 'name': NAME}
klass = self._getTargetClass()
bucket = klass.from_dict(properties)
bucket = self._makeOne(properties=properties)
self.assertEqual(bucket.connection, None)
self.assertEqual(bucket.name, NAME)
self.assertEqual(bucket.properties, properties)
self.assertTrue(bucket._acl is None)
self.assertTrue(bucket._default_object_acl is None)

def test_from_dict_explicit(self):
def test_ctor_no_name_explicit(self):
NAME = 'name'
connection = _Connection()
properties = {'key': 'value', 'name': NAME}
klass = self._getTargetClass()
bucket = klass.from_dict(properties, connection)
bucket = self._makeOne(connection=connection, properties=properties)
self.assertTrue(bucket.connection is connection)
self.assertEqual(bucket.name, NAME)
self.assertEqual(bucket.properties, properties)
Expand Down

0 comments on commit 647e819

Please sign in to comment.