Skip to content

Commit 98172f6

Browse files
WIP: Trying to solve array issue
1 parent 2cd15ac commit 98172f6

File tree

8 files changed

+61
-15
lines changed

8 files changed

+61
-15
lines changed

gitlab/mixins.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,17 @@ def list(self, **kwargs: Any) -> Union[base.RESTObjectList, List[base.RESTObject
231231
for attr_name, type_cls in self._types.items():
232232
if attr_name in data.keys():
233233
type_obj = type_cls(data[attr_name])
234-
data[attr_name] = type_obj.get_for_api()
234+
if isinstance(type_obj, g_types.ListAttribute):
235+
# NOTE(jlvillal): Array values are supposed to be
236+
# passed in the form of 'key[]=value1&key[]=value2'
237+
# https://docs.gitlab.com/ee/api/#array
238+
# But at the moment we haven't determined an elegant
239+
# way to do that. So for now just add the '[]' to the
240+
# key we send in the request.
241+
del data[attr_name]
242+
data[f"{attr_name}[]"] = type_obj.get_for_api()
243+
else:
244+
data[attr_name] = type_obj.get_for_api()
235245

236246
# Allow to overwrite the path, handy for custom listings
237247
path = data.pop("path", self.path)
@@ -313,6 +323,15 @@ def create(
313323
if isinstance(type_obj, g_types.FileAttribute):
314324
k = type_obj.get_file_name(attr_name)
315325
files[attr_name] = (k, data.pop(attr_name))
326+
elif isinstance(type_obj, g_types.ListAttribute):
327+
# NOTE(jlvillal): Array values are supposed to be
328+
# passed in the form of 'key[]=value1&key[]=value2'
329+
# https://docs.gitlab.com/ee/api/#array
330+
# But at the moment we haven't determined an elegant
331+
# way to do that. So for now just add the '[]' to the
332+
# key we send in the request.
333+
del data[attr_name]
334+
data[f"{attr_name}[]"] = type_obj.get_for_api()
316335
else:
317336
data[attr_name] = type_obj.get_for_api()
318337

@@ -409,6 +428,15 @@ def update(
409428
if isinstance(type_obj, g_types.FileAttribute):
410429
k = type_obj.get_file_name(attr_name)
411430
files[attr_name] = (k, new_data.pop(attr_name))
431+
elif isinstance(type_obj, g_types.ListAttribute):
432+
# NOTE(jlvillal): Array values are supposed to be
433+
# passed in the form of 'key[]=value1&key[]=value2'
434+
# https://docs.gitlab.com/ee/api/#array
435+
# But at the moment we haven't determined an elegant
436+
# way to do that. So for now just add the '[]' to the
437+
# key we send in the request.
438+
del new_data[attr_name]
439+
new_data[f"{attr_name}[]"] = type_obj.get_for_api()
412440
else:
413441
new_data[attr_name] = type_obj.get_for_api()
414442

gitlab/types.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,27 @@ def get_for_api(self) -> str:
4949
return ",".join([str(x) for x in self._value])
5050

5151

52+
class CsvStringAttribute(GitlabAttribute):
53+
"""For values which are sent to the server as a Comma Separated Values
54+
(CSV) string. We allow them to be specified as a list and we convert it
55+
into a CSV"""
56+
57+
def set_from_cli(self, cli_value: str) -> None:
58+
if not cli_value.strip():
59+
self._value = []
60+
else:
61+
self._value = [item.strip() for item in cli_value.split(",")]
62+
63+
def get_for_api(self) -> str:
64+
# Do not comma-split single value passed as string
65+
if isinstance(self._value, str):
66+
return self._value
67+
68+
if TYPE_CHECKING:
69+
assert isinstance(self._value, list)
70+
return ",".join([str(x) for x in self._value])
71+
72+
5273
class LowercaseStringAttribute(GitlabAttribute):
5374
def get_for_api(self) -> str:
5475
return str(self._value).lower()

gitlab/v4/objects/deploy_tokens.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class GroupDeployTokenManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
3939
"username",
4040
),
4141
)
42-
_types = {"scopes": types.ListAttribute}
42+
_types = {"scopes": types.CsvStringttribute}
4343

4444

4545
class ProjectDeployToken(ObjectDeleteMixin, RESTObject):
@@ -60,4 +60,4 @@ class ProjectDeployTokenManager(ListMixin, CreateMixin, DeleteMixin, RESTManager
6060
"username",
6161
),
6262
)
63-
_types = {"scopes": types.ListAttribute}
63+
_types = {"scopes": types.CsvStringttribute}

gitlab/v4/objects/epics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class GroupEpicManager(CRUDMixin, RESTManager):
4040
_update_attrs = RequiredOptional(
4141
optional=("title", "labels", "description", "start_date", "end_date"),
4242
)
43-
_types = {"labels": types.ListAttribute}
43+
_types = {"labels": types.CsvStringAttribute}
4444

4545

4646
class GroupEpicIssue(ObjectDeleteMixin, SaveMixin, RESTObject):

gitlab/v4/objects/issues.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class IssueManager(RetrieveMixin, RESTManager):
6363
"updated_after",
6464
"updated_before",
6565
)
66-
_types = {"iids": types.ListAttribute, "labels": types.ListAttribute}
66+
_types = {"iids": types.ListAttribute, "labels": types.CsvStringttribute}
6767

6868

6969
class GroupIssue(RESTObject):
@@ -90,7 +90,7 @@ class GroupIssueManager(ListMixin, RESTManager):
9090
"updated_after",
9191
"updated_before",
9292
)
93-
_types = {"iids": types.ListAttribute, "labels": types.ListAttribute}
93+
_types = {"iids": types.ListAttribute, "labels": types.CsvStringttribute}
9494

9595

9696
class ProjectIssue(
@@ -220,7 +220,7 @@ class ProjectIssueManager(CRUDMixin, RESTManager):
220220
"discussion_locked",
221221
),
222222
)
223-
_types = {"iids": types.ListAttribute, "labels": types.ListAttribute}
223+
_types = {"iids": types.ListAttribute, "labels": types.CsvStringttribute}
224224

225225

226226
class ProjectIssueLink(ObjectDeleteMixin, RESTObject):

gitlab/v4/objects/merge_requests.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ class MergeRequestManager(ListMixin, RESTManager):
9797
_types = {
9898
"approver_ids": types.ListAttribute,
9999
"approved_by_ids": types.ListAttribute,
100-
"in": types.ListAttribute,
101-
"labels": types.ListAttribute,
100+
"in": types.CsvStringttribute,
102101
}
103102

104103

@@ -135,7 +134,6 @@ class GroupMergeRequestManager(ListMixin, RESTManager):
135134
_types = {
136135
"approver_ids": types.ListAttribute,
137136
"approved_by_ids": types.ListAttribute,
138-
"labels": types.ListAttribute,
139137
}
140138

141139

@@ -453,7 +451,6 @@ class ProjectMergeRequestManager(CRUDMixin, RESTManager):
453451
"approver_ids": types.ListAttribute,
454452
"approved_by_ids": types.ListAttribute,
455453
"iids": types.ListAttribute,
456-
"labels": types.ListAttribute,
457454
}
458455

459456
def get(

gitlab/v4/objects/projects.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ class ProjectManager(CRUDMixin, RESTManager):
771771
"with_merge_requests_enabled",
772772
"with_programming_language",
773773
)
774-
_types = {"avatar": types.ImageAttribute, "topic": types.ListAttribute}
774+
_types = {"avatar": types.ImageAttribute, "topic": types.CsvStringttribute}
775775

776776
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Project:
777777
return cast(Project, super().get(id=id, lazy=lazy, **kwargs))

gitlab/v4/objects/runners.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class RunnerManager(CRUDMixin, RESTManager):
6868
),
6969
)
7070
_list_filters = ("scope", "tag_list")
71-
_types = {"tag_list": types.ListAttribute}
71+
_types = {"tag_list": types.CsvStringAttribute}
7272

7373
@cli.register_custom_action("RunnerManager", tuple(), ("scope",))
7474
@exc.on_http_error(exc.GitlabListError)
@@ -130,7 +130,7 @@ class GroupRunnerManager(ListMixin, RESTManager):
130130
_from_parent_attrs = {"group_id": "id"}
131131
_create_attrs = RequiredOptional(required=("runner_id",))
132132
_list_filters = ("scope", "tag_list")
133-
_types = {"tag_list": types.ListAttribute}
133+
_types = {"tag_list": types.CsvStringAttribute}
134134

135135

136136
class ProjectRunner(ObjectDeleteMixin, RESTObject):
@@ -143,4 +143,4 @@ class ProjectRunnerManager(CreateMixin, DeleteMixin, ListMixin, RESTManager):
143143
_from_parent_attrs = {"project_id": "id"}
144144
_create_attrs = RequiredOptional(required=("runner_id",))
145145
_list_filters = ("scope", "tag_list")
146-
_types = {"tag_list": types.ListAttribute}
146+
_types = {"tag_list": types.CsvStringAttribute}

0 commit comments

Comments
 (0)