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

Commitbefba35

Browse files
igorp-collaboranejch
authored andcommitted
feat(api)!: Make RESTObjectList typing generic
BREAKING CHANGE: Type narrowing of `list()` methods return objectsfrom RESTObject to a concrete subclass (for example `MergeRequest`)can become redundant.Currently the RESTObjectList type hints yielded objectsas base RESTObject. However, the ListMixin is now genericand will return the RESTObject subclass based on the RESTManagertyping.Using `typing.Generic` it is possible to make RESTObjectListtype hint a specific subclass of the RESTObject.Iterating over `list()` call the ListMixin will now yieldthe same object class because both `list` and `RESTObjectList`will have the same type hinted subclass.Signed-off-by: Igor Ponomarev <igor.ponomarev@collabora.com>
1 parent9040dbe commitbefba35

File tree

9 files changed

+44
-33
lines changed

9 files changed

+44
-33
lines changed

‎gitlab/base.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,10 @@ def encoded_id(self) -> int | str | None:
252252
returnobj_id
253253

254254

255-
classRESTObjectList:
255+
TObjCls=TypeVar("TObjCls",bound=RESTObject)
256+
257+
258+
classRESTObjectList(Generic[TObjCls]):
256259
"""Generator object representing a list of RESTObject's.
257260
258261
This generator uses the Gitlab pagination system to fetch new data when
@@ -268,7 +271,7 @@ class RESTObjectList:
268271
"""
269272

270273
def__init__(
271-
self,manager:RESTManager[Any],obj_cls:type[RESTObject],_list:GitlabList
274+
self,manager:RESTManager[TObjCls],obj_cls:type[TObjCls],_list:GitlabList
272275
)->None:
273276
"""Creates an objects list from a GitlabList.
274277
@@ -284,16 +287,16 @@ def __init__(
284287
self._obj_cls=obj_cls
285288
self._list=_list
286289

287-
def__iter__(self)->RESTObjectList:
290+
def__iter__(self)->RESTObjectList[TObjCls]:
288291
returnself
289292

290293
def__len__(self)->int:
291294
returnlen(self._list)
292295

293-
def__next__(self)->RESTObject:
296+
def__next__(self)->TObjCls:
294297
returnself.next()
295298

296-
defnext(self)->RESTObject:
299+
defnext(self)->TObjCls:
297300
data=self._list.next()
298301
returnself._obj_cls(self.manager,data,created_from_list=True)
299302

@@ -334,9 +337,6 @@ def total(self) -> int | None:
334337
returnself._list.total
335338

336339

337-
TObjCls=TypeVar("TObjCls",bound=RESTObject)
338-
339-
340340
classRESTManager(Generic[TObjCls]):
341341
"""Base class for CRUD operations on objects.
342342

‎gitlab/mixins.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,9 @@ class ListMixin(HeadMixin[base.TObjCls]):
162162
_list_filters:tuple[str, ...]= ()
163163

164164
@exc.on_http_error(exc.GitlabListError)
165-
deflist(self,**kwargs:Any)->base.RESTObjectList|list[base.TObjCls]:
165+
deflist(
166+
self,**kwargs:Any
167+
)->base.RESTObjectList[base.TObjCls]|list[base.TObjCls]:
166168
"""Retrieve a list of objects.
167169
168170
Args:

‎gitlab/v4/cli.py

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

136-
defdo_list(self)->gitlab.base.RESTObjectList|list[gitlab.base.RESTObject]:
136+
defdo_list(
137+
self,
138+
)-> (
139+
gitlab.base.RESTObjectList[gitlab.base.RESTObject]
140+
|list[gitlab.base.RESTObject]
141+
):
137142
ifTYPE_CHECKING:
138143
assertisinstance(self.mgr,gitlab.mixins.ListMixin)
139144
message_details=gitlab.utils.WarnMessageData(

‎gitlab/v4/objects/ldap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class LDAPGroupManager(RESTManager[LDAPGroup]):
1818
_list_filters= ("search","provider")
1919

2020
@exc.on_http_error(exc.GitlabListError)
21-
deflist(self,**kwargs:Any)->list[LDAPGroup]|RESTObjectList:
21+
deflist(self,**kwargs:Any)->list[LDAPGroup]|RESTObjectList[LDAPGroup]:
2222
"""Retrieve a list of objects.
2323
2424
Args:

‎gitlab/v4/objects/merge_requests.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def cancel_merge_when_pipeline_succeeds(self, **kwargs: Any) -> dict[str, str]:
203203

204204
@cli.register_custom_action(cls_names="ProjectMergeRequest")
205205
@exc.on_http_error(exc.GitlabListError)
206-
defrelated_issues(self,**kwargs:Any)->RESTObjectList:
206+
defrelated_issues(self,**kwargs:Any)->RESTObjectList[ProjectIssue]:
207207
"""List issues related to this merge request."
208208
209209
Args:
@@ -232,7 +232,7 @@ def related_issues(self, **kwargs: Any) -> RESTObjectList:
232232

233233
@cli.register_custom_action(cls_names="ProjectMergeRequest")
234234
@exc.on_http_error(exc.GitlabListError)
235-
defcloses_issues(self,**kwargs:Any)->RESTObjectList:
235+
defcloses_issues(self,**kwargs:Any)->RESTObjectList[ProjectIssue]:
236236
"""List issues that will close on merge."
237237
238238
Args:
@@ -257,7 +257,7 @@ def closes_issues(self, **kwargs: Any) -> RESTObjectList:
257257

258258
@cli.register_custom_action(cls_names="ProjectMergeRequest")
259259
@exc.on_http_error(exc.GitlabListError)
260-
defcommits(self,**kwargs:Any)->RESTObjectList:
260+
defcommits(self,**kwargs:Any)->RESTObjectList[ProjectCommit]:
261261
"""List the merge request commits.
262262
263263
Args:

‎gitlab/v4/objects/milestones.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
fromgitlabimportexceptionsasexc
55
fromgitlabimporttypes
66
fromgitlab.baseimportRESTObject,RESTObjectList
7+
fromgitlab.clientimportGitlabList
78
fromgitlab.mixinsimport (
89
CRUDMixin,
910
ObjectDeleteMixin,
@@ -16,6 +17,7 @@
1617
from .issuesimportGroupIssue,GroupIssueManager,ProjectIssue,ProjectIssueManager
1718
from .merge_requestsimport (
1819
GroupMergeRequest,
20+
GroupMergeRequestManager,
1921
ProjectMergeRequest,
2022
ProjectMergeRequestManager,
2123
)
@@ -33,7 +35,7 @@ class GroupMilestone(SaveMixin, ObjectDeleteMixin, RESTObject):
3335

3436
@cli.register_custom_action(cls_names="GroupMilestone")
3537
@exc.on_http_error(exc.GitlabListError)
36-
defissues(self,**kwargs:Any)->RESTObjectList:
38+
defissues(self,**kwargs:Any)->RESTObjectList[GroupIssue]:
3739
"""List issues related to this milestone.
3840
3941
Args:
@@ -53,14 +55,14 @@ def issues(self, **kwargs: Any) -> RESTObjectList:
5355
path=f"{self.manager.path}/{self.encoded_id}/issues"
5456
data_list=self.manager.gitlab.http_list(path,iterator=True,**kwargs)
5557
ifTYPE_CHECKING:
56-
assertisinstance(data_list,RESTObjectList)
58+
assertisinstance(data_list,GitlabList)
5759
manager=GroupIssueManager(self.manager.gitlab,parent=self.manager._parent)
5860
# FIXME(gpocentek): the computed manager path is not correct
5961
returnRESTObjectList(manager,GroupIssue,data_list)
6062

6163
@cli.register_custom_action(cls_names="GroupMilestone")
6264
@exc.on_http_error(exc.GitlabListError)
63-
defmerge_requests(self,**kwargs:Any)->RESTObjectList:
65+
defmerge_requests(self,**kwargs:Any)->RESTObjectList[GroupMergeRequest]:
6466
"""List the merge requests related to this milestone.
6567
6668
Args:
@@ -79,8 +81,10 @@ def merge_requests(self, **kwargs: Any) -> RESTObjectList:
7981
path=f"{self.manager.path}/{self.encoded_id}/merge_requests"
8082
data_list=self.manager.gitlab.http_list(path,iterator=True,**kwargs)
8183
ifTYPE_CHECKING:
82-
assertisinstance(data_list,RESTObjectList)
83-
manager=GroupIssueManager(self.manager.gitlab,parent=self.manager._parent)
84+
assertisinstance(data_list,GitlabList)
85+
manager=GroupMergeRequestManager(
86+
self.manager.gitlab,parent=self.manager._parent
87+
)
8488
# FIXME(gpocentek): the computed manager path is not correct
8589
returnRESTObjectList(manager,GroupMergeRequest,data_list)
8690

@@ -105,7 +109,7 @@ class ProjectMilestone(PromoteMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
105109

106110
@cli.register_custom_action(cls_names="ProjectMilestone")
107111
@exc.on_http_error(exc.GitlabListError)
108-
defissues(self,**kwargs:Any)->RESTObjectList:
112+
defissues(self,**kwargs:Any)->RESTObjectList[ProjectIssue]:
109113
"""List issues related to this milestone.
110114
111115
Args:
@@ -125,14 +129,14 @@ def issues(self, **kwargs: Any) -> RESTObjectList:
125129
path=f"{self.manager.path}/{self.encoded_id}/issues"
126130
data_list=self.manager.gitlab.http_list(path,iterator=True,**kwargs)
127131
ifTYPE_CHECKING:
128-
assertisinstance(data_list,RESTObjectList)
132+
assertisinstance(data_list,GitlabList)
129133
manager=ProjectIssueManager(self.manager.gitlab,parent=self.manager._parent)
130134
# FIXME(gpocentek): the computed manager path is not correct
131135
returnRESTObjectList(manager,ProjectIssue,data_list)
132136

133137
@cli.register_custom_action(cls_names="ProjectMilestone")
134138
@exc.on_http_error(exc.GitlabListError)
135-
defmerge_requests(self,**kwargs:Any)->RESTObjectList:
139+
defmerge_requests(self,**kwargs:Any)->RESTObjectList[ProjectMergeRequest]:
136140
"""List the merge requests related to this milestone.
137141
138142
Args:
@@ -151,7 +155,7 @@ def merge_requests(self, **kwargs: Any) -> RESTObjectList:
151155
path=f"{self.manager.path}/{self.encoded_id}/merge_requests"
152156
data_list=self.manager.gitlab.http_list(path,iterator=True,**kwargs)
153157
ifTYPE_CHECKING:
154-
assertisinstance(data_list,RESTObjectList)
158+
assertisinstance(data_list,GitlabList)
155159
manager=ProjectMergeRequestManager(
156160
self.manager.gitlab,parent=self.manager._parent
157161
)

‎gitlab/v4/objects/snippets.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class SnippetManager(CRUDMixin[Snippet]):
109109
)
110110

111111
@cli.register_custom_action(cls_names="SnippetManager")
112-
deflist_public(self,**kwargs:Any)->RESTObjectList|list[Snippet]:
112+
deflist_public(self,**kwargs:Any)->RESTObjectList[Snippet]|list[Snippet]:
113113
"""List all public snippets.
114114
115115
Args:
@@ -129,7 +129,7 @@ def list_public(self, **kwargs: Any) -> RESTObjectList | list[Snippet]:
129129
returnself.list(path="/snippets/public",**kwargs)
130130

131131
@cli.register_custom_action(cls_names="SnippetManager")
132-
deflist_all(self,**kwargs:Any)->RESTObjectList|list[Snippet]:
132+
deflist_all(self,**kwargs:Any)->RESTObjectList[Snippet]|list[Snippet]:
133133
"""List all snippets.
134134
135135
Args:
@@ -148,7 +148,7 @@ def list_all(self, **kwargs: Any) -> RESTObjectList | list[Snippet]:
148148
"""
149149
returnself.list(path="/snippets/all",**kwargs)
150150

151-
defpublic(self,**kwargs:Any)->RESTObjectList|list[Snippet]:
151+
defpublic(self,**kwargs:Any)->RESTObjectList[Snippet]|list[Snippet]:
152152
"""List all public snippets.
153153
154154
Args:

‎gitlab/v4/objects/users.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ class UserProjectManager(ListMixin[UserProject], CreateMixin[UserProject]):
623623
"id_before",
624624
)
625625

626-
deflist(self,**kwargs:Any)->RESTObjectList|list[UserProject]:
626+
deflist(self,**kwargs:Any)->RESTObjectList[UserProject]|list[UserProject]:
627627
"""Retrieve a list of objects.
628628
629629
Args:

‎tests/functional/conftest.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ def reset_gitlab(gl: gitlab.Gitlab) -> None:
8787
settings.save()
8888

8989
forprojectingl.projects.list():
90-
fordeploy_tokeninproject.deploytokens.list():
90+
forproject_deploy_tokeninproject.deploytokens.list():
9191
logging.info(
92-
f"Deleting deploy token:{deploy_token.username!r} in "
92+
f"Deleting deploy token:{project_deploy_token.username!r} in "
9393
f"project:{project.path_with_namespace!r}"
9494
)
95-
helpers.safe_delete(deploy_token)
95+
helpers.safe_delete(project_deploy_token)
9696
logging.info(f"Deleting project:{project.path_with_namespace!r}")
9797
helpers.safe_delete(project)
9898

@@ -106,12 +106,12 @@ def reset_gitlab(gl: gitlab.Gitlab) -> None:
106106
)
107107
continue
108108

109-
fordeploy_tokeningroup.deploytokens.list():
109+
forgroup_deploy_tokeningroup.deploytokens.list():
110110
logging.info(
111-
f"Deleting deploy token:{deploy_token.username!r} in "
111+
f"Deleting deploy token:{group_deploy_token.username!r} in "
112112
f"group:{group.path_with_namespace!r}"
113113
)
114-
helpers.safe_delete(deploy_token)
114+
helpers.safe_delete(group_deploy_token)
115115
logging.info(f"Deleting group:{group.full_path!r}")
116116
helpers.safe_delete(group)
117117
fortopicingl.topics.list():

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp