python-gitlab 5.5.0__py3-none-any.whl → 6.0.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 (102) 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 +14 -24
  7. gitlab/client.py +114 -140
  8. gitlab/config.py +16 -17
  9. gitlab/exceptions.py +7 -5
  10. gitlab/mixins.py +154 -238
  11. gitlab/types.py +13 -14
  12. gitlab/utils.py +32 -43
  13. gitlab/v4/cli.py +50 -53
  14. gitlab/v4/objects/__init__.py +1 -0
  15. gitlab/v4/objects/access_requests.py +11 -3
  16. gitlab/v4/objects/appearance.py +12 -14
  17. gitlab/v4/objects/applications.py +5 -6
  18. gitlab/v4/objects/artifacts.py +10 -17
  19. gitlab/v4/objects/audit_events.py +4 -19
  20. gitlab/v4/objects/award_emojis.py +13 -57
  21. gitlab/v4/objects/badges.py +4 -19
  22. gitlab/v4/objects/boards.py +7 -27
  23. gitlab/v4/objects/branches.py +3 -15
  24. gitlab/v4/objects/broadcast_messages.py +3 -13
  25. gitlab/v4/objects/bulk_imports.py +6 -14
  26. gitlab/v4/objects/ci_lint.py +7 -13
  27. gitlab/v4/objects/cluster_agents.py +3 -13
  28. gitlab/v4/objects/clusters.py +13 -23
  29. gitlab/v4/objects/commits.py +23 -28
  30. gitlab/v4/objects/container_registry.py +13 -19
  31. gitlab/v4/objects/custom_attributes.py +16 -21
  32. gitlab/v4/objects/deploy_keys.py +22 -19
  33. gitlab/v4/objects/deploy_tokens.py +14 -32
  34. gitlab/v4/objects/deployments.py +13 -15
  35. gitlab/v4/objects/discussions.py +13 -29
  36. gitlab/v4/objects/draft_notes.py +4 -14
  37. gitlab/v4/objects/environments.py +13 -21
  38. gitlab/v4/objects/epics.py +14 -17
  39. gitlab/v4/objects/events.py +27 -79
  40. gitlab/v4/objects/export_import.py +7 -19
  41. gitlab/v4/objects/features.py +11 -12
  42. gitlab/v4/objects/files.py +23 -38
  43. gitlab/v4/objects/geo_nodes.py +7 -11
  44. gitlab/v4/objects/group_access_tokens.py +6 -13
  45. gitlab/v4/objects/groups.py +42 -37
  46. gitlab/v4/objects/hooks.py +4 -17
  47. gitlab/v4/objects/integrations.py +7 -18
  48. gitlab/v4/objects/invitations.py +12 -23
  49. gitlab/v4/objects/issues.py +21 -27
  50. gitlab/v4/objects/iterations.py +4 -8
  51. gitlab/v4/objects/job_token_scope.py +18 -14
  52. gitlab/v4/objects/jobs.py +17 -32
  53. gitlab/v4/objects/keys.py +8 -11
  54. gitlab/v4/objects/labels.py +19 -30
  55. gitlab/v4/objects/ldap.py +25 -9
  56. gitlab/v4/objects/member_roles.py +102 -0
  57. gitlab/v4/objects/members.py +11 -29
  58. gitlab/v4/objects/merge_request_approvals.py +47 -38
  59. gitlab/v4/objects/merge_requests.py +30 -40
  60. gitlab/v4/objects/merge_trains.py +3 -6
  61. gitlab/v4/objects/milestones.py +23 -29
  62. gitlab/v4/objects/namespaces.py +4 -10
  63. gitlab/v4/objects/notes.py +26 -69
  64. gitlab/v4/objects/notification_settings.py +5 -14
  65. gitlab/v4/objects/package_protection_rules.py +8 -8
  66. gitlab/v4/objects/packages.py +22 -37
  67. gitlab/v4/objects/pages.py +8 -14
  68. gitlab/v4/objects/personal_access_tokens.py +7 -10
  69. gitlab/v4/objects/pipelines.py +38 -47
  70. gitlab/v4/objects/project_access_tokens.py +6 -13
  71. gitlab/v4/objects/projects.py +54 -76
  72. gitlab/v4/objects/push_rules.py +13 -15
  73. gitlab/v4/objects/registry_protection_repository_rules.py +6 -7
  74. gitlab/v4/objects/registry_protection_rules.py +7 -11
  75. gitlab/v4/objects/releases.py +6 -20
  76. gitlab/v4/objects/repositories.py +25 -34
  77. gitlab/v4/objects/resource_groups.py +10 -15
  78. gitlab/v4/objects/reviewers.py +4 -2
  79. gitlab/v4/objects/runners.py +14 -13
  80. gitlab/v4/objects/secure_files.py +8 -21
  81. gitlab/v4/objects/service_accounts.py +7 -5
  82. gitlab/v4/objects/settings.py +13 -14
  83. gitlab/v4/objects/sidekiq.py +17 -18
  84. gitlab/v4/objects/snippets.py +78 -66
  85. gitlab/v4/objects/statistics.py +8 -23
  86. gitlab/v4/objects/status_checks.py +6 -3
  87. gitlab/v4/objects/tags.py +3 -13
  88. gitlab/v4/objects/templates.py +11 -59
  89. gitlab/v4/objects/todos.py +3 -6
  90. gitlab/v4/objects/topics.py +10 -21
  91. gitlab/v4/objects/triggers.py +3 -13
  92. gitlab/v4/objects/users.py +87 -93
  93. gitlab/v4/objects/variables.py +4 -19
  94. gitlab/v4/objects/wikis.py +4 -19
  95. {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info}/METADATA +3 -2
  96. python_gitlab-6.0.0.dist-info/RECORD +107 -0
  97. {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info}/WHEEL +1 -1
  98. python_gitlab-5.5.0.dist-info/RECORD +0 -106
  99. {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info}/entry_points.txt +0 -0
  100. {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info/licenses}/AUTHORS +0 -0
  101. {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info/licenses}/COPYING +0 -0
  102. {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,10 @@
1
- from typing import Any, cast, Union
1
+ from typing import Any
2
2
 
3
- from gitlab.base import RESTManager, RESTObject
3
+ from gitlab.base import RESTObject
4
4
  from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
5
5
  from gitlab.types import RequiredOptional
6
6
 
7
- __all__ = [
8
- "ProjectMergeRequestDraftNote",
9
- "ProjectMergeRequestDraftNoteManager",
10
- ]
7
+ __all__ = ["ProjectMergeRequestDraftNote", "ProjectMergeRequestDraftNoteManager"]
11
8
 
12
9
 
13
10
  class ProjectMergeRequestDraftNote(ObjectDeleteMixin, SaveMixin, RESTObject):
@@ -16,7 +13,7 @@ class ProjectMergeRequestDraftNote(ObjectDeleteMixin, SaveMixin, RESTObject):
16
13
  self.manager.gitlab.http_put(path, **kwargs)
17
14
 
18
15
 
19
- class ProjectMergeRequestDraftNoteManager(CRUDMixin, RESTManager):
16
+ class ProjectMergeRequestDraftNoteManager(CRUDMixin[ProjectMergeRequestDraftNote]):
20
17
  _path = "/projects/{project_id}/merge_requests/{mr_iid}/draft_notes"
21
18
  _obj_cls = ProjectMergeRequestDraftNote
22
19
  _from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
@@ -31,13 +28,6 @@ class ProjectMergeRequestDraftNoteManager(CRUDMixin, RESTManager):
31
28
  )
32
29
  _update_attrs = RequiredOptional(optional=("position",))
33
30
 
34
- def get(
35
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
36
- ) -> ProjectMergeRequestDraftNote:
37
- return cast(
38
- ProjectMergeRequestDraftNote, super().get(id=id, lazy=lazy, **kwargs)
39
- )
40
-
41
31
  def bulk_publish(self, **kwargs: Any) -> None:
42
32
  path = f"{self.path}/bulk_publish"
43
33
  self.gitlab.http_post(path, **kwargs)
@@ -1,10 +1,12 @@
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
9
+ from gitlab.base import RESTObject
8
10
  from gitlab.mixins import (
9
11
  CreateMixin,
10
12
  DeleteMixin,
@@ -26,7 +28,7 @@ __all__ = [
26
28
  class ProjectEnvironment(SaveMixin, ObjectDeleteMixin, RESTObject):
27
29
  @cli.register_custom_action(cls_names="ProjectEnvironment")
28
30
  @exc.on_http_error(exc.GitlabStopError)
29
- def stop(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
31
+ def stop(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
30
32
  """Stop the environment.
31
33
 
32
34
  Args:
@@ -44,7 +46,10 @@ class ProjectEnvironment(SaveMixin, ObjectDeleteMixin, RESTObject):
44
46
 
45
47
 
46
48
  class ProjectEnvironmentManager(
47
- RetrieveMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager
49
+ RetrieveMixin[ProjectEnvironment],
50
+ CreateMixin[ProjectEnvironment],
51
+ UpdateMixin[ProjectEnvironment],
52
+ DeleteMixin[ProjectEnvironment],
48
53
  ):
49
54
  _path = "/projects/{project_id}/environments"
50
55
  _obj_cls = ProjectEnvironment
@@ -53,11 +58,6 @@ class ProjectEnvironmentManager(
53
58
  _update_attrs = RequiredOptional(optional=("name", "external_url"))
54
59
  _list_filters = ("name", "search", "states")
55
60
 
56
- def get(
57
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
58
- ) -> ProjectEnvironment:
59
- return cast(ProjectEnvironment, super().get(id=id, lazy=lazy, **kwargs))
60
-
61
61
 
62
62
  class ProjectProtectedEnvironment(ObjectDeleteMixin, RESTObject):
63
63
  _id_attr = "name"
@@ -65,23 +65,15 @@ class ProjectProtectedEnvironment(ObjectDeleteMixin, RESTObject):
65
65
 
66
66
 
67
67
  class ProjectProtectedEnvironmentManager(
68
- RetrieveMixin, CreateMixin, DeleteMixin, RESTManager
68
+ RetrieveMixin[ProjectProtectedEnvironment],
69
+ CreateMixin[ProjectProtectedEnvironment],
70
+ DeleteMixin[ProjectProtectedEnvironment],
69
71
  ):
70
72
  _path = "/projects/{project_id}/protected_environments"
71
73
  _obj_cls = ProjectProtectedEnvironment
72
74
  _from_parent_attrs = {"project_id": "id"}
73
75
  _create_attrs = RequiredOptional(
74
- required=(
75
- "name",
76
- "deploy_access_levels",
77
- ),
76
+ required=("name", "deploy_access_levels"),
78
77
  optional=("required_approval_count", "approval_rules"),
79
78
  )
80
79
  _types = {"deploy_access_levels": ArrayAttribute, "approval_rules": ArrayAttribute}
81
-
82
- def get(
83
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
84
- ) -> ProjectProtectedEnvironment:
85
- return cast(
86
- ProjectProtectedEnvironment, super().get(id=id, lazy=lazy, **kwargs)
87
- )
@@ -1,8 +1,10 @@
1
- from typing import Any, cast, Dict, Optional, TYPE_CHECKING, Union
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, TYPE_CHECKING
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 (
7
9
  CreateMixin,
8
10
  CRUDMixin,
@@ -17,23 +19,18 @@ from gitlab.types import RequiredOptional
17
19
  from .events import GroupEpicResourceLabelEventManager # noqa: F401
18
20
  from .notes import GroupEpicNoteManager # noqa: F401
19
21
 
20
- __all__ = [
21
- "GroupEpic",
22
- "GroupEpicManager",
23
- "GroupEpicIssue",
24
- "GroupEpicIssueManager",
25
- ]
22
+ __all__ = ["GroupEpic", "GroupEpicManager", "GroupEpicIssue", "GroupEpicIssueManager"]
26
23
 
27
24
 
28
25
  class GroupEpic(ObjectDeleteMixin, SaveMixin, RESTObject):
29
26
  _id_attr = "iid"
30
27
 
31
- issues: "GroupEpicIssueManager"
28
+ issues: GroupEpicIssueManager
32
29
  resourcelabelevents: GroupEpicResourceLabelEventManager
33
30
  notes: GroupEpicNoteManager
34
31
 
35
32
 
36
- class GroupEpicManager(CRUDMixin, RESTManager):
33
+ class GroupEpicManager(CRUDMixin[GroupEpic]):
37
34
  _path = "/groups/{group_id}/epics"
38
35
  _obj_cls = GroupEpic
39
36
  _from_parent_attrs = {"group_id": "id"}
@@ -43,19 +40,16 @@ class GroupEpicManager(CRUDMixin, RESTManager):
43
40
  optional=("labels", "description", "start_date", "end_date"),
44
41
  )
45
42
  _update_attrs = RequiredOptional(
46
- optional=("title", "labels", "description", "start_date", "end_date"),
43
+ optional=("title", "labels", "description", "start_date", "end_date")
47
44
  )
48
45
  _types = {"labels": types.CommaSeparatedListAttribute}
49
46
 
50
- def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> GroupEpic:
51
- return cast(GroupEpic, super().get(id=id, lazy=lazy, **kwargs))
52
-
53
47
 
54
48
  class GroupEpicIssue(ObjectDeleteMixin, SaveMixin, RESTObject):
55
49
  _id_attr = "epic_issue_id"
56
50
  # Define type for 'manager' here So mypy won't complain about
57
51
  # 'self.manager.update()' call in the 'save' method.
58
- manager: "GroupEpicIssueManager"
52
+ manager: GroupEpicIssueManager
59
53
 
60
54
  def save(self, **kwargs: Any) -> None:
61
55
  """Save the changes made to the object to the server.
@@ -80,7 +74,10 @@ class GroupEpicIssue(ObjectDeleteMixin, SaveMixin, RESTObject):
80
74
 
81
75
 
82
76
  class GroupEpicIssueManager(
83
- ListMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager
77
+ ListMixin[GroupEpicIssue],
78
+ CreateMixin[GroupEpicIssue],
79
+ UpdateMixin[GroupEpicIssue],
80
+ DeleteMixin[GroupEpicIssue],
84
81
  ):
85
82
  _path = "/groups/{group_id}/epics/{epic_iid}/issues"
86
83
  _obj_cls = GroupEpicIssue
@@ -90,7 +87,7 @@ class GroupEpicIssueManager(
90
87
 
91
88
  @exc.on_http_error(exc.GitlabCreateError)
92
89
  def create(
93
- self, data: Optional[Dict[str, Any]] = None, **kwargs: Any
90
+ self, data: dict[str, Any] | None = None, **kwargs: Any
94
91
  ) -> GroupEpicIssue:
95
92
  """Create a new object.
96
93
 
@@ -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 ListMixin, RetrieveMixin
5
3
 
6
4
  __all__ = [
@@ -36,7 +34,7 @@ class Event(RESTObject):
36
34
  _repr_attr = "target_title"
37
35
 
38
36
 
39
- class EventManager(ListMixin, RESTManager):
37
+ class EventManager(ListMixin[Event]):
40
38
  _path = "/events"
41
39
  _obj_cls = Event
42
40
  _list_filters = ("action", "target_type", "before", "after", "sort", "scope")
@@ -46,18 +44,11 @@ class GroupEpicResourceLabelEvent(RESTObject):
46
44
  pass
47
45
 
48
46
 
49
- class GroupEpicResourceLabelEventManager(RetrieveMixin, RESTManager):
47
+ class GroupEpicResourceLabelEventManager(RetrieveMixin[GroupEpicResourceLabelEvent]):
50
48
  _path = "/groups/{group_id}/epics/{epic_id}/resource_label_events"
51
49
  _obj_cls = GroupEpicResourceLabelEvent
52
50
  _from_parent_attrs = {"group_id": "group_id", "epic_id": "id"}
53
51
 
54
- def get(
55
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
56
- ) -> GroupEpicResourceLabelEvent:
57
- return cast(
58
- GroupEpicResourceLabelEvent, super().get(id=id, lazy=lazy, **kwargs)
59
- )
60
-
61
52
 
62
53
  class ProjectEvent(Event):
63
54
  pass
@@ -73,140 +64,97 @@ class ProjectIssueResourceLabelEvent(RESTObject):
73
64
  pass
74
65
 
75
66
 
76
- class ProjectIssueResourceLabelEventManager(RetrieveMixin, RESTManager):
67
+ class ProjectIssueResourceLabelEventManager(
68
+ RetrieveMixin[ProjectIssueResourceLabelEvent]
69
+ ):
77
70
  _path = "/projects/{project_id}/issues/{issue_iid}/resource_label_events"
78
71
  _obj_cls = ProjectIssueResourceLabelEvent
79
72
  _from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
80
73
 
81
- def get(
82
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
83
- ) -> ProjectIssueResourceLabelEvent:
84
- return cast(
85
- ProjectIssueResourceLabelEvent, super().get(id=id, lazy=lazy, **kwargs)
86
- )
87
-
88
74
 
89
75
  class ProjectIssueResourceMilestoneEvent(RESTObject):
90
76
  pass
91
77
 
92
78
 
93
- class ProjectIssueResourceMilestoneEventManager(RetrieveMixin, RESTManager):
79
+ class ProjectIssueResourceMilestoneEventManager(
80
+ RetrieveMixin[ProjectIssueResourceMilestoneEvent]
81
+ ):
94
82
  _path = "/projects/{project_id}/issues/{issue_iid}/resource_milestone_events"
95
83
  _obj_cls = ProjectIssueResourceMilestoneEvent
96
84
  _from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
97
85
 
98
- def get(
99
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
100
- ) -> ProjectIssueResourceMilestoneEvent:
101
- return cast(
102
- ProjectIssueResourceMilestoneEvent, super().get(id=id, lazy=lazy, **kwargs)
103
- )
104
-
105
86
 
106
87
  class ProjectIssueResourceStateEvent(RESTObject):
107
88
  pass
108
89
 
109
90
 
110
- class ProjectIssueResourceStateEventManager(RetrieveMixin, RESTManager):
91
+ class ProjectIssueResourceStateEventManager(
92
+ RetrieveMixin[ProjectIssueResourceStateEvent]
93
+ ):
111
94
  _path = "/projects/{project_id}/issues/{issue_iid}/resource_state_events"
112
95
  _obj_cls = ProjectIssueResourceStateEvent
113
96
  _from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
114
97
 
115
- def get(
116
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
117
- ) -> ProjectIssueResourceStateEvent:
118
- return cast(
119
- ProjectIssueResourceStateEvent, super().get(id=id, lazy=lazy, **kwargs)
120
- )
121
-
122
98
 
123
99
  class ProjectIssueResourceIterationEvent(RESTObject):
124
100
  pass
125
101
 
126
102
 
127
- class ProjectIssueResourceIterationEventManager(RetrieveMixin, RESTManager):
103
+ class ProjectIssueResourceIterationEventManager(
104
+ RetrieveMixin[ProjectIssueResourceIterationEvent]
105
+ ):
128
106
  _path = "/projects/{project_id}/issues/{issue_iid}/resource_iteration_events"
129
107
  _obj_cls = ProjectIssueResourceIterationEvent
130
108
  _from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
131
109
 
132
- def get(
133
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
134
- ) -> ProjectIssueResourceIterationEvent:
135
- return cast(
136
- ProjectIssueResourceIterationEvent, super().get(id=id, lazy=lazy, **kwargs)
137
- )
138
-
139
110
 
140
111
  class ProjectIssueResourceWeightEvent(RESTObject):
141
112
  pass
142
113
 
143
114
 
144
- class ProjectIssueResourceWeightEventManager(RetrieveMixin, RESTManager):
115
+ class ProjectIssueResourceWeightEventManager(
116
+ RetrieveMixin[ProjectIssueResourceWeightEvent]
117
+ ):
145
118
  _path = "/projects/{project_id}/issues/{issue_iid}/resource_weight_events"
146
119
  _obj_cls = ProjectIssueResourceWeightEvent
147
120
  _from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
148
121
 
149
- def get(
150
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
151
- ) -> ProjectIssueResourceWeightEvent:
152
- return cast(
153
- ProjectIssueResourceWeightEvent, super().get(id=id, lazy=lazy, **kwargs)
154
- )
155
-
156
122
 
157
123
  class ProjectMergeRequestResourceLabelEvent(RESTObject):
158
124
  pass
159
125
 
160
126
 
161
- class ProjectMergeRequestResourceLabelEventManager(RetrieveMixin, RESTManager):
127
+ class ProjectMergeRequestResourceLabelEventManager(
128
+ RetrieveMixin[ProjectMergeRequestResourceLabelEvent]
129
+ ):
162
130
  _path = "/projects/{project_id}/merge_requests/{mr_iid}/resource_label_events"
163
131
  _obj_cls = ProjectMergeRequestResourceLabelEvent
164
132
  _from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
165
133
 
166
- def get(
167
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
168
- ) -> ProjectMergeRequestResourceLabelEvent:
169
- return cast(
170
- ProjectMergeRequestResourceLabelEvent,
171
- super().get(id=id, lazy=lazy, **kwargs),
172
- )
173
-
174
134
 
175
135
  class ProjectMergeRequestResourceMilestoneEvent(RESTObject):
176
136
  pass
177
137
 
178
138
 
179
- class ProjectMergeRequestResourceMilestoneEventManager(RetrieveMixin, RESTManager):
139
+ class ProjectMergeRequestResourceMilestoneEventManager(
140
+ RetrieveMixin[ProjectMergeRequestResourceMilestoneEvent]
141
+ ):
180
142
  _path = "/projects/{project_id}/merge_requests/{mr_iid}/resource_milestone_events"
181
143
  _obj_cls = ProjectMergeRequestResourceMilestoneEvent
182
144
  _from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
183
145
 
184
- def get(
185
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
186
- ) -> ProjectMergeRequestResourceMilestoneEvent:
187
- return cast(
188
- ProjectMergeRequestResourceMilestoneEvent,
189
- super().get(id=id, lazy=lazy, **kwargs),
190
- )
191
-
192
146
 
193
147
  class ProjectMergeRequestResourceStateEvent(RESTObject):
194
148
  pass
195
149
 
196
150
 
197
- class ProjectMergeRequestResourceStateEventManager(RetrieveMixin, RESTManager):
151
+ class ProjectMergeRequestResourceStateEventManager(
152
+ RetrieveMixin[ProjectMergeRequestResourceStateEvent]
153
+ ):
198
154
  _path = "/projects/{project_id}/merge_requests/{mr_iid}/resource_state_events"
199
155
  _obj_cls = ProjectMergeRequestResourceStateEvent
200
156
  _from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
201
157
 
202
- def get(
203
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
204
- ) -> ProjectMergeRequestResourceStateEvent:
205
- return cast(
206
- ProjectMergeRequestResourceStateEvent,
207
- super().get(id=id, lazy=lazy, **kwargs),
208
- )
209
-
210
158
 
211
159
  class UserEvent(Event):
212
160
  pass
@@ -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 CreateMixin, DownloadMixin, GetWithoutIdMixin, RefreshMixin
5
3
  from gitlab.types import RequiredOptional
6
4
 
@@ -20,50 +18,40 @@ class GroupExport(DownloadMixin, RESTObject):
20
18
  _id_attr = None
21
19
 
22
20
 
23
- class GroupExportManager(GetWithoutIdMixin, CreateMixin, RESTManager):
21
+ class GroupExportManager(GetWithoutIdMixin[GroupExport], CreateMixin[GroupExport]):
24
22
  _path = "/groups/{group_id}/export"
25
23
  _obj_cls = GroupExport
26
24
  _from_parent_attrs = {"group_id": "id"}
27
25
 
28
- def get(self, **kwargs: Any) -> GroupExport:
29
- return cast(GroupExport, super().get(**kwargs))
30
-
31
26
 
32
27
  class GroupImport(RESTObject):
33
28
  _id_attr = None
34
29
 
35
30
 
36
- class GroupImportManager(GetWithoutIdMixin, RESTManager):
31
+ class GroupImportManager(GetWithoutIdMixin[GroupImport]):
37
32
  _path = "/groups/{group_id}/import"
38
33
  _obj_cls = GroupImport
39
34
  _from_parent_attrs = {"group_id": "id"}
40
35
 
41
- def get(self, **kwargs: Any) -> GroupImport:
42
- return cast(GroupImport, super().get(**kwargs))
43
-
44
36
 
45
37
  class ProjectExport(DownloadMixin, RefreshMixin, RESTObject):
46
38
  _id_attr = None
47
39
 
48
40
 
49
- class ProjectExportManager(GetWithoutIdMixin, CreateMixin, RESTManager):
41
+ class ProjectExportManager(
42
+ GetWithoutIdMixin[ProjectExport], CreateMixin[ProjectExport]
43
+ ):
50
44
  _path = "/projects/{project_id}/export"
51
45
  _obj_cls = ProjectExport
52
46
  _from_parent_attrs = {"project_id": "id"}
53
47
  _create_attrs = RequiredOptional(optional=("description",))
54
48
 
55
- def get(self, **kwargs: Any) -> ProjectExport:
56
- return cast(ProjectExport, super().get(**kwargs))
57
-
58
49
 
59
50
  class ProjectImport(RefreshMixin, RESTObject):
60
51
  _id_attr = None
61
52
 
62
53
 
63
- class ProjectImportManager(GetWithoutIdMixin, RESTManager):
54
+ class ProjectImportManager(GetWithoutIdMixin[ProjectImport]):
64
55
  _path = "/projects/{project_id}/import"
65
56
  _obj_cls = ProjectImport
66
57
  _from_parent_attrs = {"project_id": "id"}
67
-
68
- def get(self, **kwargs: Any) -> ProjectImport:
69
- return cast(ProjectImport, super().get(**kwargs))
@@ -3,24 +3,23 @@ GitLab API:
3
3
  https://docs.gitlab.com/ee/api/features.html
4
4
  """
5
5
 
6
- from typing import Any, Optional, TYPE_CHECKING, Union
6
+ from __future__ import annotations
7
+
8
+ from typing import Any, TYPE_CHECKING
7
9
 
8
10
  from gitlab import exceptions as exc
9
11
  from gitlab import utils
10
- from gitlab.base import RESTManager, RESTObject
12
+ from gitlab.base import RESTObject
11
13
  from gitlab.mixins import DeleteMixin, ListMixin, ObjectDeleteMixin
12
14
 
13
- __all__ = [
14
- "Feature",
15
- "FeatureManager",
16
- ]
15
+ __all__ = ["Feature", "FeatureManager"]
17
16
 
18
17
 
19
18
  class Feature(ObjectDeleteMixin, RESTObject):
20
19
  _id_attr = "name"
21
20
 
22
21
 
23
- class FeatureManager(ListMixin, DeleteMixin, RESTManager):
22
+ class FeatureManager(ListMixin[Feature], DeleteMixin[Feature]):
24
23
  _path = "/features/"
25
24
  _obj_cls = Feature
26
25
 
@@ -28,11 +27,11 @@ class FeatureManager(ListMixin, DeleteMixin, RESTManager):
28
27
  def set(
29
28
  self,
30
29
  name: str,
31
- value: Union[bool, int],
32
- feature_group: Optional[str] = None,
33
- user: Optional[str] = None,
34
- group: Optional[str] = None,
35
- project: Optional[str] = None,
30
+ value: bool | int,
31
+ feature_group: str | None = None,
32
+ user: str | None = None,
33
+ group: str | None = None,
34
+ project: str | None = None,
36
35
  **kwargs: Any,
37
36
  ) -> Feature:
38
37
  """Create or update the object.
@@ -1,24 +1,14 @@
1
+ from __future__ import annotations
2
+
1
3
  import base64
2
- from typing import (
3
- Any,
4
- Callable,
5
- Dict,
6
- Iterator,
7
- List,
8
- Literal,
9
- Optional,
10
- overload,
11
- Tuple,
12
- TYPE_CHECKING,
13
- Union,
14
- )
4
+ from typing import Any, Callable, Iterator, Literal, overload, TYPE_CHECKING
15
5
 
16
6
  import requests
17
7
 
18
8
  from gitlab import cli
19
9
  from gitlab import exceptions as exc
20
10
  from gitlab import utils
21
- from gitlab.base import RESTManager, RESTObject
11
+ from gitlab.base import RESTObject
22
12
  from gitlab.mixins import (
23
13
  CreateMixin,
24
14
  DeleteMixin,
@@ -28,10 +18,7 @@ from gitlab.mixins import (
28
18
  )
29
19
  from gitlab.types import RequiredOptional
30
20
 
31
- __all__ = [
32
- "ProjectFile",
33
- "ProjectFileManager",
34
- ]
21
+ __all__ = ["ProjectFile", "ProjectFileManager"]
35
22
 
36
23
 
37
24
  class ProjectFile(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -40,7 +27,7 @@ class ProjectFile(SaveMixin, ObjectDeleteMixin, RESTObject):
40
27
  branch: str
41
28
  commit_message: str
42
29
  file_path: str
43
- manager: "ProjectFileManager"
30
+ manager: ProjectFileManager
44
31
  content: str # since the `decode()` method uses `self.content`
45
32
 
46
33
  def decode(self) -> bytes:
@@ -97,11 +84,13 @@ class ProjectFile(SaveMixin, ObjectDeleteMixin, RESTObject):
97
84
  self.manager.delete(file_path, branch, commit_message, **kwargs)
98
85
 
99
86
 
100
- class ProjectFileManager(CreateMixin, UpdateMixin, DeleteMixin, RESTManager):
87
+ class ProjectFileManager(
88
+ CreateMixin[ProjectFile], UpdateMixin[ProjectFile], DeleteMixin[ProjectFile]
89
+ ):
101
90
  _path = "/projects/{project_id}/repository/files"
102
91
  _obj_cls = ProjectFile
103
92
  _from_parent_attrs = {"project_id": "id"}
104
- _optional_get_attrs: Tuple[str, ...] = ()
93
+ _optional_get_attrs: tuple[str, ...] = ()
105
94
  _create_attrs = RequiredOptional(
106
95
  required=("file_path", "branch", "content", "commit_message"),
107
96
  optional=(
@@ -155,7 +144,7 @@ class ProjectFileManager(CreateMixin, UpdateMixin, DeleteMixin, RESTManager):
155
144
  @exc.on_http_error(exc.GitlabHeadError)
156
145
  def head(
157
146
  self, file_path: str, ref: str, **kwargs: Any
158
- ) -> "requests.structures.CaseInsensitiveDict[Any]":
147
+ ) -> requests.structures.CaseInsensitiveDict[Any]:
159
148
  """Retrieve just metadata for a single file.
160
149
 
161
150
  Args:
@@ -188,9 +177,7 @@ class ProjectFileManager(CreateMixin, UpdateMixin, DeleteMixin, RESTManager):
188
177
  ),
189
178
  )
190
179
  @exc.on_http_error(exc.GitlabCreateError)
191
- def create(
192
- self, data: Optional[Dict[str, Any]] = None, **kwargs: Any
193
- ) -> ProjectFile:
180
+ def create(self, data: dict[str, Any] | None = None, **kwargs: Any) -> ProjectFile:
194
181
  """Create a new object.
195
182
 
196
183
  Args:
@@ -222,8 +209,8 @@ class ProjectFileManager(CreateMixin, UpdateMixin, DeleteMixin, RESTManager):
222
209
  # NOTE(jlvillal): Signature doesn't match UpdateMixin.update() so ignore
223
210
  # type error
224
211
  def update( # type: ignore[override]
225
- self, file_path: str, new_data: Optional[Dict[str, Any]] = None, **kwargs: Any
226
- ) -> Dict[str, Any]:
212
+ self, file_path: str, new_data: dict[str, Any] | None = None, **kwargs: Any
213
+ ) -> dict[str, Any]:
227
214
  """Update an object on the server.
228
215
 
229
216
  Args:
@@ -280,7 +267,7 @@ class ProjectFileManager(CreateMixin, UpdateMixin, DeleteMixin, RESTManager):
280
267
  def raw(
281
268
  self,
282
269
  file_path: str,
283
- ref: Optional[str] = None,
270
+ ref: str | None = None,
284
271
  streamed: Literal[False] = False,
285
272
  action: None = None,
286
273
  chunk_size: int = 1024,
@@ -293,7 +280,7 @@ class ProjectFileManager(CreateMixin, UpdateMixin, DeleteMixin, RESTManager):
293
280
  def raw(
294
281
  self,
295
282
  file_path: str,
296
- ref: Optional[str] = None,
283
+ ref: str | None = None,
297
284
  streamed: bool = False,
298
285
  action: None = None,
299
286
  chunk_size: int = 1024,
@@ -306,9 +293,9 @@ class ProjectFileManager(CreateMixin, UpdateMixin, DeleteMixin, RESTManager):
306
293
  def raw(
307
294
  self,
308
295
  file_path: str,
309
- ref: Optional[str] = None,
296
+ ref: str | None = None,
310
297
  streamed: Literal[True] = True,
311
- action: Optional[Callable[[bytes], Any]] = None,
298
+ action: Callable[[bytes], Any] | None = None,
312
299
  chunk_size: int = 1024,
313
300
  *,
314
301
  iterator: Literal[False] = False,
@@ -316,22 +303,20 @@ class ProjectFileManager(CreateMixin, UpdateMixin, DeleteMixin, RESTManager):
316
303
  ) -> None: ...
317
304
 
318
305
  @cli.register_custom_action(
319
- cls_names="ProjectFileManager",
320
- required=("file_path",),
321
- optional=("ref",),
306
+ cls_names="ProjectFileManager", required=("file_path",), optional=("ref",)
322
307
  )
323
308
  @exc.on_http_error(exc.GitlabGetError)
324
309
  def raw(
325
310
  self,
326
311
  file_path: str,
327
- ref: Optional[str] = None,
312
+ ref: str | None = None,
328
313
  streamed: bool = False,
329
- action: Optional[Callable[..., Any]] = None,
314
+ action: Callable[..., Any] | None = None,
330
315
  chunk_size: int = 1024,
331
316
  *,
332
317
  iterator: bool = False,
333
318
  **kwargs: Any,
334
- ) -> Optional[Union[bytes, Iterator[Any]]]:
319
+ ) -> bytes | Iterator[Any] | None:
335
320
  """Return the content of a file for a commit.
336
321
 
337
322
  Args:
@@ -373,7 +358,7 @@ class ProjectFileManager(CreateMixin, UpdateMixin, DeleteMixin, RESTManager):
373
358
  cls_names="ProjectFileManager", required=("file_path", "ref")
374
359
  )
375
360
  @exc.on_http_error(exc.GitlabListError)
376
- def blame(self, file_path: str, ref: str, **kwargs: Any) -> List[Dict[str, Any]]:
361
+ def blame(self, file_path: str, ref: str, **kwargs: Any) -> list[dict[str, Any]]:
377
362
  """Return the content of a file for a commit.
378
363
 
379
364
  Args: