Skip to content

Commit a57334f

Browse files
chore: create new ArrayAttribute class
Create a new ArrayAttribute class. This is to indicate types which are sent to the GitLab server as arrays https://docs.gitlab.com/ee/api/#array At this stage it is identical to the CommaSeparatedListAttribute class but will be used later to support the array types sent to GitLab. This is the second step in a series of steps of our goal to add full support for the GitLab API data types[1]: * array * hash * array of hashes Step one was: commit 5127b15 [1] https://docs.gitlab.com/ee/api/#encoding-api-parameters-of-array-and-hash-types Related: #1698
1 parent 7a13b9b commit a57334f

File tree

10 files changed

+68
-49
lines changed

10 files changed

+68
-49
lines changed

gitlab/types.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ def get_for_api(self) -> Any:
3232
return self._value
3333

3434

35-
class CommaSeparatedListAttribute(GitlabAttribute):
35+
class _ListArrayAttribute(GitlabAttribute):
36+
"""Helper class to support `list` / `array` types."""
37+
3638
def set_from_cli(self, cli_value: str) -> None:
3739
if not cli_value.strip():
3840
self._value = []
@@ -49,6 +51,17 @@ def get_for_api(self) -> str:
4951
return ",".join([str(x) for x in self._value])
5052

5153

54+
class ArrayAttribute(_ListArrayAttribute):
55+
"""To support `array` types as documented in
56+
https://docs.gitlab.com/ee/api/#array"""
57+
58+
59+
class CommaSeparatedListAttribute(_ListArrayAttribute):
60+
"""For values which are sent to the server as a Comma Separated Values
61+
(CSV) string. We allow them to be specified as a list and we convert it
62+
into a CSV"""
63+
64+
5265
class LowercaseStringAttribute(GitlabAttribute):
5366
def get_for_api(self) -> str:
5467
return str(self._value).lower()

gitlab/v4/objects/groups.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,7 @@ class GroupManager(CRUDMixin, RESTManager):
314314
"shared_runners_setting",
315315
),
316316
)
317-
_types = {
318-
"avatar": types.ImageAttribute,
319-
"skip_groups": types.CommaSeparatedListAttribute,
320-
}
317+
_types = {"avatar": types.ImageAttribute, "skip_groups": types.ArrayAttribute}
321318

322319
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Group:
323320
return cast(Group, super().get(id=id, lazy=lazy, **kwargs))
@@ -377,7 +374,7 @@ class GroupSubgroupManager(ListMixin, RESTManager):
377374
"with_custom_attributes",
378375
"min_access_level",
379376
)
380-
_types = {"skip_groups": types.CommaSeparatedListAttribute}
377+
_types = {"skip_groups": types.ArrayAttribute}
381378

382379

383380
class GroupDescendantGroup(RESTObject):

gitlab/v4/objects/issues.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,7 @@ class IssueManager(RetrieveMixin, RESTManager):
6565
"updated_after",
6666
"updated_before",
6767
)
68-
_types = {
69-
"iids": types.CommaSeparatedListAttribute,
70-
"labels": types.CommaSeparatedListAttribute,
71-
}
68+
_types = {"iids": types.ArrayAttribute, "labels": types.CommaSeparatedListAttribute}
7269

7370
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Issue:
7471
return cast(Issue, super().get(id=id, lazy=lazy, **kwargs))
@@ -98,10 +95,7 @@ class GroupIssueManager(ListMixin, RESTManager):
9895
"updated_after",
9996
"updated_before",
10097
)
101-
_types = {
102-
"iids": types.CommaSeparatedListAttribute,
103-
"labels": types.CommaSeparatedListAttribute,
104-
}
98+
_types = {"iids": types.ArrayAttribute, "labels": types.CommaSeparatedListAttribute}
10599

106100

107101
class ProjectIssue(
@@ -239,10 +233,7 @@ class ProjectIssueManager(CRUDMixin, RESTManager):
239233
"discussion_locked",
240234
),
241235
)
242-
_types = {
243-
"iids": types.CommaSeparatedListAttribute,
244-
"labels": types.CommaSeparatedListAttribute,
245-
}
236+
_types = {"iids": types.ArrayAttribute, "labels": types.CommaSeparatedListAttribute}
246237

247238
def get(
248239
self, id: Union[str, int], lazy: bool = False, **kwargs: Any

gitlab/v4/objects/members.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class GroupMemberManager(CRUDMixin, RESTManager):
4141
_update_attrs = RequiredOptional(
4242
required=("access_level",), optional=("expires_at",)
4343
)
44-
_types = {"user_ids": types.CommaSeparatedListAttribute}
44+
_types = {"user_ids": types.ArrayAttribute}
4545

4646
def get(
4747
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
@@ -101,7 +101,7 @@ class ProjectMemberManager(CRUDMixin, RESTManager):
101101
_update_attrs = RequiredOptional(
102102
required=("access_level",), optional=("expires_at",)
103103
)
104-
_types = {"user_ids": types.CommaSeparatedListAttribute}
104+
_types = {"user_ids": types.ArrayAttribute}
105105

106106
def get(
107107
self, id: Union[str, int], lazy: bool = False, **kwargs: Any

gitlab/v4/objects/merge_requests.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ class MergeRequestManager(ListMixin, RESTManager):
9595
"deployed_after",
9696
)
9797
_types = {
98-
"approver_ids": types.CommaSeparatedListAttribute,
99-
"approved_by_ids": types.CommaSeparatedListAttribute,
98+
"approver_ids": types.ArrayAttribute,
99+
"approved_by_ids": types.ArrayAttribute,
100100
"in": types.CommaSeparatedListAttribute,
101101
"labels": types.CommaSeparatedListAttribute,
102102
}
@@ -133,8 +133,8 @@ class GroupMergeRequestManager(ListMixin, RESTManager):
133133
"wip",
134134
)
135135
_types = {
136-
"approver_ids": types.CommaSeparatedListAttribute,
137-
"approved_by_ids": types.CommaSeparatedListAttribute,
136+
"approver_ids": types.ArrayAttribute,
137+
"approved_by_ids": types.ArrayAttribute,
138138
"labels": types.CommaSeparatedListAttribute,
139139
}
140140

@@ -455,9 +455,9 @@ class ProjectMergeRequestManager(CRUDMixin, RESTManager):
455455
"wip",
456456
)
457457
_types = {
458-
"approver_ids": types.CommaSeparatedListAttribute,
459-
"approved_by_ids": types.CommaSeparatedListAttribute,
460-
"iids": types.CommaSeparatedListAttribute,
458+
"approver_ids": types.ArrayAttribute,
459+
"approved_by_ids": types.ArrayAttribute,
460+
"iids": types.ArrayAttribute,
461461
"labels": types.CommaSeparatedListAttribute,
462462
}
463463

gitlab/v4/objects/milestones.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class GroupMilestoneManager(CRUDMixin, RESTManager):
9393
optional=("title", "description", "due_date", "start_date", "state_event"),
9494
)
9595
_list_filters = ("iids", "state", "search")
96-
_types = {"iids": types.CommaSeparatedListAttribute}
96+
_types = {"iids": types.ArrayAttribute}
9797

9898
def get(
9999
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
@@ -177,7 +177,7 @@ class ProjectMilestoneManager(CRUDMixin, RESTManager):
177177
optional=("title", "description", "due_date", "start_date", "state_event"),
178178
)
179179
_list_filters = ("iids", "state", "search")
180-
_types = {"iids": types.CommaSeparatedListAttribute}
180+
_types = {"iids": types.ArrayAttribute}
181181

182182
def get(
183183
self, id: Union[str, int], lazy: bool = False, **kwargs: Any

gitlab/v4/objects/projects.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class ProjectGroupManager(ListMixin, RESTManager):
125125
"shared_min_access_level",
126126
"shared_visible_only",
127127
)
128-
_types = {"skip_groups": types.CommaSeparatedListAttribute}
128+
_types = {"skip_groups": types.ArrayAttribute}
129129

130130

131131
class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTObject):

gitlab/v4/objects/settings.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ class ApplicationSettingsManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
8080
),
8181
)
8282
_types = {
83-
"asset_proxy_allowlist": types.CommaSeparatedListAttribute,
84-
"disabled_oauth_sign_in_sources": types.CommaSeparatedListAttribute,
85-
"domain_allowlist": types.CommaSeparatedListAttribute,
86-
"domain_denylist": types.CommaSeparatedListAttribute,
87-
"import_sources": types.CommaSeparatedListAttribute,
88-
"restricted_visibility_levels": types.CommaSeparatedListAttribute,
83+
"asset_proxy_allowlist": types.ArrayAttribute,
84+
"disabled_oauth_sign_in_sources": types.ArrayAttribute,
85+
"domain_allowlist": types.ArrayAttribute,
86+
"domain_denylist": types.ArrayAttribute,
87+
"import_sources": types.ArrayAttribute,
88+
"restricted_visibility_levels": types.ArrayAttribute,
8989
}
9090

9191
@exc.on_http_error(exc.GitlabUpdateError)

gitlab/v4/objects/users.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ class ProjectUserManager(ListMixin, RESTManager):
369369
_obj_cls = ProjectUser
370370
_from_parent_attrs = {"project_id": "id"}
371371
_list_filters = ("search", "skip_users")
372-
_types = {"skip_users": types.CommaSeparatedListAttribute}
372+
_types = {"skip_users": types.ArrayAttribute}
373373

374374

375375
class UserEmail(ObjectDeleteMixin, RESTObject):

tests/unit/test_types.py

+30-12
Original file line numberDiff line numberDiff line change
@@ -30,45 +30,63 @@ def test_gitlab_attribute_get():
3030
assert o._value is None
3131

3232

33-
def test_csv_list_attribute_input():
34-
o = types.CommaSeparatedListAttribute()
33+
def test_array_attribute_input():
34+
o = types.ArrayAttribute()
3535
o.set_from_cli("foo,bar,baz")
3636
assert o.get() == ["foo", "bar", "baz"]
3737

3838
o.set_from_cli("foo")
3939
assert o.get() == ["foo"]
4040

4141

42-
def test_csv_list_attribute_empty_input():
43-
o = types.CommaSeparatedListAttribute()
42+
def test_array_attribute_empty_input():
43+
o = types.ArrayAttribute()
4444
o.set_from_cli("")
4545
assert o.get() == []
4646

4747
o.set_from_cli(" ")
4848
assert o.get() == []
4949

5050

51-
def test_csv_list_attribute_get_for_api_from_cli():
52-
o = types.CommaSeparatedListAttribute()
51+
def test_array_attribute_get_for_api_from_cli():
52+
o = types.ArrayAttribute()
5353
o.set_from_cli("foo,bar,baz")
5454
assert o.get_for_api() == "foo,bar,baz"
5555

5656

57-
def test_csv_list_attribute_get_for_api_from_list():
58-
o = types.CommaSeparatedListAttribute(["foo", "bar", "baz"])
57+
def test_array_attribute_get_for_api_from_list():
58+
o = types.ArrayAttribute(["foo", "bar", "baz"])
5959
assert o.get_for_api() == "foo,bar,baz"
6060

6161

62-
def test_csv_list_attribute_get_for_api_from_int_list():
63-
o = types.CommaSeparatedListAttribute([1, 9, 7])
62+
def test_array_attribute_get_for_api_from_int_list():
63+
o = types.ArrayAttribute([1, 9, 7])
6464
assert o.get_for_api() == "1,9,7"
6565

6666

67-
def test_csv_list_attribute_does_not_split_string():
68-
o = types.CommaSeparatedListAttribute("foo")
67+
def test_array_attribute_does_not_split_string():
68+
o = types.ArrayAttribute("foo")
6969
assert o.get_for_api() == "foo"
7070

7171

72+
# CommaSeparatedListAttribute tests
73+
def test_csv_string_attribute_get_for_api_from_cli():
74+
o = types.CommaSeparatedListAttribute()
75+
o.set_from_cli("foo,bar,baz")
76+
assert o.get_for_api() == "foo,bar,baz"
77+
78+
79+
def test_csv_string_attribute_get_for_api_from_list():
80+
o = types.CommaSeparatedListAttribute(["foo", "bar", "baz"])
81+
assert o.get_for_api() == "foo,bar,baz"
82+
83+
84+
def test_csv_string_attribute_get_for_api_from_int_list():
85+
o = types.CommaSeparatedListAttribute([1, 9, 7])
86+
assert o.get_for_api() == "1,9,7"
87+
88+
89+
# LowercaseStringAttribute tests
7290
def test_lowercase_string_attribute_get_for_api():
7391
o = types.LowercaseStringAttribute("FOO")
7492
assert o.get_for_api() == "foo"

0 commit comments

Comments
 (0)