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,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,8 @@ 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,
432
+ inputs: dict[str, Any] | None = None,
442
433
  **kwargs: Any,
443
434
  ) -> ProjectPipeline:
444
435
  """Trigger a CI build.
@@ -449,6 +440,7 @@ class Project(
449
440
  ref: Commit to build; can be a branch name or a tag
450
441
  token: The trigger token
451
442
  variables: Variables passed to the build script
443
+ inputs: Inputs passed to the build script
452
444
  **kwargs: Extra options to send to the server (e.g. sudo)
453
445
 
454
446
  Raises:
@@ -456,8 +448,14 @@ class Project(
456
448
  GitlabCreateError: If the server failed to perform the request
457
449
  """
458
450
  variables = variables or {}
451
+ inputs = inputs or {}
459
452
  path = f"/projects/{self.encoded_id}/trigger/pipeline"
460
- post_data = {"ref": ref, "token": token, "variables": variables}
453
+ post_data = {
454
+ "ref": ref,
455
+ "token": token,
456
+ "variables": variables,
457
+ "inputs": inputs,
458
+ }
461
459
  attrs = self.manager.gitlab.http_post(path, post_data=post_data, **kwargs)
462
460
  if TYPE_CHECKING:
463
461
  assert isinstance(attrs, dict)
@@ -523,7 +521,7 @@ class Project(
523
521
  self,
524
522
  wiki: bool = False,
525
523
  streamed: Literal[True] = True,
526
- action: Optional[Callable[[bytes], Any]] = None,
524
+ action: Callable[[bytes], Any] | None = None,
527
525
  chunk_size: int = 1024,
528
526
  *,
529
527
  iterator: Literal[False] = False,
@@ -536,12 +534,12 @@ class Project(
536
534
  self,
537
535
  wiki: bool = False,
538
536
  streamed: bool = False,
539
- action: Optional[Callable[[bytes], Any]] = None,
537
+ action: Callable[[bytes], Any] | None = None,
540
538
  chunk_size: int = 1024,
541
539
  *,
542
540
  iterator: bool = False,
543
541
  **kwargs: Any,
544
- ) -> Optional[Union[bytes, Iterator[Any]]]:
542
+ ) -> bytes | Iterator[Any] | None:
545
543
  """Return a snapshot of the repository.
546
544
 
547
545
  Args:
@@ -577,7 +575,7 @@ class Project(
577
575
  @exc.on_http_error(exc.GitlabSearchError)
578
576
  def search(
579
577
  self, scope: str, search: str, **kwargs: Any
580
- ) -> Union[client.GitlabList, List[Dict[str, Any]]]:
578
+ ) -> client.GitlabList | list[dict[str, Any]]:
581
579
  """Search the project resources matching the provided string.'
582
580
 
583
581
  Args:
@@ -620,7 +618,7 @@ class Project(
620
618
 
621
619
  @cli.register_custom_action(cls_names="Project")
622
620
  @exc.on_http_error(exc.GitlabGetError)
623
- def mirror_pull_details(self, **kwargs: Any) -> Dict[str, Any]:
621
+ def mirror_pull_details(self, **kwargs: Any) -> dict[str, Any]:
624
622
  """Get a project's pull mirror details.
625
623
 
626
624
  Introduced in GitLab 15.5.
@@ -650,7 +648,7 @@ class Project(
650
648
 
651
649
  @cli.register_custom_action(cls_names="Project", required=("to_namespace",))
652
650
  @exc.on_http_error(exc.GitlabTransferProjectError)
653
- def transfer(self, to_namespace: Union[int, str], **kwargs: Any) -> None:
651
+ def transfer(self, to_namespace: int | str, **kwargs: Any) -> None:
654
652
  """Transfer a project to the given namespace ID
655
653
 
656
654
  Args:
@@ -668,7 +666,7 @@ class Project(
668
666
  )
669
667
 
670
668
 
671
- class ProjectManager(CRUDMixin, RESTManager):
669
+ class ProjectManager(CRUDMixin[Project]):
672
670
  _path = "/projects"
673
671
  _obj_cls = Project
674
672
  # Please keep these _create_attrs in same order as they are at:
@@ -745,7 +743,7 @@ class ProjectManager(CRUDMixin, RESTManager):
745
743
  "visibility",
746
744
  "wiki_access_level",
747
745
  "wiki_enabled",
748
- ),
746
+ )
749
747
  )
750
748
  # Please keep these _update_attrs in same order as they are at:
751
749
  # https://docs.gitlab.com/ee/api/projects.html#edit-project
@@ -833,7 +831,7 @@ class ProjectManager(CRUDMixin, RESTManager):
833
831
  "visibility",
834
832
  "wiki_access_level",
835
833
  "wiki_enabled",
836
- ),
834
+ )
837
835
  )
838
836
  _list_filters = (
839
837
  "archived",
@@ -867,20 +865,17 @@ class ProjectManager(CRUDMixin, RESTManager):
867
865
  "topics": types.ArrayAttribute,
868
866
  }
869
867
 
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
868
  @exc.on_http_error(exc.GitlabImportError)
874
869
  def import_project(
875
870
  self,
876
871
  file: io.BufferedReader,
877
872
  path: str,
878
- name: Optional[str] = None,
879
- namespace: Optional[str] = None,
873
+ name: str | None = None,
874
+ namespace: str | None = None,
880
875
  overwrite: bool = False,
881
- override_params: Optional[Dict[str, Any]] = None,
876
+ override_params: dict[str, Any] | None = None,
882
877
  **kwargs: Any,
883
- ) -> Union[Dict[str, Any], requests.Response]:
878
+ ) -> dict[str, Any] | requests.Response:
884
879
  """Import a project from an archive file.
885
880
 
886
881
  Args:
@@ -920,12 +915,12 @@ class ProjectManager(CRUDMixin, RESTManager):
920
915
  self,
921
916
  url: str,
922
917
  path: str,
923
- name: Optional[str] = None,
924
- namespace: Optional[str] = None,
918
+ name: str | None = None,
919
+ namespace: str | None = None,
925
920
  overwrite: bool = False,
926
- override_params: Optional[Dict[str, Any]] = None,
921
+ override_params: dict[str, Any] | None = None,
927
922
  **kwargs: Any,
928
- ) -> Union[Dict[str, Any], requests.Response]:
923
+ ) -> dict[str, Any] | requests.Response:
929
924
  """Import a project from an archive file stored on a remote URL.
930
925
 
931
926
  Args:
@@ -968,12 +963,12 @@ class ProjectManager(CRUDMixin, RESTManager):
968
963
  file_key: str,
969
964
  access_key_id: str,
970
965
  secret_access_key: str,
971
- name: Optional[str] = None,
972
- namespace: Optional[str] = None,
966
+ name: str | None = None,
967
+ namespace: str | None = None,
973
968
  overwrite: bool = False,
974
- override_params: Optional[Dict[str, Any]] = None,
969
+ override_params: dict[str, Any] | None = None,
975
970
  **kwargs: Any,
976
- ) -> Union[Dict[str, Any], requests.Response]:
971
+ ) -> dict[str, Any] | requests.Response:
977
972
  """Import a project from an archive file stored on AWS S3.
978
973
 
979
974
  Args:
@@ -1026,10 +1021,10 @@ class ProjectManager(CRUDMixin, RESTManager):
1026
1021
  personal_access_token: str,
1027
1022
  bitbucket_server_project: str,
1028
1023
  bitbucket_server_repo: str,
1029
- new_name: Optional[str] = None,
1030
- target_namespace: Optional[str] = None,
1024
+ new_name: str | None = None,
1025
+ target_namespace: str | None = None,
1031
1026
  **kwargs: Any,
1032
- ) -> Union[Dict[str, Any], requests.Response]:
1027
+ ) -> dict[str, Any] | requests.Response:
1033
1028
  """Import a project from BitBucket Server to Gitlab (schedule the import)
1034
1029
 
1035
1030
  This method will return when an import operation has been safely queued,
@@ -1116,11 +1111,11 @@ class ProjectManager(CRUDMixin, RESTManager):
1116
1111
  personal_access_token: str,
1117
1112
  repo_id: int,
1118
1113
  target_namespace: str,
1119
- new_name: Optional[str] = None,
1120
- github_hostname: Optional[str] = None,
1121
- optional_stages: Optional[Dict[str, bool]] = None,
1114
+ new_name: str | None = None,
1115
+ github_hostname: str | None = None,
1116
+ optional_stages: dict[str, bool] | None = None,
1122
1117
  **kwargs: Any,
1123
- ) -> Union[Dict[str, Any], requests.Response]:
1118
+ ) -> dict[str, Any] | requests.Response:
1124
1119
  """Import a project from Github to Gitlab (schedule the import)
1125
1120
 
1126
1121
  This method will return when an import operation has been safely queued,
@@ -1196,7 +1191,7 @@ class ProjectFork(RESTObject):
1196
1191
  pass
1197
1192
 
1198
1193
 
1199
- class ProjectForkManager(CreateMixin, ListMixin, RESTManager):
1194
+ class ProjectForkManager(CreateMixin[ProjectFork], ListMixin[ProjectFork]):
1200
1195
  _path = "/projects/{project_id}/forks"
1201
1196
  _obj_cls = ProjectFork
1202
1197
  _from_parent_attrs = {"project_id": "id"}
@@ -1217,9 +1212,7 @@ class ProjectForkManager(CreateMixin, ListMixin, RESTManager):
1217
1212
  )
1218
1213
  _create_attrs = RequiredOptional(optional=("namespace",))
1219
1214
 
1220
- def create(
1221
- self, data: Optional[Dict[str, Any]] = None, **kwargs: Any
1222
- ) -> ProjectFork:
1215
+ def create(self, data: dict[str, Any] | None = None, **kwargs: Any) -> ProjectFork:
1223
1216
  """Creates a new object.
1224
1217
 
1225
1218
  Args:
@@ -1235,10 +1228,8 @@ class ProjectForkManager(CreateMixin, ListMixin, RESTManager):
1235
1228
  A new instance of the managed object class build with
1236
1229
  the data sent by the server
1237
1230
  """
1238
- if TYPE_CHECKING:
1239
- assert self.path is not None
1240
1231
  path = self.path[:-1] # drop the 's'
1241
- return cast(ProjectFork, CreateMixin.create(self, data, path=path, **kwargs))
1232
+ return super().create(data, path=path, **kwargs)
1242
1233
 
1243
1234
 
1244
1235
  class ProjectRemoteMirror(ObjectDeleteMixin, SaveMixin, RESTObject):
@@ -1246,7 +1237,10 @@ class ProjectRemoteMirror(ObjectDeleteMixin, SaveMixin, RESTObject):
1246
1237
 
1247
1238
 
1248
1239
  class ProjectRemoteMirrorManager(
1249
- ListMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager
1240
+ ListMixin[ProjectRemoteMirror],
1241
+ CreateMixin[ProjectRemoteMirror],
1242
+ UpdateMixin[ProjectRemoteMirror],
1243
+ DeleteMixin[ProjectRemoteMirror],
1250
1244
  ):
1251
1245
  _path = "/projects/{project_id}/remote_mirrors"
1252
1246
  _obj_cls = ProjectRemoteMirror
@@ -1261,17 +1255,16 @@ class ProjectPullMirror(SaveMixin, RESTObject):
1261
1255
  _id_attr = None
1262
1256
 
1263
1257
 
1264
- class ProjectPullMirrorManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
1258
+ class ProjectPullMirrorManager(
1259
+ GetWithoutIdMixin[ProjectPullMirror], UpdateMixin[ProjectPullMirror]
1260
+ ):
1265
1261
  _path = "/projects/{project_id}/mirror/pull"
1266
1262
  _obj_cls = ProjectPullMirror
1267
1263
  _from_parent_attrs = {"project_id": "id"}
1268
1264
  _update_attrs = RequiredOptional(optional=("url",))
1269
1265
 
1270
- def get(self, **kwargs: Any) -> ProjectPullMirror:
1271
- return cast(ProjectPullMirror, super().get(**kwargs))
1272
-
1273
1266
  @exc.on_http_error(exc.GitlabCreateError)
1274
- def create(self, data: Dict[str, Any], **kwargs: Any) -> ProjectPullMirror:
1267
+ def create(self, data: dict[str, Any], **kwargs: Any) -> ProjectPullMirror:
1275
1268
  """Create a new object.
1276
1269
 
1277
1270
  Args:
@@ -1291,8 +1284,6 @@ class ProjectPullMirrorManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
1291
1284
  assert data is not None
1292
1285
  self._create_attrs.validate_attrs(data=data)
1293
1286
 
1294
- if TYPE_CHECKING:
1295
- assert self.path is not None
1296
1287
  server_data = self.gitlab.http_put(self.path, post_data=data, **kwargs)
1297
1288
 
1298
1289
  if TYPE_CHECKING:
@@ -1311,8 +1302,6 @@ class ProjectPullMirrorManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
1311
1302
  GitlabAuthenticationError: If authentication is not correct
1312
1303
  GitlabCreateError: If the server failed to perform the request
1313
1304
  """
1314
- if TYPE_CHECKING:
1315
- assert self.path is not None
1316
1305
  self.gitlab.http_post(self.path, **kwargs)
1317
1306
 
1318
1307
 
@@ -1320,20 +1309,17 @@ class ProjectStorage(RefreshMixin, RESTObject):
1320
1309
  pass
1321
1310
 
1322
1311
 
1323
- class ProjectStorageManager(GetWithoutIdMixin, RESTManager):
1312
+ class ProjectStorageManager(GetWithoutIdMixin[ProjectStorage]):
1324
1313
  _path = "/projects/{project_id}/storage"
1325
1314
  _obj_cls = ProjectStorage
1326
1315
  _from_parent_attrs = {"project_id": "id"}
1327
1316
 
1328
- def get(self, **kwargs: Any) -> ProjectStorage:
1329
- return cast(ProjectStorage, super().get(**kwargs))
1330
-
1331
1317
 
1332
1318
  class SharedProject(RESTObject):
1333
1319
  pass
1334
1320
 
1335
1321
 
1336
- class SharedProjectManager(ListMixin, RESTManager):
1322
+ class SharedProjectManager(ListMixin[SharedProject]):
1337
1323
  _path = "/groups/{group_id}/projects/shared"
1338
1324
  _obj_cls = SharedProject
1339
1325
  _from_parent_attrs = {"group_id": "id"}