Skip to content

Commit 211a3e6

Browse files
committed
Resolving cyclic imports in storage package.
This is accomplished by moving the definitions of BucketIterator and KeyIterator into their respective modules (i.e. storage.bucket and storage.key). This is not so big an issue because the parent class iterator.Iterator does most of the work and the children only require a small tweak.
1 parent 628c430 commit 211a3e6

File tree

7 files changed

+132
-134
lines changed

7 files changed

+132
-134
lines changed

gcloud/storage/bucket.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
from gcloud.storage import exceptions
66
from gcloud.storage.acl import BucketACL
77
from gcloud.storage.acl import DefaultObjectACL
8-
from gcloud.storage.iterator import KeyIterator
8+
from gcloud.storage.iterator import Iterator
99
from gcloud.storage.key import Key
10+
from gcloud.storage.key import KeyIterator
1011

1112

1213
class Bucket(object):
@@ -637,3 +638,27 @@ def make_public(self, recursive=False, future=False):
637638
for key in self:
638639
key.get_acl().all().grant_read()
639640
key.save_acl()
641+
642+
643+
class BucketIterator(Iterator):
644+
"""An iterator listing all buckets.
645+
646+
You shouldn't have to use this directly,
647+
but instead should use the helper methods
648+
on :class:`gcloud.storage.connection.Connection` objects.
649+
650+
:type connection: :class:`gcloud.storage.connection.Connection`
651+
:param connection: The connection to use for querying the list of buckets.
652+
"""
653+
654+
def __init__(self, connection):
655+
super(BucketIterator, self).__init__(connection=connection, path='/b')
656+
657+
def get_items_from_response(self, response):
658+
"""Factory method which yields :class:`.Bucket` items from a response.
659+
660+
:type response: dict
661+
:param response: The JSON API response for a page of buckets.
662+
"""
663+
for item in response.get('items', []):
664+
yield Bucket.from_dict(item, connection=self.connection)

gcloud/storage/connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from gcloud import connection
1616
from gcloud.storage import exceptions
1717
from gcloud.storage.bucket import Bucket
18-
from gcloud.storage.iterator import BucketIterator
18+
from gcloud.storage.bucket import BucketIterator
1919

2020

2121
def _utcnow(): # pragma: NO COVER testing replaces

gcloud/storage/iterator.py

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -134,60 +134,6 @@ def get_items_from_response(self, response):
134134
raise NotImplementedError
135135

136136

137-
class BucketIterator(Iterator):
138-
"""An iterator listing all buckets.
139-
140-
You shouldn't have to use this directly,
141-
but instead should use the helper methods
142-
on :class:`gcloud.storage.connection.Connection` objects.
143-
144-
:type connection: :class:`gcloud.storage.connection.Connection`
145-
:param connection: The connection to use for querying the list of buckets.
146-
"""
147-
148-
def __init__(self, connection):
149-
super(BucketIterator, self).__init__(connection=connection, path='/b')
150-
151-
def get_items_from_response(self, response):
152-
"""Factory method which yields :class:`.Bucket` items from a response.
153-
154-
:type response: dict
155-
:param response: The JSON API response for a page of buckets.
156-
"""
157-
158-
from gcloud.storage.bucket import Bucket
159-
for item in response.get('items', []):
160-
yield Bucket.from_dict(item, connection=self.connection)
161-
162-
163-
class KeyIterator(Iterator):
164-
"""An iterator listing keys.
165-
166-
You shouldn't have to use this directly,
167-
but instead should use the helper methods
168-
on :class:`gcloud.storage.key.Key` objects.
169-
170-
:type bucket: :class:`gcloud.storage.bucket.Bucket`
171-
:param bucket: The bucket from which to list keys.
172-
"""
173-
174-
def __init__(self, bucket):
175-
self.bucket = bucket
176-
super(KeyIterator, self).__init__(
177-
connection=bucket.connection, path=bucket.path + '/o')
178-
179-
def get_items_from_response(self, response):
180-
"""Factory method, yields :class:`.storage.key.Key` items from response.
181-
182-
:type response: dict
183-
:param response: The JSON API response for a page of keys.
184-
"""
185-
186-
from gcloud.storage.key import Key
187-
for item in response.get('items', []):
188-
yield Key.from_dict(item, bucket=self.bucket)
189-
190-
191137
class KeyDataIterator(object):
192138
"""An iterator listing data stored in a key.
193139

gcloud/storage/key.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from StringIO import StringIO
66

77
from gcloud.storage.acl import ObjectACL
8+
from gcloud.storage.iterator import Iterator
89
from gcloud.storage.iterator import KeyDataIterator
910

1011

@@ -459,3 +460,29 @@ def make_public(self):
459460
self.get_acl().all().grant_read()
460461
self.save_acl()
461462
return self
463+
464+
465+
class KeyIterator(Iterator):
466+
"""An iterator listing keys.
467+
468+
You shouldn't have to use this directly,
469+
but instead should use the helper methods
470+
on :class:`gcloud.storage.key.Key` objects.
471+
472+
:type bucket: :class:`gcloud.storage.bucket.Bucket`
473+
:param bucket: The bucket from which to list keys.
474+
"""
475+
476+
def __init__(self, bucket):
477+
self.bucket = bucket
478+
super(KeyIterator, self).__init__(
479+
connection=bucket.connection, path=bucket.path + '/o')
480+
481+
def get_items_from_response(self, response):
482+
"""Factory method, yields :class:`.storage.key.Key` items from response.
483+
484+
:type response: dict
485+
:param response: The JSON API response for a page of keys.
486+
"""
487+
for item in response.get('items', []):
488+
yield Key.from_dict(item, bucket=self.bucket)

gcloud/storage/test_bucket.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ def test_make_public_w_future(self):
840840
def test_make_public_recursive(self):
841841
from gcloud.storage.acl import _ACLEntity
842842
from gcloud._testing import _Monkey
843-
from gcloud.storage import iterator
843+
from gcloud.storage import key
844844
from gcloud.storage import bucket as MUT
845845
_saved = []
846846

@@ -863,7 +863,7 @@ def grant_read(self):
863863
def save_acl(self):
864864
_saved.append((self._bucket, self._name, self._granted))
865865

866-
class _KeyIterator(iterator.KeyIterator):
866+
class _KeyIterator(key.KeyIterator):
867867
def get_items_from_response(self, response):
868868
for item in response.get('items', []):
869869
yield _Key(self.bucket, item['name'])
@@ -892,6 +892,42 @@ def get_items_from_response(self, response):
892892
self.assertEqual(kw[1]['query_params'], None)
893893

894894

895+
class TestBucketIterator(unittest2.TestCase):
896+
897+
def _getTargetClass(self):
898+
from gcloud.storage.bucket import BucketIterator
899+
return BucketIterator
900+
901+
def _makeOne(self, *args, **kw):
902+
return self._getTargetClass()(*args, **kw)
903+
904+
def test_ctor(self):
905+
connection = _Connection()
906+
iterator = self._makeOne(connection)
907+
self.assertTrue(iterator.connection is connection)
908+
self.assertEqual(iterator.path, '/b')
909+
self.assertEqual(iterator.page_number, 0)
910+
self.assertEqual(iterator.next_page_token, None)
911+
912+
def test_get_items_from_response_empty(self):
913+
connection = _Connection()
914+
iterator = self._makeOne(connection)
915+
self.assertEqual(list(iterator.get_items_from_response({})), [])
916+
917+
def test_get_items_from_response_non_empty(self):
918+
from gcloud.storage.bucket import Bucket
919+
KEY = 'key'
920+
response = {'items': [{'name': KEY}]}
921+
connection = _Connection()
922+
iterator = self._makeOne(connection)
923+
buckets = list(iterator.get_items_from_response(response))
924+
self.assertEqual(len(buckets), 1)
925+
bucket = buckets[0]
926+
self.assertTrue(isinstance(bucket, Bucket))
927+
self.assertTrue(bucket.connection is connection)
928+
self.assertEqual(bucket.name, KEY)
929+
930+
895931
class _Connection(object):
896932
_delete_ok = False
897933

gcloud/storage/test_iterator.py

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -118,82 +118,6 @@ def test_get_items_from_response_raises_NotImplementedError(self):
118118
iterator.get_items_from_response, object())
119119

120120

121-
class TestBucketIterator(unittest2.TestCase):
122-
123-
def _getTargetClass(self):
124-
from gcloud.storage.iterator import BucketIterator
125-
return BucketIterator
126-
127-
def _makeOne(self, *args, **kw):
128-
return self._getTargetClass()(*args, **kw)
129-
130-
def test_ctor(self):
131-
connection = _Connection()
132-
iterator = self._makeOne(connection)
133-
self.assertTrue(iterator.connection is connection)
134-
self.assertEqual(iterator.path, '/b')
135-
self.assertEqual(iterator.page_number, 0)
136-
self.assertEqual(iterator.next_page_token, None)
137-
138-
def test_get_items_from_response_empty(self):
139-
connection = _Connection()
140-
iterator = self._makeOne(connection)
141-
self.assertEqual(list(iterator.get_items_from_response({})), [])
142-
143-
def test_get_items_from_response_non_empty(self):
144-
from gcloud.storage.bucket import Bucket
145-
KEY = 'key'
146-
response = {'items': [{'name': KEY}]}
147-
connection = _Connection()
148-
iterator = self._makeOne(connection)
149-
buckets = list(iterator.get_items_from_response(response))
150-
self.assertEqual(len(buckets), 1)
151-
bucket = buckets[0]
152-
self.assertTrue(isinstance(bucket, Bucket))
153-
self.assertTrue(bucket.connection is connection)
154-
self.assertEqual(bucket.name, KEY)
155-
156-
157-
class TestKeyIterator(unittest2.TestCase):
158-
159-
def _getTargetClass(self):
160-
from gcloud.storage.iterator import KeyIterator
161-
return KeyIterator
162-
163-
def _makeOne(self, *args, **kw):
164-
return self._getTargetClass()(*args, **kw)
165-
166-
def test_ctor(self):
167-
connection = _Connection()
168-
bucket = _Bucket(connection)
169-
iterator = self._makeOne(bucket)
170-
self.assertTrue(iterator.bucket is bucket)
171-
self.assertTrue(iterator.connection is connection)
172-
self.assertEqual(iterator.path, '%s/o' % bucket.path)
173-
self.assertEqual(iterator.page_number, 0)
174-
self.assertEqual(iterator.next_page_token, None)
175-
176-
def test_get_items_from_response_empty(self):
177-
connection = _Connection()
178-
bucket = _Bucket(connection)
179-
iterator = self._makeOne(bucket)
180-
self.assertEqual(list(iterator.get_items_from_response({})), [])
181-
182-
def test_get_items_from_response_non_empty(self):
183-
from gcloud.storage.key import Key
184-
KEY = 'key'
185-
response = {'items': [{'name': KEY}]}
186-
connection = _Connection()
187-
bucket = _Bucket(connection)
188-
iterator = self._makeOne(bucket)
189-
keys = list(iterator.get_items_from_response(response))
190-
self.assertEqual(len(keys), 1)
191-
key = keys[0]
192-
self.assertTrue(isinstance(key, Key))
193-
self.assertTrue(key.connection is connection)
194-
self.assertEqual(key.name, KEY)
195-
196-
197121
class TestKeyDataIterator(unittest2.TestCase):
198122

199123
def _getTargetClass(self):

gcloud/storage/test_key.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,46 @@ def test_make_public(self):
591591
self.assertEqual(kw[0]['query_params'], {'projection': 'full'})
592592

593593

594+
class TestKeyIterator(unittest2.TestCase):
595+
596+
def _getTargetClass(self):
597+
from gcloud.storage.key import KeyIterator
598+
return KeyIterator
599+
600+
def _makeOne(self, *args, **kw):
601+
return self._getTargetClass()(*args, **kw)
602+
603+
def test_ctor(self):
604+
connection = _Connection()
605+
bucket = _Bucket(connection)
606+
iterator = self._makeOne(bucket)
607+
self.assertTrue(iterator.bucket is bucket)
608+
self.assertTrue(iterator.connection is connection)
609+
self.assertEqual(iterator.path, '%s/o' % bucket.path)
610+
self.assertEqual(iterator.page_number, 0)
611+
self.assertEqual(iterator.next_page_token, None)
612+
613+
def test_get_items_from_response_empty(self):
614+
connection = _Connection()
615+
bucket = _Bucket(connection)
616+
iterator = self._makeOne(bucket)
617+
self.assertEqual(list(iterator.get_items_from_response({})), [])
618+
619+
def test_get_items_from_response_non_empty(self):
620+
from gcloud.storage.key import Key
621+
KEY = 'key'
622+
response = {'items': [{'name': KEY}]}
623+
connection = _Connection()
624+
bucket = _Bucket(connection)
625+
iterator = self._makeOne(bucket)
626+
keys = list(iterator.get_items_from_response(response))
627+
self.assertEqual(len(keys), 1)
628+
key = keys[0]
629+
self.assertTrue(isinstance(key, Key))
630+
self.assertTrue(key.connection is connection)
631+
self.assertEqual(key.name, KEY)
632+
633+
594634
class _Connection(object):
595635
API_BASE_URL = 'http://example.com'
596636

0 commit comments

Comments
 (0)