diff --git a/setup.py b/setup.py index 0fc5180..589c93e 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ def read(*names, **kwargs): setup( name='octokitpy', - version='0.11.0', + version='0.11.1', license='MIT license', description='Python client for GitHub API', long_description='%s\n%s' % ( diff --git a/src/octokit/__init__.py b/src/octokit/__init__.py index 4eb56f5..d38a054 100644 --- a/src/octokit/__init__.py +++ b/src/octokit/__init__.py @@ -11,7 +11,7 @@ from octokit import errors from octokit import utils from routes import specifications -page_regex = re.compile(r'[\?\&]page=(\d+)[_&=\w\d]*>; rel="(\w+)"') +page_regex = re.compile(r'[\?\&]page=(\d+)[_&=%+\w\d]*>; rel="(\w+)"') class Base(object): @@ -250,6 +250,7 @@ class Octokit(Base): def paginate(self, obj, page=1, **kwargs): response = self.set_pages(obj(page=page, **kwargs)) yield response.json - while not response.is_last_page: - response = self.set_pages(obj(page=response.next_page, **kwargs), response.next_page) - yield response.json + if hasattr(response, 'is_last_page'): + while not response.is_last_page: + response = self.set_pages(obj(page=response.next_page, **kwargs), response.next_page) + yield response.json diff --git a/tests/test_octokit.py b/tests/test_octokit.py index a629370..d0784d2 100644 --- a/tests/test_octokit.py +++ b/tests/test_octokit.py @@ -1,23 +1,28 @@ +import pytest + + class MockHeaders(object): - def __init__(self, requested_page): - Link = 'Links ; rel="next", ; rel="last"'.format( # noqa E501 + def __init__(self, requested_page, **kwargs): + link = 'Links ; rel="next", ; rel="last"'.format( # noqa E501 min(requested_page + 1, 4) ) - self.headers = {'Link': Link} + self.headers = {'Link': kwargs.get('link', link)} class MockObject(object): def __init__(self, page, kwargs): - self._response = MockHeaders(page) + self._response = MockHeaders(page, **kwargs) self.json = {'page': page, 'kwargs': kwargs} - # self.is_last_page = True if page == 4 else False - # self.next_page = min(page + 1, 4) if page else 2 def MockResponse(page=None, **kwargs): - print('mr', page, kwargs) + return MockObject(page, kwargs) + + +def MockResponseWithoutLinks(page=None, **kwargs): + kwargs['link'] = '' return MockObject(page, kwargs) @@ -48,6 +53,14 @@ class TestOctokit(object): assert next(p) == {'page': 3, 'kwargs': {'param': 'value'}} assert next(p) == {'page': 4, 'kwargs': {'param': 'value'}} + def test_pagination_does_break_when_iterating_over_a_single_page(self): + from octokit import Octokit + sut_obj = MockResponseWithoutLinks + p = Octokit().paginate(sut_obj, param='value') + assert next(p) == {'page': 1, 'kwargs': {'param': 'value', 'link': ''}} + with pytest.raises(StopIteration): + assert next(p) + def test_can_speficy_the_route_specifications_used(self): from octokit import Octokit octokit = Octokit(routes='ghe-2.15')