diff --git a/gitlab/__init__.py b/gitlab/__init__.py index b5f32c931..738085abd 100644 --- a/gitlab/__init__.py +++ b/gitlab/__init__.py @@ -642,8 +642,22 @@ def sanitized_url(url): return parsed._replace(path=new_path).geturl() url = self._build_url(path) - params = query_data.copy() - params.update(kwargs) + + def copy_dict(dest, src): + for k, v in src.items(): + if isinstance(v, dict): + # Transform dict values in new attributes. For example: + # custom_attributes: {'foo', 'bar'} => + # custom_attributes['foo']: 'bar' + for dict_k, dict_v in v.items(): + dest['%s[%s]' % (k, dict_k)] = dict_v + else: + dest[k] = v + + params = {} + copy_dict(params, query_data) + copy_dict(params, kwargs) + opts = self._get_session_opts(content_type='application/json') # don't set the content-type header when uploading files diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py index 106b10285..d7bb3d590 100644 --- a/gitlab/v4/objects.py +++ b/gitlab/v4/objects.py @@ -253,7 +253,7 @@ class UserManager(CRUDMixin, RESTManager): _obj_cls = User _list_filters = ('active', 'blocked', 'username', 'extern_uid', 'provider', - 'external', 'search') + 'external', 'search', 'custom_attributes') _create_attrs = ( tuple(), ('email', 'username', 'name', 'password', 'reset_password', 'skype', @@ -656,7 +656,7 @@ class GroupManager(CRUDMixin, RESTManager): _path = '/groups' _obj_cls = Group _list_filters = ('skip_groups', 'all_available', 'search', 'order_by', - 'sort', 'statistics', 'owned') + 'sort', 'statistics', 'owned', 'custom_attributes') _create_attrs = ( ('name', 'path'), ('description', 'visibility', 'parent_id', 'lfs_enabled', @@ -2639,7 +2639,8 @@ class ProjectManager(CRUDMixin, RESTManager): ) _list_filters = ('search', 'owned', 'starred', 'archived', 'visibility', 'order_by', 'sort', 'simple', 'membership', 'statistics', - 'with_issues_enabled', 'with_merge_requests_enabled') + 'with_issues_enabled', 'with_merge_requests_enabled', + 'custom_attributes') class Runner(SaveMixin, ObjectDeleteMixin, RESTObject): diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py index 4af9ea969..e06502018 100644 --- a/tools/python_test_v4.py +++ b/tools/python_test_v4.py @@ -129,6 +129,7 @@ attrs = new_user.customattributes.list() assert(len(attrs) == 0) attr = new_user.customattributes.set('key', 'value1') +assert(len(gl.users.list(custom_attributes={'key': 'value1'})) == 1) assert(attr.key == 'key') assert(attr.value == 'value1') assert(len(new_user.customattributes.list()) == 1) @@ -234,6 +235,7 @@ attrs = group2.customattributes.list() assert(len(attrs) == 0) attr = group2.customattributes.set('key', 'value1') +assert(len(gl.groups.list(custom_attributes={'key': 'value1'})) == 1) assert(attr.key == 'key') assert(attr.value == 'value1') assert(len(group2.customattributes.list()) == 1) @@ -303,6 +305,7 @@ attrs = admin_project.customattributes.list() assert(len(attrs) == 0) attr = admin_project.customattributes.set('key', 'value1') +assert(len(gl.projects.list(custom_attributes={'key': 'value1'})) == 1) assert(attr.key == 'key') assert(attr.value == 'value1') assert(len(admin_project.customattributes.list()) == 1)