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,8 +1,10 @@
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
- from gitlab.base import RESTManager, RESTObject
5
- from gitlab.mixins import CreateMixin, CRUDMixin, ObjectDeleteMixin, SaveMixin
6
+ from gitlab.base import RESTObject
7
+ from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
6
8
  from gitlab.types import RequiredOptional
7
9
 
8
10
  __all__ = [
@@ -17,7 +19,7 @@ class GroupCluster(SaveMixin, ObjectDeleteMixin, RESTObject):
17
19
  pass
18
20
 
19
21
 
20
- class GroupClusterManager(CRUDMixin, RESTManager):
22
+ class GroupClusterManager(CRUDMixin[GroupCluster]):
21
23
  _path = "/groups/{group_id}/clusters"
22
24
  _obj_cls = GroupCluster
23
25
  _from_parent_attrs = {"group_id": "id"}
@@ -32,13 +34,11 @@ class GroupClusterManager(CRUDMixin, RESTManager):
32
34
  "management_project_id",
33
35
  "platform_kubernetes_attributes",
34
36
  "environment_scope",
35
- ),
37
+ )
36
38
  )
37
39
 
38
40
  @exc.on_http_error(exc.GitlabStopError)
39
- def create(
40
- self, data: Optional[Dict[str, Any]] = None, **kwargs: Any
41
- ) -> GroupCluster:
41
+ def create(self, data: dict[str, Any] | None = None, **kwargs: Any) -> GroupCluster:
42
42
  """Create a new object.
43
43
 
44
44
  Args:
@@ -56,19 +56,14 @@ class GroupClusterManager(CRUDMixin, RESTManager):
56
56
  the data sent by the server
57
57
  """
58
58
  path = f"{self.path}/user"
59
- return cast(GroupCluster, CreateMixin.create(self, data, path=path, **kwargs))
60
-
61
- def get(
62
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
63
- ) -> GroupCluster:
64
- return cast(GroupCluster, super().get(id=id, lazy=lazy, **kwargs))
59
+ return super().create(data, path=path, **kwargs)
65
60
 
66
61
 
67
62
  class ProjectCluster(SaveMixin, ObjectDeleteMixin, RESTObject):
68
63
  pass
69
64
 
70
65
 
71
- class ProjectClusterManager(CRUDMixin, RESTManager):
66
+ class ProjectClusterManager(CRUDMixin[ProjectCluster]):
72
67
  _path = "/projects/{project_id}/clusters"
73
68
  _obj_cls = ProjectCluster
74
69
  _from_parent_attrs = {"project_id": "id"}
@@ -83,12 +78,12 @@ class ProjectClusterManager(CRUDMixin, RESTManager):
83
78
  "management_project_id",
84
79
  "platform_kubernetes_attributes",
85
80
  "environment_scope",
86
- ),
81
+ )
87
82
  )
88
83
 
89
84
  @exc.on_http_error(exc.GitlabStopError)
90
85
  def create(
91
- self, data: Optional[Dict[str, Any]] = None, **kwargs: Any
86
+ self, data: dict[str, Any] | None = None, **kwargs: Any
92
87
  ) -> ProjectCluster:
93
88
  """Create a new object.
94
89
 
@@ -107,9 +102,4 @@ class ProjectClusterManager(CRUDMixin, RESTManager):
107
102
  the data sent by the server
108
103
  """
109
104
  path = f"{self.path}/user"
110
- return cast(ProjectCluster, CreateMixin.create(self, data, path=path, **kwargs))
111
-
112
- def get(
113
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
114
- ) -> ProjectCluster:
115
- return cast(ProjectCluster, super().get(id=id, lazy=lazy, **kwargs))
105
+ return super().create(data, path=path, **kwargs)
@@ -1,11 +1,13 @@
1
- from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING, Union
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, TYPE_CHECKING
2
4
 
3
5
  import requests
4
6
 
5
7
  import gitlab
6
8
  from gitlab import cli
7
9
  from gitlab import exceptions as exc
8
- from gitlab.base import RESTManager, RESTObject
10
+ from gitlab.base import RESTObject
9
11
  from gitlab.mixins import CreateMixin, ListMixin, RefreshMixin, RetrieveMixin
10
12
  from gitlab.types import RequiredOptional
11
13
 
@@ -24,13 +26,13 @@ __all__ = [
24
26
  class ProjectCommit(RESTObject):
25
27
  _repr_attr = "title"
26
28
 
27
- comments: "ProjectCommitCommentManager"
29
+ comments: ProjectCommitCommentManager
28
30
  discussions: ProjectCommitDiscussionManager
29
- statuses: "ProjectCommitStatusManager"
31
+ statuses: ProjectCommitStatusManager
30
32
 
31
33
  @cli.register_custom_action(cls_names="ProjectCommit")
32
34
  @exc.on_http_error(exc.GitlabGetError)
33
- def diff(self, **kwargs: Any) -> Union[gitlab.GitlabList, List[Dict[str, Any]]]:
35
+ def diff(self, **kwargs: Any) -> gitlab.GitlabList | list[dict[str, Any]]:
34
36
  """Generate the commit diff.
35
37
 
36
38
  Args:
@@ -50,7 +52,7 @@ class ProjectCommit(RESTObject):
50
52
  @exc.on_http_error(exc.GitlabCherryPickError)
51
53
  def cherry_pick(
52
54
  self, branch: str, **kwargs: Any
53
- ) -> Union[Dict[str, Any], requests.Response]:
55
+ ) -> dict[str, Any] | requests.Response:
54
56
  """Cherry-pick a commit into a branch.
55
57
 
56
58
  Args:
@@ -72,7 +74,7 @@ class ProjectCommit(RESTObject):
72
74
  @exc.on_http_error(exc.GitlabGetError)
73
75
  def refs(
74
76
  self, type: str = "all", **kwargs: Any
75
- ) -> Union[gitlab.GitlabList, List[Dict[str, Any]]]:
77
+ ) -> gitlab.GitlabList | list[dict[str, Any]]:
76
78
  """List the references the commit is pushed to.
77
79
 
78
80
  Args:
@@ -92,9 +94,7 @@ class ProjectCommit(RESTObject):
92
94
 
93
95
  @cli.register_custom_action(cls_names="ProjectCommit")
94
96
  @exc.on_http_error(exc.GitlabGetError)
95
- def merge_requests(
96
- self, **kwargs: Any
97
- ) -> Union[gitlab.GitlabList, List[Dict[str, Any]]]:
97
+ def merge_requests(self, **kwargs: Any) -> gitlab.GitlabList | list[dict[str, Any]]:
98
98
  """List the merge requests related to the commit.
99
99
 
100
100
  Args:
@@ -112,9 +112,7 @@ class ProjectCommit(RESTObject):
112
112
 
113
113
  @cli.register_custom_action(cls_names="ProjectCommit", required=("branch",))
114
114
  @exc.on_http_error(exc.GitlabRevertError)
115
- def revert(
116
- self, branch: str, **kwargs: Any
117
- ) -> Union[Dict[str, Any], requests.Response]:
115
+ def revert(self, branch: str, **kwargs: Any) -> dict[str, Any] | requests.Response:
118
116
  """Revert a commit on a given branch.
119
117
 
120
118
  Args:
@@ -134,7 +132,7 @@ class ProjectCommit(RESTObject):
134
132
 
135
133
  @cli.register_custom_action(cls_names="ProjectCommit")
136
134
  @exc.on_http_error(exc.GitlabGetError)
137
- def sequence(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
135
+ def sequence(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
138
136
  """Get the sequence number of the commit.
139
137
 
140
138
  Args:
@@ -152,7 +150,7 @@ class ProjectCommit(RESTObject):
152
150
 
153
151
  @cli.register_custom_action(cls_names="ProjectCommit")
154
152
  @exc.on_http_error(exc.GitlabGetError)
155
- def signature(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
153
+ def signature(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
156
154
  """Get the signature of the commit.
157
155
 
158
156
  Args:
@@ -169,7 +167,7 @@ class ProjectCommit(RESTObject):
169
167
  return self.manager.gitlab.http_get(path, **kwargs)
170
168
 
171
169
 
172
- class ProjectCommitManager(RetrieveMixin, CreateMixin, RESTManager):
170
+ class ProjectCommitManager(RetrieveMixin[ProjectCommit], CreateMixin[ProjectCommit]):
173
171
  _path = "/projects/{project_id}/repository/commits"
174
172
  _obj_cls = ProjectCommit
175
173
  _from_parent_attrs = {"project_id": "id"}
@@ -189,18 +187,15 @@ class ProjectCommitManager(RetrieveMixin, CreateMixin, RESTManager):
189
187
  "trailers",
190
188
  )
191
189
 
192
- def get(
193
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
194
- ) -> ProjectCommit:
195
- return cast(ProjectCommit, super().get(id=id, lazy=lazy, **kwargs))
196
-
197
190
 
198
191
  class ProjectCommitComment(RESTObject):
199
192
  _id_attr = None
200
193
  _repr_attr = "note"
201
194
 
202
195
 
203
- class ProjectCommitCommentManager(ListMixin, CreateMixin, RESTManager):
196
+ class ProjectCommitCommentManager(
197
+ ListMixin[ProjectCommitComment], CreateMixin[ProjectCommitComment]
198
+ ):
204
199
  _path = "/projects/{project_id}/repository/commits/{commit_id}/comments"
205
200
  _obj_cls = ProjectCommitComment
206
201
  _from_parent_attrs = {"project_id": "project_id", "commit_id": "id"}
@@ -213,7 +208,9 @@ class ProjectCommitStatus(RefreshMixin, RESTObject):
213
208
  pass
214
209
 
215
210
 
216
- class ProjectCommitStatusManager(ListMixin, CreateMixin, RESTManager):
211
+ class ProjectCommitStatusManager(
212
+ ListMixin[ProjectCommitStatus], CreateMixin[ProjectCommitStatus]
213
+ ):
217
214
  _path = "/projects/{project_id}/repository/commits/{commit_id}/statuses"
218
215
  _obj_cls = ProjectCommitStatus
219
216
  _from_parent_attrs = {"project_id": "project_id", "commit_id": "id"}
@@ -224,7 +221,7 @@ class ProjectCommitStatusManager(ListMixin, CreateMixin, RESTManager):
224
221
 
225
222
  @exc.on_http_error(exc.GitlabCreateError)
226
223
  def create(
227
- self, data: Optional[Dict[str, Any]] = None, **kwargs: Any
224
+ self, data: dict[str, Any] | None = None, **kwargs: Any
228
225
  ) -> ProjectCommitStatus:
229
226
  """Create a new object.
230
227
 
@@ -246,13 +243,11 @@ class ProjectCommitStatusManager(ListMixin, CreateMixin, RESTManager):
246
243
  # they are missing when using only the API
247
244
  # See #511
248
245
  base_path = "/projects/{project_id}/statuses/{commit_id}"
249
- path: Optional[str]
246
+ path: str | None
250
247
  if data is not None and "project_id" in data and "commit_id" in data:
251
248
  path = base_path.format(**data)
252
249
  else:
253
250
  path = self._compute_path(base_path)
254
251
  if TYPE_CHECKING:
255
252
  assert path is not None
256
- return cast(
257
- ProjectCommitStatus, CreateMixin.create(self, data, path=path, **kwargs)
258
- )
253
+ return super().create(data, path=path, **kwargs)
@@ -1,8 +1,10 @@
1
- from typing import Any, cast, TYPE_CHECKING, Union
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
2
4
 
3
5
  from gitlab import cli
4
6
  from gitlab import exceptions as exc
5
- from gitlab.base import RESTManager, RESTObject
7
+ from gitlab.base import RESTObject
6
8
  from gitlab.mixins import (
7
9
  DeleteMixin,
8
10
  GetMixin,
@@ -23,10 +25,12 @@ __all__ = [
23
25
 
24
26
 
25
27
  class ProjectRegistryRepository(ObjectDeleteMixin, RESTObject):
26
- tags: "ProjectRegistryTagManager"
28
+ tags: ProjectRegistryTagManager
27
29
 
28
30
 
29
- class ProjectRegistryRepositoryManager(DeleteMixin, ListMixin, RESTManager):
31
+ class ProjectRegistryRepositoryManager(
32
+ DeleteMixin[ProjectRegistryRepository], ListMixin[ProjectRegistryRepository]
33
+ ):
30
34
  _path = "/projects/{project_id}/registry/repositories"
31
35
  _obj_cls = ProjectRegistryRepository
32
36
  _from_parent_attrs = {"project_id": "id"}
@@ -36,7 +40,9 @@ class ProjectRegistryTag(ObjectDeleteMixin, RESTObject):
36
40
  _id_attr = "name"
37
41
 
38
42
 
39
- class ProjectRegistryTagManager(DeleteMixin, RetrieveMixin, RESTManager):
43
+ class ProjectRegistryTagManager(
44
+ DeleteMixin[ProjectRegistryTag], RetrieveMixin[ProjectRegistryTag]
45
+ ):
40
46
  _obj_cls = ProjectRegistryTag
41
47
  _from_parent_attrs = {"project_id": "project_id", "repository_id": "id"}
42
48
  _path = "/projects/{project_id}/registry/repositories/{repository_id}/tags"
@@ -66,17 +72,10 @@ class ProjectRegistryTagManager(DeleteMixin, RetrieveMixin, RESTManager):
66
72
  valid_attrs = ["keep_n", "name_regex_keep", "older_than"]
67
73
  data = {"name_regex_delete": name_regex_delete}
68
74
  data.update({k: v for k, v in kwargs.items() if k in valid_attrs})
69
- if TYPE_CHECKING:
70
- assert self.path is not None
71
75
  self.gitlab.http_delete(self.path, query_data=data, **kwargs)
72
76
 
73
- def get(
74
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
75
- ) -> ProjectRegistryTag:
76
- return cast(ProjectRegistryTag, super().get(id=id, lazy=lazy, **kwargs))
77
-
78
77
 
79
- class GroupRegistryRepositoryManager(ListMixin, RESTManager):
78
+ class GroupRegistryRepositoryManager(ListMixin[ProjectRegistryRepository]):
80
79
  _path = "/groups/{group_id}/registry/repositories"
81
80
  _obj_cls = ProjectRegistryRepository
82
81
  _from_parent_attrs = {"group_id": "id"}
@@ -86,11 +85,6 @@ class RegistryRepository(RESTObject):
86
85
  _repr_attr = "path"
87
86
 
88
87
 
89
- class RegistryRepositoryManager(GetMixin, RESTManager):
88
+ class RegistryRepositoryManager(GetMixin[RegistryRepository]):
90
89
  _path = "/registry/repositories"
91
90
  _obj_cls = RegistryRepository
92
-
93
- def get(
94
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
95
- ) -> RegistryRepository:
96
- return cast(RegistryRepository, super().get(id=id, lazy=lazy, **kwargs))
@@ -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 DeleteMixin, ObjectDeleteMixin, RetrieveMixin, SetMixin
5
3
 
6
4
  __all__ = [
@@ -17,42 +15,39 @@ class GroupCustomAttribute(ObjectDeleteMixin, RESTObject):
17
15
  _id_attr = "key"
18
16
 
19
17
 
20
- class GroupCustomAttributeManager(RetrieveMixin, SetMixin, DeleteMixin, RESTManager):
18
+ class GroupCustomAttributeManager(
19
+ RetrieveMixin[GroupCustomAttribute],
20
+ SetMixin[GroupCustomAttribute],
21
+ DeleteMixin[GroupCustomAttribute],
22
+ ):
21
23
  _path = "/groups/{group_id}/custom_attributes"
22
24
  _obj_cls = GroupCustomAttribute
23
25
  _from_parent_attrs = {"group_id": "id"}
24
26
 
25
- def get(
26
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
27
- ) -> GroupCustomAttribute:
28
- return cast(GroupCustomAttribute, super().get(id=id, lazy=lazy, **kwargs))
29
-
30
27
 
31
28
  class ProjectCustomAttribute(ObjectDeleteMixin, RESTObject):
32
29
  _id_attr = "key"
33
30
 
34
31
 
35
- class ProjectCustomAttributeManager(RetrieveMixin, SetMixin, DeleteMixin, RESTManager):
32
+ class ProjectCustomAttributeManager(
33
+ RetrieveMixin[ProjectCustomAttribute],
34
+ SetMixin[ProjectCustomAttribute],
35
+ DeleteMixin[ProjectCustomAttribute],
36
+ ):
36
37
  _path = "/projects/{project_id}/custom_attributes"
37
38
  _obj_cls = ProjectCustomAttribute
38
39
  _from_parent_attrs = {"project_id": "id"}
39
40
 
40
- def get(
41
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
42
- ) -> ProjectCustomAttribute:
43
- return cast(ProjectCustomAttribute, super().get(id=id, lazy=lazy, **kwargs))
44
-
45
41
 
46
42
  class UserCustomAttribute(ObjectDeleteMixin, RESTObject):
47
43
  _id_attr = "key"
48
44
 
49
45
 
50
- class UserCustomAttributeManager(RetrieveMixin, SetMixin, DeleteMixin, RESTManager):
46
+ class UserCustomAttributeManager(
47
+ RetrieveMixin[UserCustomAttribute],
48
+ SetMixin[UserCustomAttribute],
49
+ DeleteMixin[UserCustomAttribute],
50
+ ):
51
51
  _path = "/users/{user_id}/custom_attributes"
52
52
  _obj_cls = UserCustomAttribute
53
53
  _from_parent_attrs = {"user_id": "id"}
54
-
55
- def get(
56
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
57
- ) -> UserCustomAttribute:
58
- return cast(UserCustomAttribute, super().get(id=id, lazy=lazy, **kwargs))
@@ -1,40 +1,48 @@
1
- from typing import Any, cast, 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, RESTObject
8
- from gitlab.mixins import CRUDMixin, ListMixin, ObjectDeleteMixin, SaveMixin
9
+ from gitlab.base import RESTObject
10
+ from gitlab.mixins import (
11
+ CreateMixin,
12
+ CRUDMixin,
13
+ ListMixin,
14
+ ObjectDeleteMixin,
15
+ SaveMixin,
16
+ )
9
17
  from gitlab.types import RequiredOptional
10
18
 
11
- __all__ = [
12
- "DeployKey",
13
- "DeployKeyManager",
14
- "ProjectKey",
15
- "ProjectKeyManager",
16
- ]
19
+ __all__ = ["DeployKey", "DeployKeyManager", "ProjectKey", "ProjectKeyManager"]
17
20
 
18
21
 
19
22
  class DeployKey(RESTObject):
20
23
  pass
21
24
 
22
25
 
23
- class DeployKeyManager(ListMixin, RESTManager):
26
+ class DeployKeyManager(CreateMixin[DeployKey], ListMixin[DeployKey]):
24
27
  _path = "/deploy_keys"
25
28
  _obj_cls = DeployKey
29
+ _create_attrs = RequiredOptional(
30
+ required=("title", "key"), optional=("expires_at",)
31
+ )
26
32
 
27
33
 
28
34
  class ProjectKey(SaveMixin, ObjectDeleteMixin, RESTObject):
29
35
  pass
30
36
 
31
37
 
32
- class ProjectKeyManager(CRUDMixin, RESTManager):
38
+ class ProjectKeyManager(CRUDMixin[ProjectKey]):
33
39
  _path = "/projects/{project_id}/deploy_keys"
34
40
  _obj_cls = ProjectKey
35
41
  _from_parent_attrs = {"project_id": "id"}
36
- _create_attrs = RequiredOptional(required=("title", "key"), optional=("can_push",))
37
- _update_attrs = RequiredOptional(optional=("title", "can_push"))
42
+ _create_attrs = RequiredOptional(
43
+ required=("title", "key"), optional=("can_push", "expires_at")
44
+ )
45
+ _update_attrs = RequiredOptional(optional=("title", "can_push", "expires_at"))
38
46
 
39
47
  @cli.register_custom_action(
40
48
  cls_names="ProjectKeyManager",
@@ -43,9 +51,7 @@ class ProjectKeyManager(CRUDMixin, RESTManager):
43
51
  help="Enable a deploy key for the project",
44
52
  )
45
53
  @exc.on_http_error(exc.GitlabProjectDeployKeyError)
46
- def enable(
47
- self, key_id: int, **kwargs: Any
48
- ) -> Union[Dict[str, Any], requests.Response]:
54
+ def enable(self, key_id: int, **kwargs: Any) -> dict[str, Any] | requests.Response:
49
55
  """Enable a deploy key for a project.
50
56
 
51
57
  Args:
@@ -61,6 +67,3 @@ class ProjectKeyManager(CRUDMixin, RESTManager):
61
67
  """
62
68
  path = f"{self.path}/{key_id}/enable"
63
69
  return self.gitlab.http_post(path, **kwargs)
64
-
65
- def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> ProjectKey:
66
- return cast(ProjectKey, super().get(id=id, lazy=lazy, **kwargs))
@@ -1,7 +1,5 @@
1
- from typing import Any, cast, Union
2
-
3
1
  from gitlab import types
4
- from gitlab.base import RESTManager, RESTObject
2
+ from gitlab.base import RESTObject
5
3
  from gitlab.mixins import (
6
4
  CreateMixin,
7
5
  DeleteMixin,
@@ -25,7 +23,7 @@ class DeployToken(ObjectDeleteMixin, RESTObject):
25
23
  pass
26
24
 
27
25
 
28
- class DeployTokenManager(ListMixin, RESTManager):
26
+ class DeployTokenManager(ListMixin[DeployToken]):
29
27
  _path = "/deploy_tokens"
30
28
  _obj_cls = DeployToken
31
29
 
@@ -34,51 +32,35 @@ class GroupDeployToken(ObjectDeleteMixin, RESTObject):
34
32
  pass
35
33
 
36
34
 
37
- class GroupDeployTokenManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
35
+ class GroupDeployTokenManager(
36
+ RetrieveMixin[GroupDeployToken],
37
+ CreateMixin[GroupDeployToken],
38
+ DeleteMixin[GroupDeployToken],
39
+ ):
38
40
  _path = "/groups/{group_id}/deploy_tokens"
39
41
  _from_parent_attrs = {"group_id": "id"}
40
42
  _obj_cls = GroupDeployToken
41
43
  _create_attrs = RequiredOptional(
42
- required=(
43
- "name",
44
- "scopes",
45
- ),
46
- optional=(
47
- "expires_at",
48
- "username",
49
- ),
44
+ required=("name", "scopes"), optional=("expires_at", "username")
50
45
  )
51
46
  _list_filters = ("scopes",)
52
47
  _types = {"scopes": types.ArrayAttribute}
53
48
 
54
- def get(
55
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
56
- ) -> GroupDeployToken:
57
- return cast(GroupDeployToken, super().get(id=id, lazy=lazy, **kwargs))
58
-
59
49
 
60
50
  class ProjectDeployToken(ObjectDeleteMixin, RESTObject):
61
51
  pass
62
52
 
63
53
 
64
- class ProjectDeployTokenManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
54
+ class ProjectDeployTokenManager(
55
+ RetrieveMixin[ProjectDeployToken],
56
+ CreateMixin[ProjectDeployToken],
57
+ DeleteMixin[ProjectDeployToken],
58
+ ):
65
59
  _path = "/projects/{project_id}/deploy_tokens"
66
60
  _from_parent_attrs = {"project_id": "id"}
67
61
  _obj_cls = ProjectDeployToken
68
62
  _create_attrs = RequiredOptional(
69
- required=(
70
- "name",
71
- "scopes",
72
- ),
73
- optional=(
74
- "expires_at",
75
- "username",
76
- ),
63
+ required=("name", "scopes"), optional=("expires_at", "username")
77
64
  )
78
65
  _list_filters = ("scopes",)
79
66
  _types = {"scopes": types.ArrayAttribute}
80
-
81
- def get(
82
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
83
- ) -> ProjectDeployToken:
84
- return cast(ProjectDeployToken, super().get(id=id, lazy=lazy, **kwargs))
@@ -3,20 +3,19 @@ GitLab API:
3
3
  https://docs.gitlab.com/ee/api/deployments.html
4
4
  """
5
5
 
6
- from typing import Any, cast, Dict, Optional, TYPE_CHECKING, Union
6
+ from __future__ import annotations
7
+
8
+ from typing import Any, TYPE_CHECKING
7
9
 
8
10
  from gitlab import cli
9
11
  from gitlab import exceptions as exc
10
- from gitlab.base import RESTManager, RESTObject
12
+ from gitlab.base import RESTObject
11
13
  from gitlab.mixins import CreateMixin, RetrieveMixin, SaveMixin, UpdateMixin
12
14
  from gitlab.types import RequiredOptional
13
15
 
14
16
  from .merge_requests import ProjectDeploymentMergeRequestManager # noqa: F401
15
17
 
16
- __all__ = [
17
- "ProjectDeployment",
18
- "ProjectDeploymentManager",
19
- ]
18
+ __all__ = ["ProjectDeployment", "ProjectDeploymentManager"]
20
19
 
21
20
 
22
21
  class ProjectDeployment(SaveMixin, RESTObject):
@@ -31,10 +30,10 @@ class ProjectDeployment(SaveMixin, RESTObject):
31
30
  def approval(
32
31
  self,
33
32
  status: str,
34
- comment: Optional[str] = None,
35
- represented_as: Optional[str] = None,
33
+ comment: str | None = None,
34
+ represented_as: str | None = None,
36
35
  **kwargs: Any,
37
- ) -> Dict[str, Any]:
36
+ ) -> dict[str, Any]:
38
37
  """Approve or reject a blocked deployment.
39
38
 
40
39
  Args:
@@ -67,7 +66,11 @@ class ProjectDeployment(SaveMixin, RESTObject):
67
66
  return server_data
68
67
 
69
68
 
70
- class ProjectDeploymentManager(RetrieveMixin, CreateMixin, UpdateMixin, RESTManager):
69
+ class ProjectDeploymentManager(
70
+ RetrieveMixin[ProjectDeployment],
71
+ CreateMixin[ProjectDeployment],
72
+ UpdateMixin[ProjectDeployment],
73
+ ):
71
74
  _path = "/projects/{project_id}/deployments"
72
75
  _obj_cls = ProjectDeployment
73
76
  _from_parent_attrs = {"project_id": "id"}
@@ -82,8 +85,3 @@ class ProjectDeploymentManager(RetrieveMixin, CreateMixin, UpdateMixin, RESTMana
82
85
  _create_attrs = RequiredOptional(
83
86
  required=("sha", "ref", "tag", "status", "environment")
84
87
  )
85
-
86
- def get(
87
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
88
- ) -> ProjectDeployment:
89
- return cast(ProjectDeployment, super().get(id=id, lazy=lazy, **kwargs))
@@ -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 CreateMixin, RetrieveMixin, SaveMixin, UpdateMixin
5
3
  from gitlab.types import RequiredOptional
6
4
 
@@ -27,40 +25,36 @@ class ProjectCommitDiscussion(RESTObject):
27
25
  notes: ProjectCommitDiscussionNoteManager
28
26
 
29
27
 
30
- class ProjectCommitDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
28
+ class ProjectCommitDiscussionManager(
29
+ RetrieveMixin[ProjectCommitDiscussion], CreateMixin[ProjectCommitDiscussion]
30
+ ):
31
31
  _path = "/projects/{project_id}/repository/commits/{commit_id}/discussions"
32
32
  _obj_cls = ProjectCommitDiscussion
33
33
  _from_parent_attrs = {"project_id": "project_id", "commit_id": "id"}
34
34
  _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
35
35
 
36
- def get(
37
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
38
- ) -> ProjectCommitDiscussion:
39
- return cast(ProjectCommitDiscussion, super().get(id=id, lazy=lazy, **kwargs))
40
-
41
36
 
42
37
  class ProjectIssueDiscussion(RESTObject):
43
38
  notes: ProjectIssueDiscussionNoteManager
44
39
 
45
40
 
46
- class ProjectIssueDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
41
+ class ProjectIssueDiscussionManager(
42
+ RetrieveMixin[ProjectIssueDiscussion], CreateMixin[ProjectIssueDiscussion]
43
+ ):
47
44
  _path = "/projects/{project_id}/issues/{issue_iid}/discussions"
48
45
  _obj_cls = ProjectIssueDiscussion
49
46
  _from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
50
47
  _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
51
48
 
52
- def get(
53
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
54
- ) -> ProjectIssueDiscussion:
55
- return cast(ProjectIssueDiscussion, super().get(id=id, lazy=lazy, **kwargs))
56
-
57
49
 
58
50
  class ProjectMergeRequestDiscussion(SaveMixin, RESTObject):
59
51
  notes: ProjectMergeRequestDiscussionNoteManager
60
52
 
61
53
 
62
54
  class ProjectMergeRequestDiscussionManager(
63
- RetrieveMixin, CreateMixin, UpdateMixin, RESTManager
55
+ RetrieveMixin[ProjectMergeRequestDiscussion],
56
+ CreateMixin[ProjectMergeRequestDiscussion],
57
+ UpdateMixin[ProjectMergeRequestDiscussion],
64
58
  ):
65
59
  _path = "/projects/{project_id}/merge_requests/{mr_iid}/discussions"
66
60
  _obj_cls = ProjectMergeRequestDiscussion
@@ -70,25 +64,15 @@ class ProjectMergeRequestDiscussionManager(
70
64
  )
71
65
  _update_attrs = RequiredOptional(required=("resolved",))
72
66
 
73
- def get(
74
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
75
- ) -> ProjectMergeRequestDiscussion:
76
- return cast(
77
- ProjectMergeRequestDiscussion, super().get(id=id, lazy=lazy, **kwargs)
78
- )
79
-
80
67
 
81
68
  class ProjectSnippetDiscussion(RESTObject):
82
69
  notes: ProjectSnippetDiscussionNoteManager
83
70
 
84
71
 
85
- class ProjectSnippetDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
72
+ class ProjectSnippetDiscussionManager(
73
+ RetrieveMixin[ProjectSnippetDiscussion], CreateMixin[ProjectSnippetDiscussion]
74
+ ):
86
75
  _path = "/projects/{project_id}/snippets/{snippet_id}/discussions"
87
76
  _obj_cls = ProjectSnippetDiscussion
88
77
  _from_parent_attrs = {"project_id": "project_id", "snippet_id": "id"}
89
78
  _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
90
-
91
- def get(
92
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
93
- ) -> ProjectSnippetDiscussion:
94
- return cast(ProjectSnippetDiscussion, super().get(id=id, lazy=lazy, **kwargs))