Skip to content

Commit 5197442

Browse files
committed
fix: remove skip from subsequent pages
1 parent 5cd552b commit 5197442

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

ibmcloudant/features/pagination.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ class _BasePageIterator(Iterator[Sequence[I]]):
263263
def __init__(self,
264264
client: CloudantV1,
265265
operation: Callable[..., DetailedResponse],
266-
page_opts: list[str],
266+
page_opts: Sequence[str],
267267
opts: dict):
268268
self._client: CloudantV1 = client
269269
self._has_next: bool = True
@@ -318,7 +318,7 @@ def _get_next_page_options(self, result: R) -> dict:
318318
class _KeyPageIterator(_BasePageIterator, Generic[K]):
319319

320320
def __init__(self, client: CloudantV1, operation: Callable[..., DetailedResponse], opts: dict):
321-
super().__init__(client, operation, ['start_key', 'start_key_doc_id'], opts)
321+
super().__init__(client, operation, ('skip', 'start_key', 'start_key_doc_id',), opts)
322322
self._boundary_failure: Optional[str] = None
323323

324324
def _next_request(self) -> list[I]:
@@ -353,8 +353,8 @@ def check_boundary(self, penultimate_item: I, last_item: I) -> Optional[str]:
353353

354354
class _BookmarkPageIterator(_BasePageIterator):
355355

356-
def __init__(self, client: CloudantV1, operation: Callable[..., DetailedResponse], opts: dict):
357-
super().__init__(client, operation, ['bookmark'], opts)
356+
def __init__(self, client: CloudantV1, operation: Callable[..., DetailedResponse], opts: dict, extra_page_opts:Sequence[str]=()):
357+
super().__init__(client, operation, ('bookmark',) + extra_page_opts, opts)
358358

359359
def _get_next_page_options(self, result: R) -> dict:
360360
return {'bookmark': result.bookmark}
@@ -391,6 +391,12 @@ def __init__(self, client: CloudantV1, opts: dict):
391391

392392
class _FindBasePageIterator(_BookmarkPageIterator):
393393

394+
def __init__(self, client: CloudantV1, operation: Callable[..., DetailedResponse], opts: dict):
395+
# Find requests allow skip, but it should only be used on the first request.
396+
# Since we don't want it on subsequent page requests we need to exclude it from
397+
# fixed opts used for the partial function.
398+
super().__init__(client, operation, opts, extra_page_opts=('skip',))
399+
394400
def _items(self, result: FindResult):
395401
return result.docs
396402

test/unit/features/test_pagination_operations.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,17 @@ def test_rows_errors(self):
191191
for row in Pagination.new_pagination(self.client, pager_type, limit=page_size).rows():
192192
actual_item_count += 1
193193
self.assertEqual(actual_item_count, expected_item_count, 'Should have got the correct number of items before error.')
194+
195+
# Test skip omitted from subsequent page requests
196+
# Applies to key pagers and find pagers
197+
def test_skip_removed_for_subsquent_page(self):
198+
page_size = 14
199+
for pager_type in (PaginationMockSupport.key_pagers + PaginationMockSupport.find_pagers):
200+
with self.subTest(pager_type):
201+
with patch(PaginationMockSupport.operation_map[pager_type], PaginationMockResponse(2*page_size, page_size, pager_type).get_next_page):
202+
pager = Pagination.new_pagination(self.client, pager_type, limit=page_size, skip=1).pager()
203+
# Assert first page has skip option
204+
self.assertEqual(pager._iterator._next_page_opts['skip'], 1, 'The skip option should be 1 for the first page')
205+
pager.get_next()
206+
# Assert second page has no skip option
207+
self.assertIsNone(pager._iterator._next_page_opts.get('skip'), 'The skip option should be absent for the next page')

0 commit comments

Comments
 (0)