Skip to content

Commit 46d00d7

Browse files
authored
Merge pull request #2602 from dhermes/pubsub-iterators
Using Iterators for list_topics() in Pub/Sub.
2 parents cac3da4 + d3482d4 commit 46d00d7

3 files changed

Lines changed: 41 additions & 4 deletions

File tree

packages/google-cloud-core/google/cloud/_testing.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,12 @@ def __init__(self, items, page_token):
8181
self.page_token = page_token
8282

8383
def next(self):
84+
if self._items is None:
85+
raise StopIteration
8486
items, self._items = self._items, None
8587
return items
88+
89+
__next__ = next
90+
91+
def __iter__(self):
92+
return self

packages/google-cloud-core/google/cloud/iterator.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,14 @@ class Iterator(object):
202202
takes the :class:`Iterator` that started the page,
203203
the :class:`Page` that was started and the dictionary
204204
containing the page response.
205+
206+
:type page_iter: callable
207+
:param page_iter: (Optional) Callable to produce a pages iterator from the
208+
current iterator. Assumed signature takes the
209+
:class:`Iterator` that started the page. By default uses
210+
the HTTP pages iterator. Meant to provide a custom
211+
way to create pages (potentially with a custom
212+
transport such as gRPC).
205213
"""
206214

207215
_PAGE_TOKEN = 'pageToken'
@@ -211,7 +219,7 @@ class Iterator(object):
211219
def __init__(self, client, path, item_to_value,
212220
items_key=DEFAULT_ITEMS_KEY,
213221
page_token=None, max_results=None, extra_params=None,
214-
page_start=_do_nothing_page_start):
222+
page_start=_do_nothing_page_start, page_iter=None):
215223
self._started = False
216224
self.client = client
217225
self.path = path
@@ -220,8 +228,14 @@ def __init__(self, client, path, item_to_value,
220228
self.max_results = max_results
221229
self.extra_params = extra_params
222230
self._page_start = page_start
231+
self._page_iter = None
232+
# Verify inputs / provide defaults.
223233
if self.extra_params is None:
224234
self.extra_params = {}
235+
if page_iter is None:
236+
self._page_iter = self._default_page_iter()
237+
else:
238+
self._page_iter = page_iter(self)
225239
self._verify_params()
226240
# The attributes below will change over the life of the iterator.
227241
self.page_number = 0
@@ -239,7 +253,7 @@ def _verify_params(self):
239253
raise ValueError('Using a reserved parameter',
240254
reserved_in_use)
241255

242-
def _pages_iter(self):
256+
def _default_page_iter(self):
243257
"""Generator of pages of API responses.
244258
245259
Yields :class:`Page` instances.
@@ -263,11 +277,11 @@ def pages(self):
263277
if self._started:
264278
raise ValueError('Iterator has already started', self)
265279
self._started = True
266-
return self._pages_iter()
280+
return self._page_iter
267281

268282
def _items_iter(self):
269283
"""Iterator for each item returned."""
270-
for page in self._pages_iter():
284+
for page in self._page_iter:
271285
# Decrement the total results since the pages iterator adds
272286
# to it when each page is encountered.
273287
self.num_results -= page.num_items

packages/google-cloud-core/unit_tests/test_iterator.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,22 @@ def test_constructor_w_extra_param_collision(self):
128128
with self.assertRaises(ValueError):
129129
self._makeOne(client, path, None, extra_params=extra_params)
130130

131+
def test_constructor_non_default_page_iter(self):
132+
connection = _Connection()
133+
client = _Client(connection)
134+
path = '/foo'
135+
result = object()
136+
called = []
137+
138+
def page_iter(iterator):
139+
called.append(iterator)
140+
return result
141+
142+
iterator = self._makeOne(client, path, None,
143+
page_iter=page_iter)
144+
self.assertEqual(called, [iterator])
145+
self.assertIs(iterator._page_iter, result)
146+
131147
def test_pages_iter_empty_then_another(self):
132148
import six
133149
from google.cloud._testing import _Monkey

0 commit comments

Comments
 (0)