Skip to content

make as_list=False work for all=True queries #514

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions gitlab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,7 @@ def http_list(self, path, query_data={}, as_list=None, **kwargs):

Returns:
list: A list of the objects returned by the server. If `as_list` is
False and no pagination-related arguments (`page`, `per_page`,
`all`) are defined then a GitlabList object (generator) is returned
False then a GitlabList object (generator) is returned
instead. This object will make API calls when needed to fetch the
next items from the server.

Expand All @@ -517,21 +516,16 @@ def http_list(self, path, query_data={}, as_list=None, **kwargs):
"""

# In case we want to change the default behavior at some point
as_list = True if as_list is None else as_list
as_list = as_list is None or as_list

get_all = kwargs.get('all', False)
url = self._build_url(path)

if get_all is True:
return list(GitlabList(self, url, query_data, **kwargs))

if 'page' in kwargs or as_list is True:
# pagination requested, we return a list
return list(GitlabList(self, url, query_data, get_next=False,
**kwargs))

# No pagination, generator requested
return GitlabList(self, url, query_data, **kwargs)
glist = GitlabList(self, url, query_data,
get_next='page' not in kwargs and get_all, **kwargs)
if as_list:
glist = list(glist)
return glist

def http_post(self, path, query_data={}, post_data={}, files=None,
**kwargs):
Expand Down
67 changes: 60 additions & 7 deletions gitlab/tests/test_gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

from httmock import HTTMock # noqa
from httmock import response # noqa
from httmock import urlmatch # noqa
from httmock import remember_called, urlmatch # noqa
import requests

import gitlab
Expand Down Expand Up @@ -57,6 +57,7 @@ def setUp(self):
def test_build_list(self):
@urlmatch(scheme='http', netloc="localhost", path="/api/v4/tests",
method="get")
@remember_called
def resp_1(url, request):
headers = {'content-type': 'application/json',
'X-Page': 1,
Expand All @@ -72,6 +73,7 @@ def resp_1(url, request):

@urlmatch(scheme='http', netloc="localhost", path="/api/v4/tests",
method='get', query=r'.*page=2')
@remember_called
def resp_2(url, request):
headers = {'content-type': 'application/json',
'X-Page': 2,
Expand All @@ -82,7 +84,7 @@ def resp_2(url, request):
content = '[{"c": "d"}]'
return response(200, content, headers, None, 5, request)

with HTTMock(resp_1):
with HTTMock(resp_2, resp_1):
obj = self.gl.http_list('/tests', as_list=False)
self.assertEqual(len(obj), 2)
self.assertEqual(obj._next_url,
Expand All @@ -94,11 +96,62 @@ def resp_2(url, request):
self.assertEqual(obj.total_pages, 2)
self.assertEqual(obj.total, 2)

with HTTMock(resp_2):
l = list(obj)
self.assertEqual(len(l), 2)
self.assertEqual(l[0]['a'], 'b')
self.assertEqual(l[1]['c'], 'd')
l = list(obj)
self.assertListEqual(l, [{"a": "b"}])
self.assertEqual(resp_1.call['count'], 1)
self.assertFalse(resp_2.call['called'])

def test_build_list_all(self):
@urlmatch(scheme='http', netloc="localhost", path="/api/v4/tests",
method="get")
@remember_called
def resp_1(url, request):
headers = {'content-type': 'application/json',
'X-Page': 1,
'X-Next-Page': 2,
'X-Per-Page': 1,
'X-Total-Pages': 2,
'X-Total': 2,
'Link': (
'<http://localhost/api/v4/tests?per_page=1&page=2>;'
' rel="next"')}
content = '[{"a": "b"}]'
return response(200, content, headers, None, 5, request)

@urlmatch(scheme='http', netloc="localhost", path="/api/v4/tests",
method='get', query=r'.*page=2')
@remember_called
def resp_2(url, request):
headers = {'content-type': 'application/json',
'X-Page': 2,
'X-Next-Page': 2,
'X-Per-Page': 1,
'X-Total-Pages': 2,
'X-Total': 2}
content = '[{"c": "d"}]'
return response(200, content, headers, None, 5, request)

with HTTMock(resp_2, resp_1):
obj = self.gl.http_list('/tests', as_list=False, all=True)
self.assertEqual(len(obj), 2)
self.assertEqual(obj._next_url,
'http://localhost/api/v4/tests?per_page=1&page=2')
self.assertEqual(obj.current_page, 1)
self.assertEqual(obj.prev_page, None)
self.assertEqual(obj.next_page, 2)
self.assertEqual(obj.per_page, 1)
self.assertEqual(obj.total_pages, 2)
self.assertEqual(obj.total, 2)
self.assertEqual(resp_1.call['count'], 1)
self.assertFalse(resp_2.call['called'])
self.assertDictEqual(next(obj), {"a": "b"})
self.assertEqual(resp_1.call['count'], 1)
self.assertFalse(resp_2.call['called'])
self.assertDictEqual(next(obj), {"c": "d"})
self.assertEqual(resp_1.call['count'], 1)
self.assertEqual(resp_2.call['count'], 1)
with self.assertRaises(StopIteration):
next(obj)


class TestGitlabHttpMethods(unittest.TestCase):
Expand Down