python-gitlab 5.6.0__py3-none-any.whl → 6.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. gitlab/__init__.py +0 -1
  2. gitlab/_backends/protocol.py +9 -13
  3. gitlab/_backends/requests_backend.py +12 -12
  4. gitlab/_version.py +1 -1
  5. gitlab/base.py +48 -48
  6. gitlab/cli.py +15 -25
  7. gitlab/client.py +114 -140
  8. gitlab/config.py +16 -17
  9. gitlab/const.py +2 -0
  10. gitlab/exceptions.py +7 -5
  11. gitlab/mixins.py +154 -238
  12. gitlab/types.py +13 -14
  13. gitlab/utils.py +32 -43
  14. gitlab/v4/cli.py +51 -54
  15. gitlab/v4/objects/__init__.py +1 -0
  16. gitlab/v4/objects/access_requests.py +11 -3
  17. gitlab/v4/objects/appearance.py +12 -14
  18. gitlab/v4/objects/applications.py +5 -6
  19. gitlab/v4/objects/artifacts.py +10 -17
  20. gitlab/v4/objects/audit_events.py +4 -19
  21. gitlab/v4/objects/award_emojis.py +13 -57
  22. gitlab/v4/objects/badges.py +4 -19
  23. gitlab/v4/objects/boards.py +7 -27
  24. gitlab/v4/objects/branches.py +26 -14
  25. gitlab/v4/objects/broadcast_messages.py +3 -13
  26. gitlab/v4/objects/bulk_imports.py +6 -14
  27. gitlab/v4/objects/ci_lint.py +7 -13
  28. gitlab/v4/objects/cluster_agents.py +3 -13
  29. gitlab/v4/objects/clusters.py +13 -23
  30. gitlab/v4/objects/commits.py +23 -28
  31. gitlab/v4/objects/container_registry.py +13 -19
  32. gitlab/v4/objects/custom_attributes.py +16 -21
  33. gitlab/v4/objects/deploy_keys.py +22 -19
  34. gitlab/v4/objects/deploy_tokens.py +14 -32
  35. gitlab/v4/objects/deployments.py +13 -15
  36. gitlab/v4/objects/discussions.py +13 -29
  37. gitlab/v4/objects/draft_notes.py +4 -14
  38. gitlab/v4/objects/environments.py +13 -21
  39. gitlab/v4/objects/epics.py +14 -17
  40. gitlab/v4/objects/events.py +27 -79
  41. gitlab/v4/objects/export_import.py +7 -19
  42. gitlab/v4/objects/features.py +11 -12
  43. gitlab/v4/objects/files.py +23 -38
  44. gitlab/v4/objects/geo_nodes.py +7 -11
  45. gitlab/v4/objects/group_access_tokens.py +6 -13
  46. gitlab/v4/objects/groups.py +42 -37
  47. gitlab/v4/objects/hooks.py +4 -17
  48. gitlab/v4/objects/integrations.py +7 -18
  49. gitlab/v4/objects/invitations.py +12 -23
  50. gitlab/v4/objects/issues.py +21 -27
  51. gitlab/v4/objects/iterations.py +4 -8
  52. gitlab/v4/objects/job_token_scope.py +18 -14
  53. gitlab/v4/objects/jobs.py +17 -32
  54. gitlab/v4/objects/keys.py +8 -11
  55. gitlab/v4/objects/labels.py +19 -30
  56. gitlab/v4/objects/ldap.py +25 -9
  57. gitlab/v4/objects/member_roles.py +102 -0
  58. gitlab/v4/objects/members.py +11 -29
  59. gitlab/v4/objects/merge_request_approvals.py +31 -44
  60. gitlab/v4/objects/merge_requests.py +30 -40
  61. gitlab/v4/objects/merge_trains.py +3 -6
  62. gitlab/v4/objects/milestones.py +23 -29
  63. gitlab/v4/objects/namespaces.py +4 -10
  64. gitlab/v4/objects/notes.py +26 -69
  65. gitlab/v4/objects/notification_settings.py +5 -14
  66. gitlab/v4/objects/package_protection_rules.py +8 -8
  67. gitlab/v4/objects/packages.py +22 -37
  68. gitlab/v4/objects/pages.py +8 -14
  69. gitlab/v4/objects/personal_access_tokens.py +7 -10
  70. gitlab/v4/objects/pipelines.py +38 -47
  71. gitlab/v4/objects/project_access_tokens.py +6 -13
  72. gitlab/v4/objects/projects.py +63 -77
  73. gitlab/v4/objects/push_rules.py +13 -15
  74. gitlab/v4/objects/registry_protection_repository_rules.py +6 -7
  75. gitlab/v4/objects/registry_protection_rules.py +7 -11
  76. gitlab/v4/objects/releases.py +6 -20
  77. gitlab/v4/objects/repositories.py +25 -34
  78. gitlab/v4/objects/resource_groups.py +10 -15
  79. gitlab/v4/objects/reviewers.py +4 -2
  80. gitlab/v4/objects/runners.py +14 -13
  81. gitlab/v4/objects/secure_files.py +8 -21
  82. gitlab/v4/objects/service_accounts.py +7 -5
  83. gitlab/v4/objects/settings.py +13 -14
  84. gitlab/v4/objects/sidekiq.py +17 -18
  85. gitlab/v4/objects/snippets.py +78 -66
  86. gitlab/v4/objects/statistics.py +8 -23
  87. gitlab/v4/objects/status_checks.py +6 -3
  88. gitlab/v4/objects/tags.py +4 -13
  89. gitlab/v4/objects/templates.py +11 -59
  90. gitlab/v4/objects/todos.py +3 -6
  91. gitlab/v4/objects/topics.py +10 -21
  92. gitlab/v4/objects/triggers.py +3 -13
  93. gitlab/v4/objects/users.py +101 -93
  94. gitlab/v4/objects/variables.py +4 -19
  95. gitlab/v4/objects/wikis.py +4 -19
  96. {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info}/METADATA +3 -2
  97. python_gitlab-6.1.0.dist-info/RECORD +107 -0
  98. {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info}/WHEEL +1 -1
  99. python_gitlab-5.6.0.dist-info/RECORD +0 -106
  100. {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info}/entry_points.txt +0 -0
  101. {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info/licenses}/AUTHORS +0 -0
  102. {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info/licenses}/COPYING +0 -0
  103. {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info}/top_level.txt +0 -0
@@ -1,22 +1,23 @@
1
- from typing import Any, cast, Dict, Optional, Union
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
2
4
 
3
5
  from gitlab import exceptions as exc
4
6
  from gitlab import types
5
- from gitlab.base import RESTManager, RESTObject
7
+ from gitlab.base import RESTObject
6
8
  from gitlab.mixins import GetWithoutIdMixin, SaveMixin, UpdateMixin
7
9
  from gitlab.types import RequiredOptional
8
10
 
9
- __all__ = [
10
- "ApplicationSettings",
11
- "ApplicationSettingsManager",
12
- ]
11
+ __all__ = ["ApplicationSettings", "ApplicationSettingsManager"]
13
12
 
14
13
 
15
14
  class ApplicationSettings(SaveMixin, RESTObject):
16
15
  _id_attr = None
17
16
 
18
17
 
19
- class ApplicationSettingsManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
18
+ class ApplicationSettingsManager(
19
+ GetWithoutIdMixin[ApplicationSettings], UpdateMixin[ApplicationSettings]
20
+ ):
20
21
  _path = "/application/settings"
21
22
  _obj_cls = ApplicationSettings
22
23
  _update_attrs = RequiredOptional(
@@ -24,6 +25,7 @@ class ApplicationSettingsManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
24
25
  "id",
25
26
  "default_projects_limit",
26
27
  "signup_enabled",
28
+ "silent_mode_enabled",
27
29
  "password_authentication_enabled_for_web",
28
30
  "gravatar_enabled",
29
31
  "sign_in_text",
@@ -78,7 +80,7 @@ class ApplicationSettingsManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
78
80
  "allow_local_requests_from_hooks_and_services",
79
81
  "allow_local_requests_from_web_hooks_and_services",
80
82
  "allow_local_requests_from_system_hooks",
81
- ),
83
+ )
82
84
  )
83
85
  _types = {
84
86
  "asset_proxy_allowlist": types.ArrayAttribute,
@@ -92,10 +94,10 @@ class ApplicationSettingsManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
92
94
  @exc.on_http_error(exc.GitlabUpdateError)
93
95
  def update(
94
96
  self,
95
- id: Optional[Union[str, int]] = None,
96
- new_data: Optional[Dict[str, Any]] = None,
97
+ id: str | int | None = None,
98
+ new_data: dict[str, Any] | None = None,
97
99
  **kwargs: Any,
98
- ) -> Dict[str, Any]:
100
+ ) -> dict[str, Any]:
99
101
  """Update an object on the server.
100
102
 
101
103
  Args:
@@ -115,6 +117,3 @@ class ApplicationSettingsManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
115
117
  if "domain_whitelist" in data and data["domain_whitelist"] is None:
116
118
  data.pop("domain_whitelist")
117
119
  return super().update(id, data, **kwargs)
118
-
119
- def get(self, **kwargs: Any) -> ApplicationSettings:
120
- return cast(ApplicationSettings, super().get(**kwargs))
@@ -1,26 +1,29 @@
1
- from typing import Any, Dict, Union
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
2
4
 
3
5
  import requests
4
6
 
5
7
  from gitlab import cli
6
8
  from gitlab import exceptions as exc
7
- from gitlab.base import RESTManager
9
+ from gitlab.base import RESTManager, RESTObject
8
10
 
9
- __all__ = [
10
- "SidekiqManager",
11
- ]
11
+ __all__ = ["SidekiqManager"]
12
12
 
13
13
 
14
- class SidekiqManager(RESTManager):
14
+ class SidekiqManager(RESTManager[RESTObject]):
15
15
  """Manager for the Sidekiq methods.
16
16
 
17
17
  This manager doesn't actually manage objects but provides helper function
18
18
  for the sidekiq metrics API.
19
19
  """
20
20
 
21
+ _path = "/sidekiq"
22
+ _obj_cls = RESTObject
23
+
21
24
  @cli.register_custom_action(cls_names="SidekiqManager")
22
25
  @exc.on_http_error(exc.GitlabGetError)
23
- def queue_metrics(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
26
+ def queue_metrics(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
24
27
  """Return the registered queues information.
25
28
 
26
29
  Args:
@@ -33,13 +36,11 @@ class SidekiqManager(RESTManager):
33
36
  Returns:
34
37
  Information about the Sidekiq queues
35
38
  """
36
- return self.gitlab.http_get("/sidekiq/queue_metrics", **kwargs)
39
+ return self.gitlab.http_get(f"{self.path}/queue_metrics", **kwargs)
37
40
 
38
41
  @cli.register_custom_action(cls_names="SidekiqManager")
39
42
  @exc.on_http_error(exc.GitlabGetError)
40
- def process_metrics(
41
- self, **kwargs: Any
42
- ) -> Union[Dict[str, Any], requests.Response]:
43
+ def process_metrics(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
43
44
  """Return the registered sidekiq workers.
44
45
 
45
46
  Args:
@@ -52,11 +53,11 @@ class SidekiqManager(RESTManager):
52
53
  Returns:
53
54
  Information about the register Sidekiq worker
54
55
  """
55
- return self.gitlab.http_get("/sidekiq/process_metrics", **kwargs)
56
+ return self.gitlab.http_get(f"{self.path}/process_metrics", **kwargs)
56
57
 
57
58
  @cli.register_custom_action(cls_names="SidekiqManager")
58
59
  @exc.on_http_error(exc.GitlabGetError)
59
- def job_stats(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
60
+ def job_stats(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
60
61
  """Return statistics about the jobs performed.
61
62
 
62
63
  Args:
@@ -69,13 +70,11 @@ class SidekiqManager(RESTManager):
69
70
  Returns:
70
71
  Statistics about the Sidekiq jobs performed
71
72
  """
72
- return self.gitlab.http_get("/sidekiq/job_stats", **kwargs)
73
+ return self.gitlab.http_get(f"{self.path}/job_stats", **kwargs)
73
74
 
74
75
  @cli.register_custom_action(cls_names="SidekiqManager")
75
76
  @exc.on_http_error(exc.GitlabGetError)
76
- def compound_metrics(
77
- self, **kwargs: Any
78
- ) -> Union[Dict[str, Any], requests.Response]:
77
+ def compound_metrics(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
79
78
  """Return all available metrics and statistics.
80
79
 
81
80
  Args:
@@ -88,4 +87,4 @@ class SidekiqManager(RESTManager):
88
87
  Returns:
89
88
  All available Sidekiq metrics and statistics
90
89
  """
91
- return self.gitlab.http_get("/sidekiq/compound_metrics", **kwargs)
90
+ return self.gitlab.http_get(f"{self.path}/compound_metrics", **kwargs)
@@ -1,22 +1,13 @@
1
- from typing import (
2
- Any,
3
- Callable,
4
- cast,
5
- Iterator,
6
- List,
7
- Literal,
8
- Optional,
9
- overload,
10
- TYPE_CHECKING,
11
- Union,
12
- )
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Callable, Iterator, Literal, overload, TYPE_CHECKING
13
4
 
14
5
  import requests
15
6
 
16
7
  from gitlab import cli
17
8
  from gitlab import exceptions as exc
18
9
  from gitlab import utils
19
- from gitlab.base import RESTManager, RESTObject, RESTObjectList
10
+ from gitlab.base import RESTObject, RESTObjectList
20
11
  from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin, UserAgentDetailMixin
21
12
  from gitlab.types import RequiredOptional
22
13
 
@@ -24,12 +15,7 @@ from .award_emojis import ProjectSnippetAwardEmojiManager # noqa: F401
24
15
  from .discussions import ProjectSnippetDiscussionManager # noqa: F401
25
16
  from .notes import ProjectSnippetNoteManager # noqa: F401
26
17
 
27
- __all__ = [
28
- "Snippet",
29
- "SnippetManager",
30
- "ProjectSnippet",
31
- "ProjectSnippetManager",
32
- ]
18
+ __all__ = ["Snippet", "SnippetManager", "ProjectSnippet", "ProjectSnippetManager"]
33
19
 
34
20
 
35
21
  class Snippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -61,7 +47,7 @@ class Snippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
61
47
  def content(
62
48
  self,
63
49
  streamed: Literal[True] = True,
64
- action: Optional[Callable[[bytes], Any]] = None,
50
+ action: Callable[[bytes], Any] | None = None,
65
51
  chunk_size: int = 1024,
66
52
  *,
67
53
  iterator: Literal[False] = False,
@@ -73,12 +59,12 @@ class Snippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
73
59
  def content(
74
60
  self,
75
61
  streamed: bool = False,
76
- action: Optional[Callable[..., Any]] = None,
62
+ action: Callable[..., Any] | None = None,
77
63
  chunk_size: int = 1024,
78
64
  *,
79
65
  iterator: bool = False,
80
66
  **kwargs: Any,
81
- ) -> Optional[Union[bytes, Iterator[Any]]]:
67
+ ) -> bytes | Iterator[Any] | None:
82
68
  """Return the content of a snippet.
83
69
 
84
70
  Args:
@@ -110,31 +96,37 @@ class Snippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
110
96
  )
111
97
 
112
98
 
113
- class SnippetManager(CRUDMixin, RESTManager):
99
+ class SnippetManager(CRUDMixin[Snippet]):
114
100
  _path = "/snippets"
115
101
  _obj_cls = Snippet
116
102
  _create_attrs = RequiredOptional(
117
103
  required=("title",),
118
104
  exclusive=("files", "file_name"),
119
- optional=(
120
- "description",
121
- "content",
122
- "visibility",
123
- ),
105
+ optional=("description", "content", "visibility"),
124
106
  )
125
107
  _update_attrs = RequiredOptional(
126
- optional=(
127
- "title",
128
- "files",
129
- "file_name",
130
- "content",
131
- "visibility",
132
- "description",
133
- ),
108
+ optional=("title", "files", "file_name", "content", "visibility", "description")
134
109
  )
135
110
 
111
+ @overload
112
+ def list_public(
113
+ self, *, iterator: Literal[False] = False, **kwargs: Any
114
+ ) -> list[Snippet]: ...
115
+
116
+ @overload
117
+ def list_public(
118
+ self, *, iterator: Literal[True] = True, **kwargs: Any
119
+ ) -> RESTObjectList[Snippet]: ...
120
+
121
+ @overload
122
+ def list_public(
123
+ self, *, iterator: bool = False, **kwargs: Any
124
+ ) -> RESTObjectList[Snippet] | list[Snippet]: ...
125
+
136
126
  @cli.register_custom_action(cls_names="SnippetManager")
137
- def list_public(self, **kwargs: Any) -> Union[RESTObjectList, List[RESTObject]]:
127
+ def list_public(
128
+ self, *, iterator: bool = False, **kwargs: Any
129
+ ) -> RESTObjectList[Snippet] | list[Snippet]:
138
130
  """List all public snippets.
139
131
 
140
132
  Args:
@@ -151,10 +143,27 @@ class SnippetManager(CRUDMixin, RESTManager):
151
143
  Returns:
152
144
  The list of snippets, or a generator if `iterator` is True
153
145
  """
154
- return self.list(path="/snippets/public", **kwargs)
146
+ return self.list(path="/snippets/public", iterator=iterator, **kwargs)
147
+
148
+ @overload
149
+ def list_all(
150
+ self, *, iterator: Literal[False] = False, **kwargs: Any
151
+ ) -> list[Snippet]: ...
152
+
153
+ @overload
154
+ def list_all(
155
+ self, *, iterator: Literal[True] = True, **kwargs: Any
156
+ ) -> RESTObjectList[Snippet]: ...
157
+
158
+ @overload
159
+ def list_all(
160
+ self, *, iterator: bool = False, **kwargs: Any
161
+ ) -> RESTObjectList[Snippet] | list[Snippet]: ...
155
162
 
156
163
  @cli.register_custom_action(cls_names="SnippetManager")
157
- def list_all(self, **kwargs: Any) -> Union[RESTObjectList, List[RESTObject]]:
164
+ def list_all(
165
+ self, *, iterator: bool = False, **kwargs: Any
166
+ ) -> RESTObjectList[Snippet] | list[Snippet]:
158
167
  """List all snippets.
159
168
 
160
169
  Args:
@@ -171,9 +180,30 @@ class SnippetManager(CRUDMixin, RESTManager):
171
180
  Returns:
172
181
  A generator for the snippets list
173
182
  """
174
- return self.list(path="/snippets/all", **kwargs)
183
+ return self.list(path="/snippets/all", iterator=iterator, **kwargs)
175
184
 
176
- def public(self, **kwargs: Any) -> Union[RESTObjectList, List[RESTObject]]:
185
+ @overload
186
+ def public(
187
+ self,
188
+ *,
189
+ iterator: Literal[False] = False,
190
+ page: int | None = None,
191
+ **kwargs: Any,
192
+ ) -> list[Snippet]: ...
193
+
194
+ @overload
195
+ def public(
196
+ self, *, iterator: Literal[True] = True, **kwargs: Any
197
+ ) -> RESTObjectList[Snippet]: ...
198
+
199
+ @overload
200
+ def public(
201
+ self, *, iterator: bool = False, **kwargs: Any
202
+ ) -> RESTObjectList[Snippet] | list[Snippet]: ...
203
+
204
+ def public(
205
+ self, *, iterator: bool = False, **kwargs: Any
206
+ ) -> RESTObjectList[Snippet] | list[Snippet]:
177
207
  """List all public snippets.
178
208
 
179
209
  Args:
@@ -197,10 +227,7 @@ class SnippetManager(CRUDMixin, RESTManager):
197
227
  ),
198
228
  category=DeprecationWarning,
199
229
  )
200
- return self.list(path="/snippets/public", **kwargs)
201
-
202
- def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Snippet:
203
- return cast(Snippet, super().get(id=id, lazy=lazy, **kwargs))
230
+ return self.list(path="/snippets/public", iterator=iterator, **kwargs)
204
231
 
205
232
 
206
233
  class ProjectSnippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -237,7 +264,7 @@ class ProjectSnippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObj
237
264
  def content(
238
265
  self,
239
266
  streamed: Literal[True] = True,
240
- action: Optional[Callable[[bytes], Any]] = None,
267
+ action: Callable[[bytes], Any] | None = None,
241
268
  chunk_size: int = 1024,
242
269
  *,
243
270
  iterator: Literal[False] = False,
@@ -249,12 +276,12 @@ class ProjectSnippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObj
249
276
  def content(
250
277
  self,
251
278
  streamed: bool = False,
252
- action: Optional[Callable[..., Any]] = None,
279
+ action: Callable[..., Any] | None = None,
253
280
  chunk_size: int = 1024,
254
281
  *,
255
282
  iterator: bool = False,
256
283
  **kwargs: Any,
257
- ) -> Optional[Union[bytes, Iterator[Any]]]:
284
+ ) -> bytes | Iterator[Any] | None:
258
285
  """Return the content of a snippet.
259
286
 
260
287
  Args:
@@ -286,30 +313,15 @@ class ProjectSnippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObj
286
313
  )
287
314
 
288
315
 
289
- class ProjectSnippetManager(CRUDMixin, RESTManager):
316
+ class ProjectSnippetManager(CRUDMixin[ProjectSnippet]):
290
317
  _path = "/projects/{project_id}/snippets"
291
318
  _obj_cls = ProjectSnippet
292
319
  _from_parent_attrs = {"project_id": "id"}
293
320
  _create_attrs = RequiredOptional(
294
321
  required=("title", "visibility"),
295
322
  exclusive=("files", "file_name"),
296
- optional=(
297
- "description",
298
- "content",
299
- ),
323
+ optional=("description", "content"),
300
324
  )
301
325
  _update_attrs = RequiredOptional(
302
- optional=(
303
- "title",
304
- "files",
305
- "file_name",
306
- "content",
307
- "visibility",
308
- "description",
309
- ),
326
+ optional=("title", "files", "file_name", "content", "visibility", "description")
310
327
  )
311
-
312
- def get(
313
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
314
- ) -> ProjectSnippet:
315
- return cast(ProjectSnippet, super().get(id=id, lazy=lazy, **kwargs))
@@ -1,6 +1,4 @@
1
- from typing import Any, cast
2
-
3
- from gitlab.base import RESTManager, RESTObject
1
+ from gitlab.base import RESTObject
4
2
  from gitlab.mixins import GetWithoutIdMixin, RefreshMixin
5
3
  from gitlab.types import ArrayAttribute
6
4
 
@@ -22,66 +20,53 @@ class ProjectAdditionalStatistics(RefreshMixin, RESTObject):
22
20
  _id_attr = None
23
21
 
24
22
 
25
- class ProjectAdditionalStatisticsManager(GetWithoutIdMixin, RESTManager):
23
+ class ProjectAdditionalStatisticsManager(
24
+ GetWithoutIdMixin[ProjectAdditionalStatistics]
25
+ ):
26
26
  _path = "/projects/{project_id}/statistics"
27
27
  _obj_cls = ProjectAdditionalStatistics
28
28
  _from_parent_attrs = {"project_id": "id"}
29
29
 
30
- def get(self, **kwargs: Any) -> ProjectAdditionalStatistics:
31
- return cast(ProjectAdditionalStatistics, super().get(**kwargs))
32
-
33
30
 
34
31
  class IssuesStatistics(RefreshMixin, RESTObject):
35
32
  _id_attr = None
36
33
 
37
34
 
38
- class IssuesStatisticsManager(GetWithoutIdMixin, RESTManager):
35
+ class IssuesStatisticsManager(GetWithoutIdMixin[IssuesStatistics]):
39
36
  _path = "/issues_statistics"
40
37
  _obj_cls = IssuesStatistics
41
38
  _list_filters = ("iids",)
42
39
  _types = {"iids": ArrayAttribute}
43
40
 
44
- def get(self, **kwargs: Any) -> IssuesStatistics:
45
- return cast(IssuesStatistics, super().get(**kwargs))
46
-
47
41
 
48
42
  class GroupIssuesStatistics(RefreshMixin, RESTObject):
49
43
  _id_attr = None
50
44
 
51
45
 
52
- class GroupIssuesStatisticsManager(GetWithoutIdMixin, RESTManager):
46
+ class GroupIssuesStatisticsManager(GetWithoutIdMixin[GroupIssuesStatistics]):
53
47
  _path = "/groups/{group_id}/issues_statistics"
54
48
  _obj_cls = GroupIssuesStatistics
55
49
  _from_parent_attrs = {"group_id": "id"}
56
50
  _list_filters = ("iids",)
57
51
  _types = {"iids": ArrayAttribute}
58
52
 
59
- def get(self, **kwargs: Any) -> GroupIssuesStatistics:
60
- return cast(GroupIssuesStatistics, super().get(**kwargs))
61
-
62
53
 
63
54
  class ProjectIssuesStatistics(RefreshMixin, RESTObject):
64
55
  _id_attr = None
65
56
 
66
57
 
67
- class ProjectIssuesStatisticsManager(GetWithoutIdMixin, RESTManager):
58
+ class ProjectIssuesStatisticsManager(GetWithoutIdMixin[ProjectIssuesStatistics]):
68
59
  _path = "/projects/{project_id}/issues_statistics"
69
60
  _obj_cls = ProjectIssuesStatistics
70
61
  _from_parent_attrs = {"project_id": "id"}
71
62
  _list_filters = ("iids",)
72
63
  _types = {"iids": ArrayAttribute}
73
64
 
74
- def get(self, **kwargs: Any) -> ProjectIssuesStatistics:
75
- return cast(ProjectIssuesStatistics, super().get(**kwargs))
76
-
77
65
 
78
66
  class ApplicationStatistics(RESTObject):
79
67
  _id_attr = None
80
68
 
81
69
 
82
- class ApplicationStatisticsManager(GetWithoutIdMixin, RESTManager):
70
+ class ApplicationStatisticsManager(GetWithoutIdMixin[ApplicationStatistics]):
83
71
  _path = "/application/statistics"
84
72
  _obj_cls = ApplicationStatistics
85
-
86
- def get(self, **kwargs: Any) -> ApplicationStatistics:
87
- return cast(ApplicationStatistics, super().get(**kwargs))
@@ -1,4 +1,4 @@
1
- from gitlab.base import RESTManager, RESTObject
1
+ from gitlab.base import RESTObject
2
2
  from gitlab.mixins import (
3
3
  CreateMixin,
4
4
  DeleteMixin,
@@ -23,7 +23,10 @@ class ProjectExternalStatusCheck(SaveMixin, ObjectDeleteMixin, RESTObject):
23
23
 
24
24
 
25
25
  class ProjectExternalStatusCheckManager(
26
- ListMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager
26
+ ListMixin[ProjectExternalStatusCheck],
27
+ CreateMixin[ProjectExternalStatusCheck],
28
+ UpdateMixin[ProjectExternalStatusCheck],
29
+ DeleteMixin[ProjectExternalStatusCheck],
27
30
  ):
28
31
  _path = "/projects/{project_id}/external_status_checks"
29
32
  _obj_cls = ProjectExternalStatusCheck
@@ -42,7 +45,7 @@ class ProjectMergeRequestStatusCheck(SaveMixin, RESTObject):
42
45
  pass
43
46
 
44
47
 
45
- class ProjectMergeRequestStatusCheckManager(ListMixin, RESTManager):
48
+ class ProjectMergeRequestStatusCheckManager(ListMixin[ProjectMergeRequestStatusCheck]):
46
49
  _path = "/projects/{project_id}/merge_requests/{merge_request_iid}/status_checks"
47
50
  _obj_cls = ProjectMergeRequestStatusCheck
48
51
  _from_parent_attrs = {"project_id": "project_id", "merge_request_iid": "iid"}
gitlab/v4/objects/tags.py CHANGED
@@ -1,6 +1,4 @@
1
- from typing import Any, cast, Union
2
-
3
- from gitlab.base import RESTManager, RESTObject
1
+ from gitlab.base import RESTObject
4
2
  from gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin
5
3
  from gitlab.types import RequiredOptional
6
4
 
@@ -17,32 +15,25 @@ class ProjectTag(ObjectDeleteMixin, RESTObject):
17
15
  _repr_attr = "name"
18
16
 
19
17
 
20
- class ProjectTagManager(NoUpdateMixin, RESTManager):
18
+ class ProjectTagManager(NoUpdateMixin[ProjectTag]):
21
19
  _path = "/projects/{project_id}/repository/tags"
22
20
  _obj_cls = ProjectTag
23
21
  _from_parent_attrs = {"project_id": "id"}
22
+ _list_filters = ("order_by", "sort", "search")
24
23
  _create_attrs = RequiredOptional(
25
24
  required=("tag_name", "ref"), optional=("message",)
26
25
  )
27
26
 
28
- def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> ProjectTag:
29
- return cast(ProjectTag, super().get(id=id, lazy=lazy, **kwargs))
30
-
31
27
 
32
28
  class ProjectProtectedTag(ObjectDeleteMixin, RESTObject):
33
29
  _id_attr = "name"
34
30
  _repr_attr = "name"
35
31
 
36
32
 
37
- class ProjectProtectedTagManager(NoUpdateMixin, RESTManager):
33
+ class ProjectProtectedTagManager(NoUpdateMixin[ProjectProtectedTag]):
38
34
  _path = "/projects/{project_id}/protected_tags"
39
35
  _obj_cls = ProjectProtectedTag
40
36
  _from_parent_attrs = {"project_id": "id"}
41
37
  _create_attrs = RequiredOptional(
42
38
  required=("name",), optional=("create_access_level",)
43
39
  )
44
-
45
- def get(
46
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
47
- ) -> ProjectProtectedTag:
48
- return cast(ProjectProtectedTag, super().get(id=id, lazy=lazy, **kwargs))