8000 fix: Use the [] after key names for array variables · python-gitlab/python-gitlab@f596068 · GitHub
[go: up one dir, main page]

Skip to content

Commit f596068

Browse files
fix: Use the [] after key names for array variables
1. Create a new CsvStringAttribute class. This is to indicate types which are sent to the GitLab server as comma-separated-strings (CSV) but we have been allowing users to use a list-of-strings. These values are NOT array values, so adding [] to the key name breaks them. 2. If a value is a ListAttribute
1 parent 2cd15ac commit f596068

File tree

14 files changed

+97
-48
lines changed

14 files changed

+97
-48
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.ArrayAttribute):
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.ArrayAttribute):
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.ArrayAttribute):
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
1E0A 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: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,31 @@ def get_for_api(self) -> Any:
3232
return self._value
3333

3434

35-
class ListAttribute(GitlabAttribute):
35+
class ArrayAttribute(GitlabAttribute):
36+
"""To support `array` types as documented in
37+
https://docs.gitlab.com/ee/api/#array"""
38+
39+
def set_from_cli(self, cli_value: str) -> None:
40+
if not cli_value.strip():
41+
self._value = []
42+
else:
43+
self._value = [item.strip() for item in cli_value.split(",")]
44+
45+
def get_for_api(self) -> str:
46+
# Do not comma-split single value passed as string
47+
if isinstance(self._value, str):
48+
return self._value
49+
50+
if TYPE_CHECKING:
51+
assert isinstance(self._value, list)
52+
return ",".join([str(x) for x in self._value])
53+
54+
55+
class CsvStringAttribute(GitlabAttribute):
56+
"""For values which are sent to the server as a Comma Separated Values
57+
(CSV) string. We allow them to be specified as a list and we convert it
58+
into a CSV"""
59+
3660
def set_from_cli(self, cli_value: str) -> None:
3761
if not cli_value.strip():
3862
self._value = []

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.CsvStringAttribute}
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.CsvStringAttribute}

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/groups.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ class GroupManager(CRUDMixin, RESTManager):
290290
"shared_runners_setting",
291291
),
292292
)
293-
_types = {"avatar": types.ImageAttribute, "skip_groups": types.ListAttribute}
293+
_types = {"avatar": types.ImageAttribute, "skip_groups": types.ArrayAttribute}
294294

295295
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Group:
296296
return cast(Group, super().get(id=id, lazy=lazy, **kwargs))
@@ -350,7 +350,7 @@ class GroupSubgroupManager(ListMixin, RESTManager):
350350
"with_custom_attributes",
351351
"min_access_level",
352352
)
353-
_types = {"skip_groups": types.ListAttribute}
353+
_types = {"skip_groups": types.ArrayAttribute}
354354

355355

356356
class GroupDescendantGroup(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.ArrayAttribute, "labels": types.CsvStringAttribute}
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.ArrayAttribute, "labels": types.CsvStringAttribute}
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.ArrayAttribute, "labels": types.CsvStringAttribute}
224224

225225

226226
class ProjectIssueLink(ObjectDeleteMixin, RESTObject):

gitlab/v4/objects/members.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class GroupMemberManager(CRUDMixin, RESTManager):
3939
_update_attrs = RequiredOptional(
4040
required=("access_level",), optional=("expires_at",)
4141
)
42-
_types = {"user_ids": types.ListAttribute}
42+
_types = {"user_ids": types.ArrayAttribute}
4343

4444
def get(
4545
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
@@ -95,7 +95,7 @@ class ProjectMemberManager(CRUDMixin, RESTManager):
9595
_update_attrs = RequiredOptional(
9696
required=("access_level",), optional=("expires_at",)
9797
)
98-
_types = {"user_ids": types.ListAttribute}
98+
_types = {"user_ids": types.ArrayAttribute}
9999

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

gitlab/v4/objects/merge_requests.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,9 @@ class MergeRequestManager(ListMixin, RESTManager):
9595
"deployed_after",
9696
)
9797
_types = {
98-
"approver_ids": types.ListAttribute,
99-
"approved_by_ids": types.ListAttribute,
100-
"in": types.ListAttribute,
101-
"labels": types.ListAttribute,
98+
"approver_ids": types.ArrayAttribute,
99+
"approved_by_ids": types.ArrayAttribute,
100+
"in": types.CsvStringAttribute,
102101
}
103102

104103

@@ -133,9 +132,8 @@ class GroupMergeRequestManager(ListMixin, RESTManager):
133132
"wip",
134133
)
135134
_types = {
136-
"approver_ids": types.ListAttribute,
137-
"approved_by_ids": types.ListAttribute,
138-
"labels": types.ListAttribute,
135+
"approver_ids": types.ArrayAttribute,
136+
"approved_by_ids": types.ArrayAttribute,
139137
}
140138

141139

@@ -450,10 +448,9 @@ class ProjectMergeRequestManager(CRUDMixin, RESTManager):
450448
"wip",
451449
)
452450
_types = {
453-
"approver_ids": types.ListAttribute,
454-
"approved_by_ids": types.ListAttribute,
455-
"iids": types.ListAttribute,
456-
"labels": types.ListAttribute,
451+
"approver_ids": types.ArrayAttribute,
452+
"approved_by_ids": types.ArrayAttribute,
453+
"iids": types.ArrayAttribute,
457454
}
458455

459456
def get(

gitlab/v4/objects/milestones.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class GroupMilestoneManager(CRUDMixin, RESTManager):
8989
optional=("title", "description", "due_date", "start_date", "state_event"),
9090
)
9191
_list_filters = ("iids", "state", "search")
92-
_types = {"iids": types.ListAttribute}
92+
_types = {"iids": types.ArrayAttribute}
9393

9494

9595
class ProjectMilestone(PromoteMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -164,4 +164,4 @@ class ProjectMilestoneManager(CRUDMixin, RESTManager):
164164
optional=("title", "description", "due_date", "start_date", "state_event"),
165165
)
166166
_list_filters = ("iids", "state", "search")
167-
_types = {"iids": types.ListAttribute}
167+
_types = {"iids": types.ArrayAttribute}

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.CsvStringAttribute}
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))

0 commit comments

Comments
 (0)
0