python-gitlab 5.6.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 +40 -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 +31 -44
  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.6.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.6.0.dist-info → python_gitlab-6.0.0.dist-info}/WHEEL +1 -1
  98. python_gitlab-5.6.0.dist-info/RECORD +0 -106
  99. {python_gitlab-5.6.0.dist-info → python_gitlab-6.0.0.dist-info}/entry_points.txt +0 -0
  100. {python_gitlab-5.6.0.dist-info → python_gitlab-6.0.0.dist-info/licenses}/AUTHORS +0 -0
  101. {python_gitlab-5.6.0.dist-info → python_gitlab-6.0.0.dist-info/licenses}/COPYING +0 -0
  102. {python_gitlab-5.6.0.dist-info → python_gitlab-6.0.0.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,12 @@
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
  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
  CRUDMixin,
@@ -47,22 +49,24 @@ class ProjectMergeRequestPipeline(RESTObject):
47
49
  pass
48
50
 
49
51
 
50
- class ProjectMergeRequestPipelineManager(CreateMixin, ListMixin, RESTManager):
52
+ class ProjectMergeRequestPipelineManager(
53
+ CreateMixin[ProjectMergeRequestPipeline], ListMixin[ProjectMergeRequestPipeline]
54
+ ):
51
55
  _path = "/projects/{project_id}/merge_requests/{mr_iid}/pipelines"
52
56
  _obj_cls = ProjectMergeRequestPipeline
53
57
  _from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
54
58
 
55
59
 
56
60
  class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
57
- bridges: "ProjectPipelineBridgeManager"
58
- jobs: "ProjectPipelineJobManager"
59
- test_report: "ProjectPipelineTestReportManager"
60
- test_report_summary: "ProjectPipelineTestReportSummaryManager"
61
- variables: "ProjectPipelineVariableManager"
61
+ bridges: ProjectPipelineBridgeManager
62
+ jobs: ProjectPipelineJobManager
63
+ test_report: ProjectPipelineTestReportManager
64
+ test_report_summary: ProjectPipelineTestReportSummaryManager
65
+ variables: ProjectPipelineVariableManager
62
66
 
63
67
  @cli.register_custom_action(cls_names="ProjectPipeline")
64
68
  @exc.on_http_error(exc.GitlabPipelineCancelError)
65
- def cancel(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
69
+ def cancel(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
66
70
  """Cancel the job.
67
71
 
68
72
  Args:
@@ -77,7 +81,7 @@ class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
77
81
 
78
82
  @cli.register_custom_action(cls_names="ProjectPipeline")
79
83
  @exc.on_http_error(exc.GitlabPipelineRetryError)
80
- def retry(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
84
+ def retry(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
81
85
  """Retry the job.
82
86
 
83
87
  Args:
@@ -91,7 +95,11 @@ class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
91
95
  return self.manager.gitlab.http_post(path, **kwargs)
92
96
 
93
97
 
94
- class ProjectPipelineManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
98
+ class ProjectPipelineManager(
99
+ RetrieveMixin[ProjectPipeline],
100
+ CreateMixin[ProjectPipeline],
101
+ DeleteMixin[ProjectPipeline],
102
+ ):
95
103
  _path = "/projects/{project_id}/pipelines"
96
104
  _obj_cls = ProjectPipeline
97
105
  _from_parent_attrs = {"project_id": "id"}
@@ -109,13 +117,8 @@ class ProjectPipelineManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManage
109
117
  )
110
118
  _create_attrs = RequiredOptional(required=("ref",))
111
119
 
112
- def get(
113
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
114
- ) -> ProjectPipeline:
115
- return cast(ProjectPipeline, super().get(id=id, lazy=lazy, **kwargs))
116
-
117
120
  def create(
118
- self, data: Optional[Dict[str, Any]] = None, **kwargs: Any
121
+ self, data: dict[str, Any] | None = None, **kwargs: Any
119
122
  ) -> ProjectPipeline:
120
123
  """Creates a new object.
121
124
 
@@ -132,14 +135,10 @@ class ProjectPipelineManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManage
132
135
  A new instance of the managed object class build with
133
136
  the data sent by the server
134
137
  """
135
- if TYPE_CHECKING:
136
- assert self.path is not None
137
138
  path = self.path[:-1] # drop the 's'
138
- return cast(
139
- ProjectPipeline, CreateMixin.create(self, data, path=path, **kwargs)
140
- )
139
+ return super().create(data, path=path, **kwargs)
141
140
 
142
- def latest(self, ref: Optional[str] = None, lazy: bool = False) -> ProjectPipeline:
141
+ def latest(self, ref: str | None = None, lazy: bool = False) -> ProjectPipeline:
143
142
  """Get the latest pipeline for the most recent commit
144
143
  on a specific ref in a project
145
144
 
@@ -152,9 +151,6 @@ class ProjectPipelineManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManage
152
151
  data = {}
153
152
  if ref:
154
153
  data = {"ref": ref}
155
- if TYPE_CHECKING:
156
- assert self._obj_cls is not None
157
- assert self.path is not None
158
154
  server_data = self.gitlab.http_get(self.path + "/latest", query_data=data)
159
155
  if TYPE_CHECKING:
160
156
  assert not isinstance(server_data, requests.Response)
@@ -165,7 +161,7 @@ class ProjectPipelineJob(RESTObject):
165
161
  pass
166
162
 
167
163
 
168
- class ProjectPipelineJobManager(ListMixin, RESTManager):
164
+ class ProjectPipelineJobManager(ListMixin[ProjectPipelineJob]):
169
165
  _path = "/projects/{project_id}/pipelines/{pipeline_id}/jobs"
170
166
  _obj_cls = ProjectPipelineJob
171
167
  _from_parent_attrs = {"project_id": "project_id", "pipeline_id": "id"}
@@ -177,7 +173,7 @@ class ProjectPipelineBridge(RESTObject):
177
173
  pass
178
174
 
179
175
 
180
- class ProjectPipelineBridgeManager(ListMixin, RESTManager):
176
+ class ProjectPipelineBridgeManager(ListMixin[ProjectPipelineBridge]):
181
177
  _path = "/projects/{project_id}/pipelines/{pipeline_id}/bridges"
182
178
  _obj_cls = ProjectPipelineBridge
183
179
  _from_parent_attrs = {"project_id": "project_id", "pipeline_id": "id"}
@@ -188,7 +184,7 @@ class ProjectPipelineVariable(RESTObject):
188
184
  _id_attr = "key"
189
185
 
190
186
 
191
- class ProjectPipelineVariableManager(ListMixin, RESTManager):
187
+ class ProjectPipelineVariableManager(ListMixin[ProjectPipelineVariable]):
192
188
  _path = "/projects/{project_id}/pipelines/{pipeline_id}/variables"
193
189
  _obj_cls = ProjectPipelineVariable
194
190
  _from_parent_attrs = {"project_id": "project_id", "pipeline_id": "id"}
@@ -199,7 +195,9 @@ class ProjectPipelineScheduleVariable(SaveMixin, ObjectDeleteMixin, RESTObject):
199
195
 
200
196
 
201
197
  class ProjectPipelineScheduleVariableManager(
202
- CreateMixin, UpdateMixin, DeleteMixin, RESTManager
198
+ CreateMixin[ProjectPipelineScheduleVariable],
199
+ UpdateMixin[ProjectPipelineScheduleVariable],
200
+ DeleteMixin[ProjectPipelineScheduleVariable],
203
201
  ):
204
202
  _path = "/projects/{project_id}/pipeline_schedules/{pipeline_schedule_id}/variables"
205
203
  _obj_cls = ProjectPipelineScheduleVariable
@@ -212,7 +210,9 @@ class ProjectPipelineSchedulePipeline(RESTObject):
212
210
  pass
213
211
 
214
212
 
215
- class ProjectPipelineSchedulePipelineManager(ListMixin, RESTManager):
213
+ class ProjectPipelineSchedulePipelineManager(
214
+ ListMixin[ProjectPipelineSchedulePipeline]
215
+ ):
216
216
  _path = "/projects/{project_id}/pipeline_schedules/{pipeline_schedule_id}/pipelines"
217
217
  _obj_cls = ProjectPipelineSchedulePipeline
218
218
  _from_parent_attrs = {"project_id": "project_id", "pipeline_schedule_id": "id"}
@@ -242,7 +242,7 @@ class ProjectPipelineSchedule(SaveMixin, ObjectDeleteMixin, RESTObject):
242
242
 
243
243
  @cli.register_custom_action(cls_names="ProjectPipelineSchedule")
244
244
  @exc.on_http_error(exc.GitlabPipelinePlayError)
245
- def play(self, **kwargs: Any) -> Dict[str, Any]:
245
+ def play(self, **kwargs: Any) -> dict[str, Any]:
246
246
  """Trigger a new scheduled pipeline, which runs immediately.
247
247
  The next scheduled run of this pipeline is not affected.
248
248
 
@@ -261,7 +261,7 @@ class ProjectPipelineSchedule(SaveMixin, ObjectDeleteMixin, RESTObject):
261
261
  return server_data
262
262
 
263
263
 
264
- class ProjectPipelineScheduleManager(CRUDMixin, RESTManager):
264
+ class ProjectPipelineScheduleManager(CRUDMixin[ProjectPipelineSchedule]):
265
265
  _path = "/projects/{project_id}/pipeline_schedules"
266
266
  _obj_cls = ProjectPipelineSchedule
267
267
  _from_parent_attrs = {"project_id": "id"}
@@ -269,36 +269,27 @@ class ProjectPipelineScheduleManager(CRUDMixin, RESTManager):
269
269
  required=("description", "ref", "cron"), optional=("cron_timezone", "active")
270
270
  )
271
271
  _update_attrs = RequiredOptional(
272
- optional=("description", "ref", "cron", "cron_timezone", "active"),
272
+ optional=("description", "ref", "cron", "cron_timezone", "active")
273
273
  )
274
274
 
275
- def get(
276
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
277
- ) -> ProjectPipelineSchedule:
278
- return cast(ProjectPipelineSchedule, super().get(id=id, lazy=lazy, **kwargs))
279
-
280
275
 
281
276
  class ProjectPipelineTestReport(RESTObject):
282
277
  _id_attr = None
283
278
 
284
279
 
285
- class ProjectPipelineTestReportManager(GetWithoutIdMixin, RESTManager):
280
+ class ProjectPipelineTestReportManager(GetWithoutIdMixin[ProjectPipelineTestReport]):
286
281
  _path = "/projects/{project_id}/pipelines/{pipeline_id}/test_report"
287
282
  _obj_cls = ProjectPipelineTestReport
288
283
  _from_parent_attrs = {"project_id": "project_id", "pipeline_id": "id"}
289
284
 
290
- def get(self, **kwargs: Any) -> ProjectPipelineTestReport:
291
- return cast(ProjectPipelineTestReport, super().get(**kwargs))
292
-
293
285
 
294
286
  class ProjectPipelineTestReportSummary(RESTObject):
295
287
  _id_attr = None
296
288
 
297
289
 
298
- class ProjectPipelineTestReportSummaryManager(GetWithoutIdMixin, RESTManager):
290
+ class ProjectPipelineTestReportSummaryManager(
291
+ GetWithoutIdMixin[ProjectPipelineTestReportSummary]
292
+ ):
299
293
  _path = "/projects/{project_id}/pipelines/{pipeline_id}/test_report_summary"
300
294
  _obj_cls = ProjectPipelineTestReportSummary
301
295
  _from_parent_attrs = {"project_id": "project_id", "pipeline_id": "id"}
302
-
303
- def get(self, **kwargs: Any) -> ProjectPipelineTestReportSummary:
304
- return cast(ProjectPipelineTestReportSummary, super().get(**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 (
5
3
  CreateMixin,
6
4
  DeleteMixin,
@@ -11,10 +9,7 @@ from gitlab.mixins import (
11
9
  )
12
10
  from gitlab.types import ArrayAttribute, RequiredOptional
13
11
 
14
- __all__ = [
15
- "ProjectAccessToken",
16
- "ProjectAccessTokenManager",
17
- ]
12
+ __all__ = ["ProjectAccessToken", "ProjectAccessTokenManager"]
18
13
 
19
14
 
20
15
  class ProjectAccessToken(ObjectDeleteMixin, ObjectRotateMixin, RESTObject):
@@ -22,7 +17,10 @@ class ProjectAccessToken(ObjectDeleteMixin, ObjectRotateMixin, RESTObject):
22
17
 
23
18
 
24
19
  class ProjectAccessTokenManager(
25
- CreateMixin, DeleteMixin, RetrieveMixin, RotateMixin, RESTManager
20
+ CreateMixin[ProjectAccessToken],
21
+ DeleteMixin[ProjectAccessToken],
22
+ RetrieveMixin[ProjectAccessToken],
23
+ RotateMixin[ProjectAccessToken],
26
24
  ):
27
25
  _path = "/projects/{project_id}/access_tokens"
28
26
  _obj_cls = ProjectAccessToken
@@ -31,8 +29,3 @@ class ProjectAccessTokenManager(
31
29
  required=("name", "scopes"), optional=("access_level", "expires_at")
32
30
  )
33
31
  _types = {"scopes": ArrayAttribute}
34
-
35
- def get(
36
- self, id: Union[str, int], lazy: bool = False, **kwargs: Any
37
- ) -> ProjectAccessToken:
38
- return cast(ProjectAccessToken, super().get(id=id, lazy=lazy, **kwargs))
@@ -3,27 +3,17 @@ GitLab API:
3
3
  https://docs.gitlab.com/ee/api/projects.html
4
4
  """
5
5
 
6
+ from __future__ import annotations
7
+
6
8
  import io
7
- from typing import (
8
- Any,
9
- Callable,
10
- cast,
11
- Dict,
12
- Iterator,
13
- List,
14
- Literal,
15
- Optional,
16
- overload,
17
- TYPE_CHECKING,
18
- Union,
19
- )
9
+ from typing import Any, Callable, Iterator, Literal, overload, TYPE_CHECKING
20
10
 
21
11
  import requests
22
12
 
23
13
  from gitlab import cli, client
24
14
  from gitlab import exceptions as exc
25
15
  from gitlab import types, utils
26
- from gitlab.base import RESTManager, RESTObject
16
+ from gitlab.base import RESTObject
27
17
  from gitlab.mixins import (
28
18
  CreateMixin,
29
19
  CRUDMixin,
@@ -141,7 +131,7 @@ class GroupProject(RESTObject):
141
131
  pass
142
132
 
143
133
 
144
- class GroupProjectManager(ListMixin, RESTManager):
134
+ class GroupProjectManager(ListMixin[GroupProject]):
145
135
  _path = "/groups/{group_id}/projects"
146
136
  _obj_cls = GroupProject
147
137
  _from_parent_attrs = {"group_id": "id"}
@@ -168,7 +158,7 @@ class ProjectGroup(RESTObject):
168
158
  pass
169
159
 
170
160
 
171
- class ProjectGroupManager(ListMixin, RESTManager):
161
+ class ProjectGroupManager(ListMixin[ProjectGroup]):
172
162
  _path = "/projects/{project_id}/groups"
173
163
  _obj_cls = ProjectGroup
174
164
  _from_parent_attrs = {"project_id": "id"}
@@ -210,7 +200,7 @@ class Project(
210
200
  events: ProjectEventManager
211
201
  exports: ProjectExportManager
212
202
  files: ProjectFileManager
213
- forks: "ProjectForkManager"
203
+ forks: ProjectForkManager
214
204
  generic_packages: GenericPackageManager
215
205
  gitignore_templates: ProjectGitignoreTemplateManager
216
206
  gitlabciyml_templates: ProjectGitlabciymlTemplateManager
@@ -250,15 +240,15 @@ class Project(
250
240
  registry_protection_repository_rules: ProjectRegistryRepositoryProtectionRuleManager
251
241
  releases: ProjectReleaseManager
252
242
  resource_groups: ProjectResourceGroupManager
253
- remote_mirrors: "ProjectRemoteMirrorManager"
254
- pull_mirror: "ProjectPullMirrorManager"
243
+ remote_mirrors: ProjectRemoteMirrorManager
244
+ pull_mirror: ProjectPullMirrorManager
255
245
  repositories: ProjectRegistryRepositoryManager
256
246
  runners: ProjectRunnerManager
257
247
  secure_files: ProjectSecureFileManager
258
248
  services: ProjectServiceManager
259
249
  snippets: ProjectSnippetManager
260
250
  external_status_checks: ProjectExternalStatusCheckManager
261
- storage: "ProjectStorageManager"
251
+ storage: ProjectStorageManager
262
252
  tags: ProjectTagManager
263
253
  triggers: ProjectTriggerManager
264
254
  users: ProjectUserManager
@@ -298,7 +288,7 @@ class Project(
298
288
 
299
289
  @cli.register_custom_action(cls_names="Project")
300
290
  @exc.on_http_error(exc.GitlabGetError)
301
- def languages(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
291
+ def languages(self, **kwargs: Any) -> dict[str, Any] | requests.Response:
302
292
  """Get languages used in the project with percentage value.
303
293
 
304
294
  Args:
@@ -393,7 +383,7 @@ class Project(
393
383
  self,
394
384
  group_id: int,
395
385
  group_access: int,
396
- expires_at: Optional[str] = None,
386
+ expires_at: str | None = None,
397
387
  **kwargs: Any,
398
388
  ) -> None:
399
389
  """Share the project with a group.
@@ -438,7 +428,7 @@ class Project(
438
428
  self,
439
429
  ref: str,
440
430
  token: str,
441
- variables: Optional[Dict[str, Any]] = None,
431
+ variables: dict[str, Any] | None = None,
442
432
  **kwargs: Any,
443
433
  ) -> ProjectPipeline:
444
434
  """Trigger a CI build.
@@ -523,7 +513,7 @@ class Project(
523
513
  self,
524
514
  wiki: bool = False,
525
515
  streamed: Literal[True] = True,
526
- action: Optional[Callable[[bytes], Any]] = None,
516
+ action: Callable[[bytes], Any] | None = None,
527
517
  chunk_size: int = 1024,
528
518
  *,
529
519
  iterator: Literal[False] = False,
@@ -536,12 +526,12 @@ class Project(
536
526
  self,
537
527
  wiki: bool = False,
538
528
  streamed: bool = False,
539
- action: Optional[Callable[[bytes], Any]] = None,
529
+ action: Callable[[bytes], Any] | None = None,
540
530
  chunk_size: int = 1024,
541
531
  *,
542
532
  iterator: bool = False,
543
533
  **kwargs: Any,
544
- ) -> Optional[Union[bytes, Iterator[Any]]]:
534
+ ) -> bytes | Iterator[Any] | None:
545
535
  """Return a snapshot of the repository.
546
536
 
547
537
  Args:
@@ -577,7 +567,7 @@ class Project(
577
567
  @exc.on_http_error(exc.GitlabSearchError)
578
568
  def search(
579
569
  self, scope: str, search: str, **kwargs: Any
580
- ) -> Union[client.GitlabList, List[Dict[str, Any]]]:
570
+ ) -> client.GitlabList | list[dict[str, Any]]:
581
571
  """Search the project resources matching the provided string.'
582
572
 
583
573
  Args:
@@ -620,7 +610,7 @@ class Project(
620
610
 
621
611
  @cli.register_custom_action(cls_names="Project")
622
612
  @exc.on_http_error(exc.GitlabGetError)
623
- def mirror_pull_details(self, **kwargs: Any) -> Dict[str, Any]:
613
+ def mirror_pull_details(self, **kwargs: Any) -> dict[str, Any]:
624
614
  """Get a project's pull mirror details.
625
615
 
626
616
  Introduced in GitLab 15.5.
@@ -650,7 +640,7 @@ class Project(
650
640
 
651
641
  @cli.register_custom_action(cls_names="Project", required=("to_namespace",))
652
642
  @exc.on_http_error(exc.GitlabTransferProjectError)
653
- def transfer(self, to_namespace: Union[int, str], **kwargs: Any) -> None:
643
+ def transfer(self, to_namespace: int | str, **kwargs: Any) -> None:
654
644
  """Transfer a project to the given namespace ID
655
645
 
656
646
  Args:
@@ -668,7 +658,7 @@ class Project(
668
658
  )
669
659
 
670
660
 
671
- class ProjectManager(CRUDMixin, RESTManager):
661
+ class ProjectManager(CRUDMixin[Project]):
672
662
  _path = "/projects"
673
663
  _obj_cls = Project
674
664
  # Please keep these _create_attrs in same order as they are at:
@@ -745,7 +735,7 @@ class ProjectManager(CRUDMixin, RESTManager):
745
735
  "visibility",
746
736
  "wiki_access_level",
747
737
  "wiki_enabled",
748
- ),
738
+ )
749
739
  )
750
740
  # Please keep these _update_attrs in same order as they are at:
751
741
  # https://docs.gitlab.com/ee/api/projects.html#edit-project
@@ -833,7 +823,7 @@ class ProjectManager(CRUDMixin, RESTManager):
833
823
  "visibility",
834
824
  "wiki_access_level",
835
825
  "wiki_enabled",
836
- ),
826
+ )
837
827
  )
838
828
  _list_filters = (
839
829
  "archived",
@@ -867,20 +857,17 @@ class ProjectManager(CRUDMixin, RESTManager):
867
857
  "topics": types.ArrayAttribute,
868
858
  }
869
859
 
870
- def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Project:
871
- return cast(Project, super().get(id=id, lazy=lazy, **kwargs))
872
-
873
860
  @exc.on_http_error(exc.GitlabImportError)
874
861
  def import_project(
875
862
  self,
876
863
  file: io.BufferedReader,
877
864
  path: str,
878
- name: Optional[str] = None,
879
- namespace: Optional[str] = None,
865
+ name: str | None = None,
866
+ namespace: str | None = None,
880
867
  overwrite: bool = False,
881
- override_params: Optional[Dict[str, Any]] = None,
868
+ override_params: dict[str, Any] | None = None,
882
869
  **kwargs: Any,
883
- ) -> Union[Dict[str, Any], requests.Response]:
870
+ ) -> dict[str, Any] | requests.Response:
884
871
  """Import a project from an archive file.
885
872
 
886
873
  Args:
@@ -920,12 +907,12 @@ class ProjectManager(CRUDMixin, RESTManager):
920
907
  self,
921
908
  url: str,
922
909
  path: str,
923
- name: Optional[str] = None,
924
- namespace: Optional[str] = None,
910
+ name: str | None = None,
911
+ namespace: str | None = None,
925
912
  overwrite: bool = False,
926
- override_params: Optional[Dict[str, Any]] = None,
913
+ override_params: dict[str, Any] | None = None,
927
914
  **kwargs: Any,
928
- ) -> Union[Dict[str, Any], requests.Response]:
915
+ ) -> dict[str, Any] | requests.Response:
929
916
  """Import a project from an archive file stored on a remote URL.
930
917
 
931
918
  Args:
@@ -968,12 +955,12 @@ class ProjectManager(CRUDMixin, RESTManager):
968
955
  file_key: str,
969
956
  access_key_id: str,
970
957
  secret_access_key: str,
971
- name: Optional[str] = None,
972
- namespace: Optional[str] = None,
958
+ name: str | None = None,
959
+ namespace: str | None = None,
973
960
  overwrite: bool = False,
974
- override_params: Optional[Dict[str, Any]] = None,
961
+ override_params: dict[str, Any] | None = None,
975
962
  **kwargs: Any,
976
- ) -> Union[Dict[str, Any], requests.Response]:
963
+ ) -> dict[str, Any] | requests.Response:
977
964
  """Import a project from an archive file stored on AWS S3.
978
965
 
979
966
  Args:
@@ -1026,10 +1013,10 @@ class ProjectManager(CRUDMixin, RESTManager):
1026
1013
  personal_access_token: str,
1027
1014
  bitbucket_server_project: str,
1028
1015
  bitbucket_server_repo: str,
1029
- new_name: Optional[str] = None,
1030
- target_namespace: Optional[str] = None,
1016
+ new_name: str | None = None,
1017
+ target_namespace: str | None = None,
1031
1018
  **kwargs: Any,
1032
- ) -> Union[Dict[str, Any], requests.Response]:
1019
+ ) -> dict[str, Any] | requests.Response:
1033
1020
  """Import a project from BitBucket Server to Gitlab (schedule the import)
1034
1021
 
1035
1022
  This method will return when an import operation has been safely queued,
@@ -1116,11 +1103,11 @@ class ProjectManager(CRUDMixin, RESTManager):
1116
1103
  personal_access_token: str,
1117
1104
  repo_id: int,
1118
1105
  target_namespace: str,
1119
- new_name: Optional[str] = None,
1120
- github_hostname: Optional[str] = None,
1121
- optional_stages: Optional[Dict[str, bool]] = None,
1106
+ new_name: str | None = None,
1107
+ github_hostname: str | None = None,
1108
+ optional_stages: dict[str, bool] | None = None,
1122
1109
  **kwargs: Any,
1123
- ) -> Union[Dict[str, Any], requests.Response]:
1110
+ ) -> dict[str, Any] | requests.Response:
1124
1111
  """Import a project from Github to Gitlab (schedule the import)
1125
1112
 
1126
1113
  This method will return when an import operation has been safely queued,
@@ -1196,7 +1183,7 @@ class ProjectFork(RESTObject):
1196
1183
  pass
1197
1184
 
1198
1185
 
1199
- class ProjectForkManager(CreateMixin, ListMixin, RESTManager):
1186
+ class ProjectForkManager(CreateMixin[ProjectFork], ListMixin[ProjectFork]):
1200
1187
  _path = "/projects/{project_id}/forks"
1201
1188
  _obj_cls = ProjectFork
1202
1189
  _from_parent_attrs = {"project_id": "id"}
@@ -1217,9 +1204,7 @@ class ProjectForkManager(CreateMixin, ListMixin, RESTManager):
1217
1204
  )
1218
1205
  _create_attrs = RequiredOptional(optional=("namespace",))
1219
1206
 
1220
- def create(
1221
- self, data: Optional[Dict[str, Any]] = None, **kwargs: Any
1222
- ) -> ProjectFork:
1207
+ def create(self, data: dict[str, Any] | None = None, **kwargs: Any) -> ProjectFork:
1223
1208
  """Creates a new object.
1224
1209
 
1225
1210
  Args:
@@ -1235,10 +1220,8 @@ class ProjectForkManager(CreateMixin, ListMixin, RESTManager):
1235
1220
  A new instance of the managed object class build with
1236
1221
  the data sent by the server
1237
1222
  """
1238
- if TYPE_CHECKING:
1239
- assert self.path is not None
1240
1223
  path = self.path[:-1] # drop the 's'
1241
- return cast(ProjectFork, CreateMixin.create(self, data, path=path, **kwargs))
1224
+ return super().create(data, path=path, **kwargs)
1242
1225
 
1243
1226
 
1244
1227
  class ProjectRemoteMirror(ObjectDeleteMixin, SaveMixin, RESTObject):
@@ -1246,7 +1229,10 @@ class ProjectRemoteMirror(ObjectDeleteMixin, SaveMixin, RESTObject):
1246
1229
 
1247
1230
 
1248
1231
  class ProjectRemoteMirrorManager(
1249
- ListMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager
1232
+ ListMixin[ProjectRemoteMirror],
1233
+ CreateMixin[ProjectRemoteMirror],
1234
+ UpdateMixin[ProjectRemoteMirror],
1235
+ DeleteMixin[ProjectRemoteMirror],
1250
1236
  ):
1251
1237
  _path = "/projects/{project_id}/remote_mirrors"
1252
1238
  _obj_cls = ProjectRemoteMirror
@@ -1261,17 +1247,16 @@ class ProjectPullMirror(SaveMixin, RESTObject):
1261
1247
  _id_attr = None
1262
1248
 
1263
1249
 
1264
- class ProjectPullMirrorManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
1250
+ class ProjectPullMirrorManager(
1251
+ GetWithoutIdMixin[ProjectPullMirror], UpdateMixin[ProjectPullMirror]
1252
+ ):
1265
1253
  _path = "/projects/{project_id}/mirror/pull"
1266
1254
  _obj_cls = ProjectPullMirror
1267
1255
  _from_parent_attrs = {"project_id": "id"}
1268
1256
  _update_attrs = RequiredOptional(optional=("url",))
1269
1257
 
1270
- def get(self, **kwargs: Any) -> ProjectPullMirror:
1271
- return cast(ProjectPullMirror, super().get(**kwargs))
1272
-
1273
1258
  @exc.on_http_error(exc.GitlabCreateError)
1274
- def create(self, data: Dict[str, Any], **kwargs: Any) -> ProjectPullMirror:
1259
+ def create(self, data: dict[str, Any], **kwargs: Any) -> ProjectPullMirror:
1275
1260
  """Create a new object.
1276
1261
 
1277
1262
  Args:
@@ -1291,8 +1276,6 @@ class ProjectPullMirrorManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
1291
1276
  assert data is not None
1292
1277
  self._create_attrs.validate_attrs(data=data)
1293
1278
 
1294
- if TYPE_CHECKING:
1295
- assert self.path is not None
1296
1279
  server_data = self.gitlab.http_put(self.path, post_data=data, **kwargs)
1297
1280
 
1298
1281
  if TYPE_CHECKING:
@@ -1311,8 +1294,6 @@ class ProjectPullMirrorManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
1311
1294
  GitlabAuthenticationError: If authentication is not correct
1312
1295
  GitlabCreateError: If the server failed to perform the request
1313
1296
  """
1314
- if TYPE_CHECKING:
1315
- assert self.path is not None
1316
1297
  self.gitlab.http_post(self.path, **kwargs)
1317
1298
 
1318
1299
 
@@ -1320,20 +1301,17 @@ class ProjectStorage(RefreshMixin, RESTObject):
1320
1301
  pass
1321
1302
 
1322
1303
 
1323
- class ProjectStorageManager(GetWithoutIdMixin, RESTManager):
1304
+ class ProjectStorageManager(GetWithoutIdMixin[ProjectStorage]):
1324
1305
  _path = "/projects/{project_id}/storage"
1325
1306
  _obj_cls = ProjectStorage
1326
1307
  _from_parent_attrs = {"project_id": "id"}
1327
1308
 
1328
- def get(self, **kwargs: Any) -> ProjectStorage:
1329
- return cast(ProjectStorage, super().get(**kwargs))
1330
-
1331
1309
 
1332
1310
  class SharedProject(RESTObject):
1333
1311
  pass
1334
1312
 
1335
1313
 
1336
- class SharedProjectManager(ListMixin, RESTManager):
1314
+ class SharedProjectManager(ListMixin[SharedProject]):
1337
1315
  _path = "/groups/{group_id}/projects/shared"
1338
1316
  _obj_cls = SharedProject
1339
1317
  _from_parent_attrs = {"group_id": "id"}