diff --git a/gcloud/storage/_helpers.py b/gcloud/storage/_helpers.py index bbe60c923818..725f91ed5071 100644 --- a/gcloud/storage/_helpers.py +++ b/gcloud/storage/_helpers.py @@ -39,20 +39,15 @@ def path(self): """Abstract getter for the object path.""" raise NotImplementedError - def __init__(self, name=None, properties=None): + def __init__(self, name=None): """_PropertyMixin constructor. :type name: string :param name: The name of the object. - - :type properties: dict - :param properties: All the other data provided by Cloud Storage. """ self.name = name self._properties = {} self._changes = set() - if properties is not None: - self._properties.update(properties) @property def properties(self): diff --git a/gcloud/storage/api.py b/gcloud/storage/api.py index 526a15e7be5f..4783dcfa9763 100644 --- a/gcloud/storage/api.py +++ b/gcloud/storage/api.py @@ -125,9 +125,9 @@ def get_bucket(bucket_name, connection=None): if connection is None: connection = get_default_connection() - bucket_path = Bucket.path_helper(bucket_name) - response = connection.api_request(method='GET', path=bucket_path) - return Bucket(properties=response, connection=connection) + bucket = Bucket(bucket_name, connection=connection) + bucket._reload_properties() + return bucket def create_bucket(bucket_name, project=None, connection=None): @@ -169,7 +169,10 @@ def create_bucket(bucket_name, project=None, connection=None): response = connection.api_request(method='POST', path='/b', query_params=query_params, data={'name': bucket_name}) - return Bucket(properties=response, connection=connection) + name = response.get('name') + bucket = Bucket(name, connection=connection) + bucket._properties = response + return bucket class _BucketIterator(Iterator): @@ -194,4 +197,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(properties=item, connection=self.connection) + name = item.get('name') + bucket = Bucket(name, connection=self.connection) + bucket._properties = item + yield bucket diff --git a/gcloud/storage/blob.py b/gcloud/storage/blob.py index ac3f9ce86817..e1ae7a41d5a2 100644 --- a/gcloud/storage/blob.py +++ b/gcloud/storage/blob.py @@ -62,17 +62,14 @@ class Blob(_PropertyMixin): # ACL rules are lazily retrieved. _acl = None - def __init__(self, name, bucket=None, properties=None): - if name is None and properties is not None: - name = properties.get('name') - + def __init__(self, name, bucket=None): if bucket is None: bucket = _implicit_environ.get_default_bucket() if bucket is None: raise ValueError('A Blob must have a bucket set.') - super(Blob, self).__init__(name=name, properties=properties) + super(Blob, self).__init__(name=name) self.bucket = bucket diff --git a/gcloud/storage/bucket.py b/gcloud/storage/bucket.py index 7422db121b5f..0200d766d126 100644 --- a/gcloud/storage/bucket.py +++ b/gcloud/storage/bucket.py @@ -69,7 +69,10 @@ def get_items_from_response(self, response): """ self.prefixes = tuple(response.get('prefixes', ())) for item in response.get('items', []): - yield Blob(None, properties=item, bucket=self.bucket) + name = item.get('name') + blob = Blob(name, bucket=self.bucket) + blob._properties = item + yield blob class Bucket(_PropertyMixin): @@ -92,10 +95,8 @@ class Bucket(_PropertyMixin): # ACL rules are lazily retrieved. _acl = _default_object_acl = None - def __init__(self, name=None, connection=None, properties=None): - if name is None and properties is not None: - name = properties.get('name') - super(Bucket, self).__init__(name=name, properties=properties) + def __init__(self, name=None, connection=None): + super(Bucket, self).__init__(name=name) self._connection = connection def __repr__(self): @@ -190,7 +191,10 @@ def get_blob(self, blob_name): try: response = self.connection.api_request(method='GET', path=blob.path) - return Blob(None, bucket=self, properties=response) + name = response.get('name') # Expect this to be blob_name + blob = Blob(name, bucket=self) + blob._properties = response + return blob except NotFound: return None diff --git a/gcloud/storage/iterator.py b/gcloud/storage/iterator.py index bb47490bd368..284e9b5392e4 100644 --- a/gcloud/storage/iterator.py +++ b/gcloud/storage/iterator.py @@ -25,7 +25,9 @@ class MyIterator(Iterator): def get_items_from_response(self, response): items = response.get('items', []) for item in items: - yield MyItemClass(properties=item, other_arg=True) + my_item = MyItemClass(other_arg=True) + my_item._properties = item + yield my_item You then can use this to get **all** the results from a resource:: diff --git a/gcloud/storage/test_api.py b/gcloud/storage/test_api.py index 69bd5a2fee5e..11db48572a67 100644 --- a/gcloud/storage/test_api.py +++ b/gcloud/storage/test_api.py @@ -30,7 +30,7 @@ def test_miss(self): 'storage', conn.API_VERSION, 'b', - 'nonesuch', + 'nonesuch?projection=noAcl', ]) http = conn._http = Http( {'status': '404', 'content-type': 'application/json'}, @@ -52,7 +52,7 @@ def _lookup_bucket_hit_helper(self, use_default=False): 'storage', conn.API_VERSION, 'b', - '%s' % (BLOB_NAME,), + '%s?projection=noAcl' % (BLOB_NAME,), ]) http = conn._http = Http( {'status': '200', 'content-type': 'application/json'}, @@ -156,7 +156,7 @@ def test_miss(self): 'storage', conn.API_VERSION, 'b', - 'nonesuch', + 'nonesuch?projection=noAcl', ]) http = conn._http = Http( {'status': '404', 'content-type': 'application/json'}, @@ -177,7 +177,7 @@ def _get_bucket_hit_helper(self, use_default=False): 'storage', conn.API_VERSION, 'b', - '%s' % (BLOB_NAME,), + '%s?projection=noAcl' % (BLOB_NAME,), ]) http = conn._http = Http( {'status': '200', 'content-type': 'application/json'}, diff --git a/gcloud/storage/test_blob.py b/gcloud/storage/test_blob.py index b4dd01355d11..3fafb8cd790c 100644 --- a/gcloud/storage/test_blob.py +++ b/gcloud/storage/test_blob.py @@ -19,7 +19,10 @@ class Test_Blob(unittest2.TestCase): def _makeOne(self, *args, **kw): from gcloud.storage.blob import Blob - return Blob(*args, **kw) + properties = kw.pop('properties', None) + blob = Blob(*args, **kw) + blob._properties = properties or {} + return blob def test_ctor_no_bucket(self): self.assertRaises(ValueError, self._makeOne, None) @@ -63,29 +66,6 @@ def test_ctor_explicit(self): self.assertEqual(blob.properties, properties) self.assertTrue(blob._acl is None) - def test_ctor_no_name_defaults(self): - BLOB_NAME = 'blob-name' - properties = {'key': 'value', 'name': BLOB_NAME} - FAKE_BUCKET = _Bucket(None) - blob = self._makeOne(None, bucket=FAKE_BUCKET, properties=properties) - self.assertEqual(blob.bucket, FAKE_BUCKET) - self.assertEqual(blob.connection, None) - self.assertEqual(blob.name, BLOB_NAME) - self.assertEqual(blob.properties, properties) - self.assertTrue(blob._acl is None) - - def test_ctor_no_name_explicit(self): - BLOB_NAME = 'blob-name' - connection = _Connection() - bucket = _Bucket(connection) - properties = {'key': 'value', 'name': BLOB_NAME} - blob = self._makeOne(None, properties=properties, bucket=bucket) - self.assertTrue(blob.bucket is bucket) - self.assertTrue(blob.connection is connection) - self.assertEqual(blob.name, BLOB_NAME) - self.assertEqual(blob.properties, properties) - self.assertTrue(blob._acl is None) - def test_acl_property(self): from gcloud.storage.acl import ObjectACL FAKE_BUCKET = _Bucket(None) @@ -1043,8 +1023,7 @@ def __init__(self, connection): def copy_blob(self, blob, destination_bucket, new_name): destination_bucket._blobs[new_name] = self._blobs[blob.name] - return blob.__class__(None, bucket=destination_bucket, - properties={'name': new_name}) + return blob.__class__(new_name, bucket=destination_bucket) def delete_blob(self, blob_name): del self._blobs[blob_name] diff --git a/gcloud/storage/test_bucket.py b/gcloud/storage/test_bucket.py index f2f32a6c6cc7..081344598825 100644 --- a/gcloud/storage/test_bucket.py +++ b/gcloud/storage/test_bucket.py @@ -64,7 +64,10 @@ class Test_Bucket(unittest2.TestCase): def _makeOne(self, *args, **kw): from gcloud.storage.bucket import Bucket - return Bucket(*args, **kw) + properties = kw.pop('properties', None) + bucket = Bucket(*args, **kw) + bucket._properties = properties or {} + return bucket def test_ctor_defaults(self): bucket = self._makeOne() @@ -78,34 +81,13 @@ def test_ctor_explicit(self): NAME = 'name' connection = _Connection() properties = {'key': 'value'} - bucket = self._makeOne(NAME, connection, properties) + bucket = self._makeOne(NAME, connection, properties=properties) self.assertTrue(bucket.connection is connection) 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_ctor_no_name_defaults(self): - NAME = 'name' - properties = {'key': 'value', 'name': NAME} - 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_ctor_no_name_explicit(self): - NAME = 'name' - connection = _Connection() - properties = {'key': 'value', 'name': NAME} - bucket = self._makeOne(connection=connection, properties=properties) - self.assertTrue(bucket.connection is connection) - 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___iter___empty(self): NAME = 'name' connection = _Connection({'items': []}) @@ -164,7 +146,7 @@ def api_request(cls, *args, **kwargs): raise NotFound(args) BUCKET_NAME = 'bucket-name' - bucket = self._makeOne(connection=_FakeConnection, name=BUCKET_NAME) + bucket = self._makeOne(BUCKET_NAME, connection=_FakeConnection) self.assertFalse(bucket.exists()) expected_called_kwargs = { 'method': 'GET', @@ -188,7 +170,7 @@ def api_request(cls, *args, **kwargs): return object() BUCKET_NAME = 'bucket-name' - bucket = self._makeOne(connection=_FakeConnection, name=BUCKET_NAME) + bucket = self._makeOne(BUCKET_NAME, connection=_FakeConnection) self.assertTrue(bucket.exists()) expected_called_kwargs = { 'method': 'GET', @@ -592,7 +574,7 @@ def test_get_cors_eager(self): } before = {'cors': [CORS_ENTRY, {}]} connection = _Connection() - bucket = self._makeOne(NAME, connection, before) + bucket = self._makeOne(NAME, connection, properties=before) entries = bucket.get_cors() self.assertEqual(len(entries), 2) self.assertEqual(entries[0]['maxAgeSeconds'], @@ -697,7 +679,7 @@ def test_get_lifecycle_eager(self): LC_RULE = {'action': {'type': 'Delete'}, 'condition': {'age': 42}} before = {'lifecycle': {'rule': [LC_RULE]}} connection = _Connection() - bucket = self._makeOne(NAME, connection, before) + bucket = self._makeOne(NAME, connection, properties=before) entries = bucket.get_lifecycle() self.assertEqual(len(entries), 1) self.assertEqual(entries[0]['action']['type'], 'Delete') @@ -744,7 +726,7 @@ def test_location_getter(self): NAME = 'name' connection = _Connection() before = {'location': 'AS'} - bucket = self._makeOne(NAME, connection, before) + bucket = self._makeOne(NAME, connection, properties=before) self.assertEqual(bucket.location, 'AS') kw = connection._requested self.assertEqual(len(kw), 0) @@ -795,7 +777,7 @@ def test_enable_logging_defaults(self): } connection = _Connection(resp_to_reload, resp_to_enable_logging, resp_to_enable_logging) - bucket = self._makeOne(NAME, connection, before) + bucket = self._makeOne(NAME, connection, properties=before) self.assertTrue(bucket.get_logging() is None) bucket.enable_logging(LOG_BUCKET) info = bucket.get_logging() @@ -826,7 +808,7 @@ def test_enable_logging_explicit(self): connection = _Connection(resp_to_reload, resp_to_enable_logging, resp_to_enable_logging) - bucket = self._makeOne(NAME, connection, before) + bucket = self._makeOne(NAME, connection, properties=before) self.assertTrue(bucket.get_logging() is None) bucket.enable_logging(LOG_BUCKET, LOG_PFX) info = bucket.get_logging() @@ -852,7 +834,7 @@ def test_disable_logging(self): resp_to_disable_logging = {'logging': None} connection = _Connection(resp_to_reload, resp_to_disable_logging, resp_to_disable_logging) - bucket = self._makeOne(NAME, connection, before) + bucket = self._makeOne(NAME, connection, properties=before) self.assertTrue(bucket.get_logging() is not None) bucket.disable_logging() self.assertTrue(bucket.get_logging() is None) @@ -923,7 +905,7 @@ def test_versioning_enabled_getter(self): NAME = 'name' before = {'versioning': {'enabled': True}} connection = _Connection() - bucket = self._makeOne(NAME, connection, before) + bucket = self._makeOne(NAME, connection, properties=before) self.assertEqual(bucket.versioning_enabled, True) kw = connection._requested self.assertEqual(len(kw), 0) @@ -933,7 +915,7 @@ def test_versioning_enabled_setter(self): before = {'versioning': {'enabled': False}} after = {'versioning': {'enabled': True}} connection = _Connection(after) - bucket = self._makeOne(NAME, connection, before) + bucket = self._makeOne(NAME, connection, properties=before) self.assertFalse(bucket.versioning_enabled) bucket.versioning_enabled = True bucket.patch()