Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita939db1

Browse files
fix: use the [] after key names for array variables
1. If a value is of type ArrayAttribute then append '[]' to the name of the value.2. Move processing of most GitlabAttributes into the client.py:http_request() method. Now we convert our params into a list of tuples so that we can have multiple identical keys but with different values.This is step 3 in a series of steps of our goal to add fullsupport for the GitLab API data types[1]: * array * hash * array of hashesStep one was: commit5127b15Step two was: commita57334fFixes:#1698[1]https://docs.gitlab.com/ee/api/#encoding-api-parameters-of-array-and-hash-types
1 parent1ecbc7c commita939db1

File tree

6 files changed

+111
-6
lines changed

6 files changed

+111
-6
lines changed

‎gitlab/client.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
"""Wrapper for the GitLab API."""
1818

19+
importcopy
1920
importos
2021
importtime
2122
fromtypingimportAny,cast,Dict,List,Optional,Tuple,TYPE_CHECKING,Union
@@ -28,6 +29,7 @@
2829
importgitlab.config
2930
importgitlab.const
3031
importgitlab.exceptions
32+
fromgitlabimporttypesasgl_types
3133
fromgitlabimportutils
3234

3335
REDIRECT_MSG= (
@@ -626,6 +628,28 @@ def _prepare_send_data(
626628

627629
return (post_data,None,"application/json")
628630

631+
@staticmethod
632+
def_prepare_dict_for_api(*,in_dict:Dict[str,Any])->Dict[str,Any]:
633+
result:Dict[str,Any]= {}
634+
forkey,valueinin_dict.items():
635+
ifisinstance(value,gl_types.GitlabAttribute):
636+
result[key]=value.get_for_api()
637+
else:
638+
result[key]=copy.deepcopy(in_dict[key])
639+
returnresult
640+
641+
@staticmethod
642+
def_param_dict_to_param_tuples(*,params:Dict[str,Any])->List[Tuple[str,Any]]:
643+
"""Convert a dict to a list of key/values. This will be used to pass
644+
values to requests"""
645+
result:List[Tuple[str,Any]]= []
646+
forkey,valueinparams.items():
647+
ifisinstance(value,gl_types.GitlabAttribute):
648+
result.extend(value.get_as_tuple_list(key=key))
649+
else:
650+
result.append((key,value))
651+
returnresult
652+
629653
defhttp_request(
630654
self,
631655
verb:str,
@@ -688,6 +712,10 @@ def http_request(
688712
else:
689713
utils.copy_dict(src=kwargs,dest=params)
690714

715+
tuple_params=self._param_dict_to_param_tuples(params=params)
716+
ifisinstance(post_data,dict):
717+
post_data=self._prepare_dict_for_api(in_dict=post_data)
718+
691719
opts=self._get_session_opts()
692720

693721
verify=opts.pop("verify")
@@ -710,7 +738,7 @@ def http_request(
710738
url=url,
711739
json=json,
712740
data=data,
713-
params=params,
741+
params=tuple_params,
714742
timeout=timeout,
715743
verify=verify,
716744
stream=streamed,

‎gitlab/types.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ def set_from_cli(self, cli_value: Any) -> None:
6666
defget_for_api(self)->Any:
6767
returnself._value
6868

69+
defget_as_tuple_list(self,*,key:str)->List[Tuple[str,Any]]:
70+
return [(key,self._value)]
71+
6972

7073
class_ListArrayAttribute(GitlabAttribute):
7174
"""Helper class to support `list` / `array` types."""
@@ -90,17 +93,31 @@ class ArrayAttribute(_ListArrayAttribute):
9093
"""To support `array` types as documented in
9194
https://docs.gitlab.com/ee/api/#array"""
9295

96+
defget_as_tuple_list(self,*,key:str)->List[Tuple[str,str]]:
97+
ifisinstance(self._value,str):
98+
return [(f"{key}[]",self._value)]
99+
100+
ifTYPE_CHECKING:
101+
assertisinstance(self._value,list)
102+
return [(f"{key}[]",str(value))forvalueinself._value]
103+
93104

94105
classCommaSeparatedListAttribute(_ListArrayAttribute):
95106
"""For values which are sent to the server as a Comma Separated Values
96107
(CSV) string. We allow them to be specified as a list and we convert it
97108
into a CSV"""
98109

110+
defget_as_tuple_list(self,*,key:str)->List[Tuple[str,str]]:
111+
return [(key,self.get_for_api())]
112+
99113

100114
classLowercaseStringAttribute(GitlabAttribute):
101115
defget_for_api(self)->str:
102116
returnstr(self._value).lower()
103117

118+
defget_as_tuple_list(self,*,key:str)->List[Tuple[str,str]]:
119+
return [(key,self.get_for_api())]
120+
104121

105122
classFileAttribute(GitlabAttribute):
106123
@staticmethod

‎gitlab/utils.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ def _transform_types(
7777

7878
type_obj=type_cls(data[attr_name])
7979

80-
# if the type if FileAttribute we need to pass the data as file
81-
iftransform_filesandisinstance(type_obj,types.FileAttribute):
82-
key=type_obj.get_file_name(attr_name)
83-
files[attr_name]= (key,data.pop(attr_name))
80+
# if the type is FileAttribute we need to pass the data as file
81+
ifisinstance(type_obj,types.FileAttribute):
82+
iftransform_files:
83+
key=type_obj.get_file_name(attr_name)
84+
files[attr_name]= (key,data.pop(attr_name))
8485
else:
85-
data[attr_name]=type_obj.get_for_api()
86+
data[attr_name]=type_obj
8687

8788
returndata,files
8889

@@ -94,6 +95,8 @@ def copy_dict(
9495
)->None:
9596
fork,vinsrc.items():
9697
ifisinstance(v,dict):
98+
# NOTE(jlvillal): This provides some support for the `hash` type
99+
# https://docs.gitlab.com/ee/api/#hash
97100
# Transform dict values to new attributes. For example:
98101
# custom_attributes: {'foo', 'bar'} =>
99102
# "custom_attributes['foo']": "bar"

‎tests/functional/api/test_groups.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ def test_groups(gl):
9999
assertlen(group1.members.list())==3
100100
assertlen(group2.members.list())==2
101101

102+
# Test `user_ids` array
103+
result=group1.members.list(user_ids=[user.id,99999])
104+
assertlen(result)==1
105+
assertresult[0].id==user.id
106+
102107
group1.members.delete(user.id)
103108
assertusernotingroup1.members.list()
104109
assertgroup1.members_all.list()

‎tests/unit/test_gitlab_http_methods.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
importrequests
66
importresponses
77

8+
importgitlab
89
fromgitlabimportGitlabHttpError,GitlabList,GitlabParsingError,RedirectError
910
fromgitlab.clientimportRETRYABLE_TRANSIENT_ERROR_CODES
1011
fromtests.unitimporthelpers
@@ -742,3 +743,20 @@ def test_delete_request_404(gl):
742743
withpytest.raises(GitlabHttpError):
743744
gl.http_delete("/not_there")
744745
assertresponses.assert_call_count(url,1)isTrue
746+
747+
748+
@responses.activate
749+
deftest_array_type_request(gl):
750+
url="http://localhost/api/v4/projects"
751+
params="array_var[]=1&array_var[]=2&array_var[]=3"
752+
full_url=f"{url}?array_var%5B%5D=1&array_var%5B%5D=2&array_var%5B%5D=3"
753+
responses.add(
754+
method=responses.GET,
755+
url=url,
756+
json={"name":"project1"},
757+
status=200,
758+
match=[responses.matchers.query_string_matcher(params)],
759+
)
760+
761+
gl.http_get("/projects",array_var=gitlab.types.ArrayAttribute([1,2,3]))
762+
assertresponses.assert_call_count(full_url,1)isTrue

‎tests/unit/test_types.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def test_gitlab_attribute_get():
7474
o.set_from_cli("whatever2")
7575
asserto.get()=="whatever2"
7676
asserto.get_for_api()=="whatever2"
77+
asserto.get_as_tuple_list(key="foo")== [("foo","whatever2")]
7778

7879
o=types.GitlabAttribute()
7980
asserto._valueisNone
@@ -113,6 +114,24 @@ def test_array_attribute_get_for_api_from_int_list():
113114
asserto.get_for_api()=="1,9,7"
114115

115116

117+
deftest_array_attribute_get_as_tuple_list_from_list():
118+
o=types.ArrayAttribute(["foo","bar","baz"])
119+
asserto.get_as_tuple_list(key="identifier")== [
120+
("identifier[]","foo"),
121+
("identifier[]","bar"),
122+
("identifier[]","baz"),
123+
]
124+
125+
126+
deftest_array_attribute_get_as_tuple_list_from_int_list():
127+
o=types.ArrayAttribute([1,9,7])
128+
asserto.get_as_tuple_list(key="identifier")== [
129+
("identifier[]","1"),
130+
("identifier[]","9"),
131+
("identifier[]","7"),
132+
]
133+
134+
116135
deftest_array_attribute_does_not_split_string():
117136
o=types.ArrayAttribute("foo")
118137
asserto.get_for_api()=="foo"
@@ -135,7 +154,22 @@ def test_csv_string_attribute_get_for_api_from_int_list():
135154
asserto.get_for_api()=="1,9,7"
136155

137156

157+
deftest_csv_string_attribute_get_as_tuple_list_from_list():
158+
o=types.CommaSeparatedListAttribute(["foo","bar","baz"])
159+
asserto.get_as_tuple_list(key="identifier")== [("identifier","foo,bar,baz")]
160+
161+
162+
deftest_csv_string_attribute_get_as_tuple_list_from_int_list():
163+
o=types.CommaSeparatedListAttribute([1,9,7])
164+
asserto.get_as_tuple_list(key="identifier")== [("identifier","1,9,7")]
165+
166+
138167
# LowercaseStringAttribute tests
139168
deftest_lowercase_string_attribute_get_for_api():
140169
o=types.LowercaseStringAttribute("FOO")
141170
asserto.get_for_api()=="foo"
171+
172+
173+
deftest_lowercase_string_attribute_get_as_tuple():
174+
o=types.LowercaseStringAttribute("FOO")
175+
asserto.get_as_tuple_list(key="user_name")== [("user_name","foo")]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp