Skip to content

Commit

Permalink
Move 'key._KeyIterator' -> 'bucket._KeyIterator'.
Browse files Browse the repository at this point in the history
The iterator is an implementation detail of 'Bucket'.
  • Loading branch information
tseaver committed Nov 8, 2014
1 parent a2c8c00 commit 13b4e94
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 75 deletions.
32 changes: 29 additions & 3 deletions gcloud/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,31 @@
from gcloud.storage.acl import DefaultObjectACL
from gcloud.storage.iterator import Iterator
from gcloud.storage.key import Key
from gcloud.storage.key import _KeyIterator


class _KeyIterator(Iterator):
"""An iterator listing keys in a bucket
You shouldn't have to use this directly, but instead should use the
helper methods on :class:`gcloud.storage.key.Bucket` objects.
:type bucket: :class:`gcloud.storage.bucket.Bucket`
:param bucket: The bucket from which to list keys.
"""
def __init__(self, bucket, connection=None, extra_params=None):
self.bucket = bucket
super(_KeyIterator, self).__init__(
connection=bucket.connection, path=bucket.path + '/o',
extra_params=extra_params)

def get_items_from_response(self, response):
"""Yield :class:`.storage.key.Key` items from response.
:type response: dict
:param response: The JSON API response for a page of keys.
"""
for item in response.get('items', []):
yield Key.from_dict(item, bucket=self.bucket)


class Bucket(_PropertyMixin):
Expand All @@ -21,6 +45,7 @@ class Bucket(_PropertyMixin):
:type name: string
:param name: The name of the bucket.
"""
_iterator_class = _KeyIterator

CUSTOM_PROPERTY_ACCESSORS = {
'acl': 'get_acl()',
Expand Down Expand Up @@ -66,7 +91,7 @@ def __repr__(self):
return '<Bucket: %s>' % self.name

def __iter__(self):
return iter(_KeyIterator(bucket=self))
return iter(self._iterator_class(bucket=self))

def __contains__(self, key):
return self.get_key(key) is not None
Expand Down Expand Up @@ -640,6 +665,7 @@ def make_public(self, recursive=False, future=False):
doa.save()

if recursive:
for key in self:
iterator = self._iterator_class(self)
for key in iterator:
key.get_acl().all().grant_read()
key.save_acl()
26 changes: 0 additions & 26 deletions gcloud/storage/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from gcloud.storage._helpers import _scalar_property
from gcloud.storage.acl import ObjectACL
from gcloud.storage.exceptions import StorageError
from gcloud.storage.iterator import Iterator


class Key(_PropertyMixin):
Expand Down Expand Up @@ -590,31 +589,6 @@ def updated(self):
return self.properties['updated']


class _KeyIterator(Iterator):
"""An iterator listing keys.
You shouldn't have to use this directly, but instead should use the
helper methods on :class:`gcloud.storage.key.Key` objects.
:type bucket: :class:`gcloud.storage.bucket.Bucket`
:param bucket: The bucket from which to list keys.
"""
def __init__(self, bucket, extra_params=None):
self.bucket = bucket
super(_KeyIterator, self).__init__(
connection=bucket.connection, path=bucket.path + '/o',
extra_params=extra_params)

def get_items_from_response(self, response):
"""Yield :class:`.storage.key.Key` items from response.
:type response: dict
:param response: The JSON API response for a page of keys.
"""
for item in response.get('items', []):
yield Key.from_dict(item, bucket=self.bucket)


class _KeyDataIterator(object):
"""An iterator listing data stored in a key.
Expand Down
58 changes: 52 additions & 6 deletions gcloud/storage/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -832,9 +832,7 @@ def test_make_public_w_future(self):

def test_make_public_recursive(self):
from gcloud.storage.acl import _ACLEntity
from gcloud._testing import _Monkey
from gcloud.storage import key
from gcloud.storage import bucket as MUT
from gcloud.storage.bucket import _KeyIterator
_saved = []

class _Key(object):
Expand All @@ -856,7 +854,7 @@ def grant_read(self):
def save_acl(self):
_saved.append((self._bucket, self._name, self._granted))

class _KeyIterator(key._KeyIterator):
class _Iterator(_KeyIterator):
def get_items_from_response(self, response):
for item in response.get('items', []):
yield _Key(self.bucket, item['name'])
Expand All @@ -868,8 +866,8 @@ def get_items_from_response(self, response):
connection = _Connection(after, {'items': [{'name': KEY}]})
bucket = self._makeOne(connection, NAME)
bucket.acl.loaded = True
with _Monkey(MUT, _KeyIterator=_KeyIterator):
bucket.make_public(recursive=True)
bucket._iterator_class = _Iterator
bucket.make_public(recursive=True)
self.assertEqual(list(bucket.acl), permissive)
self.assertEqual(list(bucket.default_object_acl), [])
self.assertEqual(_saved, [(bucket, KEY, True)])
Expand All @@ -884,6 +882,46 @@ def get_items_from_response(self, response):
self.assertEqual(kw[1]['query_params'], {})


class Test__KeyIterator(unittest2.TestCase):

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

def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)

def test_ctor(self):
connection = _Connection()
bucket = _Bucket(connection)
iterator = self._makeOne(bucket)
self.assertTrue(iterator.bucket is bucket)
self.assertTrue(iterator.connection is connection)
self.assertEqual(iterator.path, '%s/o' % bucket.path)
self.assertEqual(iterator.page_number, 0)
self.assertEqual(iterator.next_page_token, None)

def test_get_items_from_response_empty(self):
connection = _Connection()
bucket = _Bucket(connection)
iterator = self._makeOne(bucket)
self.assertEqual(list(iterator.get_items_from_response({})), [])

def test_get_items_from_response_non_empty(self):
from gcloud.storage.key import Key
KEY = 'key'
response = {'items': [{'name': KEY}]}
connection = _Connection()
bucket = _Bucket(connection)
iterator = self._makeOne(bucket)
keys = list(iterator.get_items_from_response(response))
self.assertEqual(len(keys), 1)
key = keys[0]
self.assertTrue(isinstance(key, Key))
self.assertTrue(key.connection is connection)
self.assertEqual(key.name, KEY)


class _Connection(object):
_delete_ok = False

Expand Down Expand Up @@ -911,6 +949,14 @@ def delete_bucket(self, bucket, force=False):
return True


class _Bucket(object):
path = '/b/name'
name = 'name'

def __init__(self, connection):
self.connection = connection


class MockFile(io.StringIO):
name = None

Expand Down
40 changes: 0 additions & 40 deletions gcloud/storage/test_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,46 +662,6 @@ def test_updated(self):
self.assertEqual(key.updated, UPDATED)


class Test__KeyIterator(unittest2.TestCase):

def _getTargetClass(self):
from gcloud.storage.key import _KeyIterator
return _KeyIterator

def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)

def test_ctor(self):
connection = _Connection()
bucket = _Bucket(connection)
iterator = self._makeOne(bucket)
self.assertTrue(iterator.bucket is bucket)
self.assertTrue(iterator.connection is connection)
self.assertEqual(iterator.path, '%s/o' % bucket.path)
self.assertEqual(iterator.page_number, 0)
self.assertEqual(iterator.next_page_token, None)

def test_get_items_from_response_empty(self):
connection = _Connection()
bucket = _Bucket(connection)
iterator = self._makeOne(bucket)
self.assertEqual(list(iterator.get_items_from_response({})), [])

def test_get_items_from_response_non_empty(self):
from gcloud.storage.key import Key
KEY = 'key'
response = {'items': [{'name': KEY}]}
connection = _Connection()
bucket = _Bucket(connection)
iterator = self._makeOne(bucket)
keys = list(iterator.get_items_from_response(response))
self.assertEqual(len(keys), 1)
key = keys[0]
self.assertTrue(isinstance(key, Key))
self.assertTrue(key.connection is connection)
self.assertEqual(key.name, KEY)


class Test__KeyDataIterator(unittest2.TestCase):

def _getTargetClass(self):
Expand Down

0 comments on commit 13b4e94

Please sign in to comment.