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

Commit6eee494

Browse files
igorp-collaboranejch
authored andcommitted
feat(api)!: ListMixin.list typing overload
BREAKING CHANGE: The `http_list` method will no longerignore the `iterator` argument if the `page` argument is notNone. The `ListMixin.list()` will now return either list oriterator based on the `iterator` argument. This will makecertain type narrowing checks redundant.Overload `ListMixin.list` method typing to return either`RESTObjectList` or `list` based on the `iterator` argument.By default then `iterator` is False return a list otherwisereturn an iterator.Provide 3 overloads:1. `iterator: Literal[False]` - this is the default and returns a list.2. `iterator: Literal[True]` - return an iterator.3. `iterator: bool` - return either list or iterator. It is useful when the list function is being extended by another function that can also take either True or False for the `iterator` argument.Make `page` argument to `http_list` not override the `iterator`to make the function signatures more straight forward. Thisalso makes it easier to unpack `**kwargs` as only `iterator`argument will control if a list or iterator is returned so the`**kwargs` can no longer have a hidden page argument.
1 parentbeb2f24 commit6eee494

File tree

8 files changed

+134
-35
lines changed

8 files changed

+134
-35
lines changed

‎gitlab/client.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -881,18 +881,16 @@ def http_list(
881881

882882
page=kwargs.get("page")
883883

884-
ifiteratorandpageisnotNone:
885-
arg_used_message=f"iterator={iterator}"
886-
utils.warn(
887-
message=(
888-
f"`{arg_used_message}` and `page={page}` were both specified. "
889-
f"`{arg_used_message}` will be ignored and a `list` will be "
890-
f"returned."
891-
),
892-
category=UserWarning,
893-
)
884+
ifiterator:
885+
ifpageisnotNone:
886+
utils.warn(
887+
message=(
888+
f"`{iterator=}` and `{page=}` were both specified. "
889+
f"`{page=}` will be ignored."
890+
),
891+
category=UserWarning,
892+
)
894893

895-
ifiteratorandpageisNone:
896894
# Generator requested
897895
returnGitlabList(self,url,query_data,**kwargs)
898896

‎gitlab/mixins.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,24 @@ def refresh(self, **kwargs: Any) -> None:
161161
classListMixin(HeadMixin[base.TObjCls]):
162162
_list_filters:tuple[str, ...]= ()
163163

164+
@overload
165+
deflist(
166+
self,*,iterator:Literal[False]=False,**kwargs:Any
167+
)->list[base.TObjCls]: ...
168+
169+
@overload
170+
deflist(
171+
self,*,iterator:Literal[True]=True,**kwargs:Any
172+
)->base.RESTObjectList[base.TObjCls]: ...
173+
174+
@overload
175+
deflist(
176+
self,*,iterator:bool=False,**kwargs:Any
177+
)->base.RESTObjectList[base.TObjCls]|list[base.TObjCls]: ...
178+
164179
@exc.on_http_error(exc.GitlabListError)
165180
deflist(
166-
self,**kwargs:Any
181+
self,*,iterator:bool=False,**kwargs:Any
167182
)->base.RESTObjectList[base.TObjCls]|list[base.TObjCls]:
168183
"""Retrieve a list of objects.
169184
@@ -203,7 +218,7 @@ def list(
203218
# Allow to overwrite the path, handy for custom listings
204219
path=data.pop("path",self.path)
205220

206-
obj=self.gitlab.http_list(path,**data)
221+
obj=self.gitlab.http_list(path,iterator=iterator,**data)
207222
ifisinstance(obj,list):
208223
return [self._obj_cls(self,item,created_from_list=True)foriteminobj]
209224
returnbase.RESTObjectList(self,self._obj_cls,obj)

‎gitlab/v4/cli.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,7 @@ def do_create(self) -> gitlab.base.RESTObject:
133133
cli.die("Impossible to create object",e)
134134
returnresult
135135

136-
defdo_list(
137-
self,
138-
)-> (
139-
gitlab.base.RESTObjectList[gitlab.base.RESTObject]
140-
|list[gitlab.base.RESTObject]
141-
):
136+
defdo_list(self)->list[gitlab.base.RESTObject]:
142137
ifTYPE_CHECKING:
143138
assertisinstance(self.mgr,gitlab.mixins.ListMixin)
144139
message_details=gitlab.utils.WarnMessageData(
@@ -150,7 +145,9 @@ def do_list(
150145
)
151146

152147
try:
153-
result=self.mgr.list(**self.args,message_details=message_details)
148+
result=self.mgr.list(
149+
**self.args,message_details=message_details,iterator=False
150+
)
154151
exceptExceptionase:# pragma: no cover, cli.die is unit-tested
155152
cli.die("Impossible to list objects",e)
156153
returnresult

‎gitlab/v4/objects/ldap.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__importannotations
22

3-
fromtypingimportAny
3+
fromtypingimportAny,Literal,overload
44

55
fromgitlabimportexceptionsasexc
66
fromgitlab.baseimportRESTManager,RESTObject,RESTObjectList
@@ -17,8 +17,25 @@ class LDAPGroupManager(RESTManager[LDAPGroup]):
1717
_obj_cls=LDAPGroup
1818
_list_filters= ("search","provider")
1919

20+
@overload
21+
deflist(
22+
self,*,iterator:Literal[False]=False,**kwargs:Any
23+
)->list[LDAPGroup]: ...
24+
25+
@overload
26+
deflist(
27+
self,*,iterator:Literal[True]=True,**kwargs:Any
28+
)->RESTObjectList[LDAPGroup]: ...
29+
30+
@overload
31+
deflist(
32+
self,*,iterator:bool=False,**kwargs:Any
33+
)->list[LDAPGroup]|RESTObjectList[LDAPGroup]: ...
34+
2035
@exc.on_http_error(exc.GitlabListError)
21-
deflist(self,**kwargs:Any)->list[LDAPGroup]|RESTObjectList[LDAPGroup]:
36+
deflist(
37+
self,*,iterator:bool=False,**kwargs:Any
38+
)->list[LDAPGroup]|RESTObjectList[LDAPGroup]:
2239
"""Retrieve a list of objects.
2340
2441
Args:
@@ -45,7 +62,7 @@ def list(self, **kwargs: Any) -> list[LDAPGroup] | RESTObjectList[LDAPGroup]:
4562
else:
4663
path=self._path
4764

48-
obj=self.gitlab.http_list(path,**data)
65+
obj=self.gitlab.http_list(path,iterator=iterator,**data)
4966
ifisinstance(obj,list):
5067
return [self._obj_cls(self,item)foriteminobj]
5168
returnRESTObjectList(self,self._obj_cls,obj)

‎gitlab/v4/objects/snippets.py

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,25 @@ class SnippetManager(CRUDMixin[Snippet]):
108108
optional=("title","files","file_name","content","visibility","description")
109109
)
110110

111+
@overload
112+
deflist_public(
113+
self,*,iterator:Literal[False]=False,**kwargs:Any
114+
)->list[Snippet]: ...
115+
116+
@overload
117+
deflist_public(
118+
self,*,iterator:Literal[True]=True,**kwargs:Any
119+
)->RESTObjectList[Snippet]: ...
120+
121+
@overload
122+
deflist_public(
123+
self,*,iterator:bool=False,**kwargs:Any
124+
)->RESTObjectList[Snippet]|list[Snippet]: ...
125+
111126
@cli.register_custom_action(cls_names="SnippetManager")
112-
deflist_public(self,**kwargs:Any)->RESTObjectList[Snippet]|list[Snippet]:
127+
deflist_public(
128+
self,*,iterator:bool=False,**kwargs:Any
129+
)->RESTObjectList[Snippet]|list[Snippet]:
113130
"""List all public snippets.
114131
115132
Args:
@@ -126,10 +143,27 @@ def list_public(self, **kwargs: Any) -> RESTObjectList[Snippet] | list[Snippet]:
126143
Returns:
127144
The list of snippets, or a generator if `iterator` is True
128145
"""
129-
returnself.list(path="/snippets/public",**kwargs)
146+
returnself.list(path="/snippets/public",iterator=iterator,**kwargs)
147+
148+
@overload
149+
deflist_all(
150+
self,*,iterator:Literal[False]=False,**kwargs:Any
151+
)->list[Snippet]: ...
152+
153+
@overload
154+
deflist_all(
155+
self,*,iterator:Literal[True]=True,**kwargs:Any
156+
)->RESTObjectList[Snippet]: ...
157+
158+
@overload
159+
deflist_all(
160+
self,*,iterator:bool=False,**kwargs:Any
161+
)->RESTObjectList[Snippet]|list[Snippet]: ...
130162

131163
@cli.register_custom_action(cls_names="SnippetManager")
132-
deflist_all(self,**kwargs:Any)->RESTObjectList[Snippet]|list[Snippet]:
164+
deflist_all(
165+
self,*,iterator:bool=False,**kwargs:Any
166+
)->RESTObjectList[Snippet]|list[Snippet]:
133167
"""List all snippets.
134168
135169
Args:
@@ -146,9 +180,30 @@ def list_all(self, **kwargs: Any) -> RESTObjectList[Snippet] | list[Snippet]:
146180
Returns:
147181
A generator for the snippets list
148182
"""
149-
returnself.list(path="/snippets/all",**kwargs)
183+
returnself.list(path="/snippets/all",iterator=iterator,**kwargs)
184+
185+
@overload
186+
defpublic(
187+
self,
188+
*,
189+
iterator:Literal[False]=False,
190+
page:int|None=None,
191+
**kwargs:Any,
192+
)->list[Snippet]: ...
193+
194+
@overload
195+
defpublic(
196+
self,*,iterator:Literal[True]=True,**kwargs:Any
197+
)->RESTObjectList[Snippet]: ...
198+
199+
@overload
200+
defpublic(
201+
self,*,iterator:bool=False,**kwargs:Any
202+
)->RESTObjectList[Snippet]|list[Snippet]: ...
150203

151-
defpublic(self,**kwargs:Any)->RESTObjectList[Snippet]|list[Snippet]:
204+
defpublic(
205+
self,*,iterator:bool=False,**kwargs:Any
206+
)->RESTObjectList[Snippet]|list[Snippet]:
152207
"""List all public snippets.
153208
154209
Args:
@@ -172,7 +227,7 @@ def public(self, **kwargs: Any) -> RESTObjectList[Snippet] | list[Snippet]:
172227
),
173228
category=DeprecationWarning,
174229
)
175-
returnself.list(path="/snippets/public",**kwargs)
230+
returnself.list(path="/snippets/public",iterator=iterator,**kwargs)
176231

177232

178233
classProjectSnippet(UserAgentDetailMixin,SaveMixin,ObjectDeleteMixin,RESTObject):

‎gitlab/v4/objects/users.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from __future__importannotations
88

9-
fromtypingimportAny,cast,Optional
9+
fromtypingimportAny,cast,Literal,Optional,overload
1010

1111
importrequests
1212

@@ -623,7 +623,24 @@ class UserProjectManager(ListMixin[UserProject], CreateMixin[UserProject]):
623623
"id_before",
624624
)
625625

626-
deflist(self,**kwargs:Any)->RESTObjectList[UserProject]|list[UserProject]:
626+
@overload
627+
deflist(
628+
self,*,iterator:Literal[False]=False,**kwargs:Any
629+
)->list[UserProject]: ...
630+
631+
@overload
632+
deflist(
633+
self,*,iterator:Literal[True]=True,**kwargs:Any
634+
)->RESTObjectList[UserProject]: ...
635+
636+
@overload
637+
deflist(
638+
self,*,iterator:bool=False,**kwargs:Any
639+
)->RESTObjectList[UserProject]|list[UserProject]: ...
640+
641+
deflist(
642+
self,*,iterator:bool=False,**kwargs:Any
643+
)->RESTObjectList[UserProject]|list[UserProject]:
627644
"""Retrieve a list of objects.
628645
629646
Args:
@@ -645,7 +662,7 @@ def list(self, **kwargs: Any) -> RESTObjectList[UserProject] | list[UserProject]
645662
path=f"/users/{self._parent.id}/projects"
646663
else:
647664
path=f"/users/{self._from_parent_attrs['user_id']}/projects"
648-
returnsuper().list(path=path,**kwargs)
665+
returnsuper().list(path=path,iterator=iterator,**kwargs)
649666

650667

651668
classStarredProject(RESTObject):

‎tests/functional/api/test_merge_requests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def test_merge_request_reset_approvals(gitlab_url, project):
177177
# Pause to let GL catch up (happens on hosted too, sometimes takes a while for server to be ready to merge)
178178
time.sleep(5)
179179

180-
mr=bot_project.mergerequests.list()[0]# type: ignore[index]
180+
mr=bot_project.mergerequests.list()[0]
181181

182182
assertmr.reset_approvals()
183183

‎tests/unit/test_gitlab_http_methods.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -567,8 +567,8 @@ def test_list_request_page_and_iterator(gl):
567567
UserWarning,match="`iterator=True` and `page=1` were both specified"
568568
):
569569
result=gl.http_list("/projects",iterator=True,page=1)
570-
assertisinstance(result,list)
571-
assertlen(result)==20
570+
assertisinstance(result,GitlabList)
571+
assertlen(list(result))==20
572572
assertlen(responses.calls)==1
573573

574574

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp