Skip to content

Commit

Permalink
Merge pull request #602 from dhermes/fix-590
Browse files Browse the repository at this point in the history
Removing __iter__ and __contains__ from Connection in storage.
  • Loading branch information
dhermes committed Feb 9, 2015
2 parents ab0a587 + 45fd420 commit a6317d1
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 106 deletions.
2 changes: 1 addition & 1 deletion docs/_components/storage-getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ The :class:`Connection <gcloud.storage.connection.Connection>` object
itself is iterable, so you can loop over it, or call ``list`` on it to get
a list object::

>>> for bucket in connection:
>>> for bucket in connection.get_all_buckets():
... print bucket.name
>>> print list(connection)

Expand Down
12 changes: 12 additions & 0 deletions gcloud/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ def __iter__(self):
def __contains__(self, blob):
return self.get_blob(blob) is not None

def exists(self):
"""Determines whether or not this bucket exists.
:rtype: boolean
:returns: True if the bucket exists in Cloud Storage.
"""
try:
self.connection.get_bucket(self.name)
return True
except NotFound:
return False

@property
def acl(self):
"""Create our ACL on demand."""
Expand Down
24 changes: 2 additions & 22 deletions gcloud/storage/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

from gcloud.connection import Connection as _Base
from gcloud.exceptions import make_exception
from gcloud.exceptions import NotFound
from gcloud.storage.bucket import Bucket
from gcloud.storage.iterator import Iterator

Expand Down Expand Up @@ -57,15 +56,9 @@ class Connection(_Base):
A :class:`Connection` is actually iterable and will return the
:class:`gcloud.storage.bucket.Bucket` objects inside the project::
>>> for bucket in connection:
>>> for bucket in connection.get_all_buckets():
>>> print bucket
<Bucket: my-bucket-name>
In that same way, you can check for whether a bucket exists inside
the project using Python's ``in`` operator::
>>> print 'my-bucket-name' in connection
True
"""

API_VERSION = 'v1'
Expand All @@ -82,16 +75,6 @@ def __init__(self, project, *args, **kwargs):
super(Connection, self).__init__(*args, **kwargs)
self.project = project

def __iter__(self):
return iter(_BucketIterator(connection=self))

def __contains__(self, bucket_name):
try:
self.get_bucket(bucket_name)
return True
except NotFound:
return False

def build_api_url(self, path, query_params=None, api_base_url=None,
api_version=None, upload=False):
"""Construct an API url given a few components, some optional.
Expand Down Expand Up @@ -265,14 +248,11 @@ def get_all_buckets(self):
>>> connection = storage.get_connection(project)
>>> for bucket in connection.get_all_buckets():
>>> print bucket
>>> # ... is the same as ...
>>> for bucket in connection:
>>> print bucket
:rtype: list of :class:`gcloud.storage.bucket.Bucket` objects.
:returns: All buckets belonging to this project.
"""
return list(self)
return iter(_BucketIterator(connection=self))

def get_bucket(self, bucket_name):
"""Get a bucket by name.
Expand Down
33 changes: 33 additions & 0 deletions gcloud/storage/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,39 @@ def test___contains___hit(self):
self.assertEqual(kw['method'], 'GET')
self.assertEqual(kw['path'], '/b/%s/o/%s' % (NAME, BLOB_NAME))

def test_exists_miss(self):
from gcloud.exceptions import NotFound

class _FakeConnection(object):

_called_with = []

@classmethod
def get_bucket(cls, bucket_name):
cls._called_with.append(bucket_name)
raise NotFound(bucket_name)

NAME = 'name'
bucket = self._makeOne(connection=_FakeConnection, name=NAME)
self.assertFalse(bucket.exists())
self.assertEqual(_FakeConnection._called_with, [NAME])

def test_exists_hit(self):
class _FakeConnection(object):

_called_with = []

@classmethod
def get_bucket(cls, bucket_name):
cls._called_with.append(bucket_name)
# exists() does not use the return value
return object()

NAME = 'name'
bucket = self._makeOne(connection=_FakeConnection, name=NAME)
self.assertTrue(bucket.exists())
self.assertEqual(_FakeConnection._called_with, [NAME])

def test_acl_property(self):
from gcloud.storage.acl import BucketACL
bucket = self._makeOne()
Expand Down
90 changes: 7 additions & 83 deletions gcloud/storage/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,82 +63,6 @@ def authorize(self, http):
self.assertTrue(conn.http is authorized)
self.assertTrue(isinstance(creds._called_with, httplib2.Http))

def test___iter___empty(self):
PROJECT = 'project'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
'storage',
conn.API_VERSION,
'b?project=%s' % PROJECT,
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
'{}',
)
blobs = list(conn)
self.assertEqual(len(blobs), 0)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test___iter___non_empty(self):
PROJECT = 'project'
BLOB_NAME = 'blob-name'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
'storage',
conn.API_VERSION,
'b?project=%s' % PROJECT,
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
'{"items": [{"name": "%s"}]}' % BLOB_NAME,
)
blobs = list(conn)
self.assertEqual(len(blobs), 1)
self.assertEqual(blobs[0].name, BLOB_NAME)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test___contains___miss(self):
PROJECT = 'project'
NONESUCH = 'nonesuch'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
'storage',
conn.API_VERSION,
'b',
'nonesuch?project=%s' % PROJECT,
])
http = conn._http = Http(
{'status': '404', 'content-type': 'application/json'},
'{}',
)
self.assertFalse(NONESUCH in conn)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test___contains___hit(self):
PROJECT = 'project'
BLOB_NAME = 'blob-name'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
'storage',
conn.API_VERSION,
'b',
'%s?project=%s' % (BLOB_NAME, PROJECT),
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
'{"name": "%s"}' % BLOB_NAME,
)
self.assertTrue(BLOB_NAME in conn)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test_build_api_url_no_extra_query_params(self):
PROJECT = 'project'
conn = self._makeOne(PROJECT)
Expand Down Expand Up @@ -370,14 +294,14 @@ def test_get_all_buckets_empty(self):
{'status': '200', 'content-type': 'application/json'},
'{}',
)
blobs = conn.get_all_buckets()
self.assertEqual(len(blobs), 0)
buckets = list(conn.get_all_buckets())
self.assertEqual(len(buckets), 0)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

def test_get_all_buckets_non_empty(self):
PROJECT = 'project'
BLOB_NAME = 'blob-name'
BUCKET_NAME = 'bucket-name'
conn = self._makeOne(PROJECT)
URI = '/'.join([
conn.API_BASE_URL,
Expand All @@ -387,11 +311,11 @@ def test_get_all_buckets_non_empty(self):
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
'{"items": [{"name": "%s"}]}' % BLOB_NAME,
'{"items": [{"name": "%s"}]}' % BUCKET_NAME,
)
blobs = conn.get_all_buckets()
self.assertEqual(len(blobs), 1)
self.assertEqual(blobs[0].name, BLOB_NAME)
buckets = list(conn.get_all_buckets())
self.assertEqual(len(buckets), 1)
self.assertEqual(buckets[0].name, BUCKET_NAME)
self.assertEqual(http._called_with['method'], 'GET')
self.assertEqual(http._called_with['uri'], URI)

Expand Down

0 comments on commit a6317d1

Please sign in to comment.