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.
- gitlab/__init__.py +0 -1
- gitlab/_backends/protocol.py +9 -13
- gitlab/_backends/requests_backend.py +12 -12
- gitlab/_version.py +1 -1
- gitlab/base.py +48 -48
- gitlab/cli.py +15 -25
- gitlab/client.py +114 -140
- gitlab/config.py +16 -17
- gitlab/const.py +2 -0
- gitlab/exceptions.py +7 -5
- gitlab/mixins.py +154 -238
- gitlab/types.py +13 -14
- gitlab/utils.py +32 -43
- gitlab/v4/cli.py +51 -54
- gitlab/v4/objects/__init__.py +1 -0
- gitlab/v4/objects/access_requests.py +11 -3
- gitlab/v4/objects/appearance.py +12 -14
- gitlab/v4/objects/applications.py +5 -6
- gitlab/v4/objects/artifacts.py +10 -17
- gitlab/v4/objects/audit_events.py +4 -19
- gitlab/v4/objects/award_emojis.py +13 -57
- gitlab/v4/objects/badges.py +4 -19
- gitlab/v4/objects/boards.py +7 -27
- gitlab/v4/objects/branches.py +26 -14
- gitlab/v4/objects/broadcast_messages.py +3 -13
- gitlab/v4/objects/bulk_imports.py +6 -14
- gitlab/v4/objects/ci_lint.py +7 -13
- gitlab/v4/objects/cluster_agents.py +3 -13
- gitlab/v4/objects/clusters.py +13 -23
- gitlab/v4/objects/commits.py +23 -28
- gitlab/v4/objects/container_registry.py +13 -19
- gitlab/v4/objects/custom_attributes.py +16 -21
- gitlab/v4/objects/deploy_keys.py +22 -19
- gitlab/v4/objects/deploy_tokens.py +14 -32
- gitlab/v4/objects/deployments.py +13 -15
- gitlab/v4/objects/discussions.py +13 -29
- gitlab/v4/objects/draft_notes.py +4 -14
- gitlab/v4/objects/environments.py +13 -21
- gitlab/v4/objects/epics.py +14 -17
- gitlab/v4/objects/events.py +27 -79
- gitlab/v4/objects/export_import.py +7 -19
- gitlab/v4/objects/features.py +11 -12
- gitlab/v4/objects/files.py +23 -38
- gitlab/v4/objects/geo_nodes.py +7 -11
- gitlab/v4/objects/group_access_tokens.py +6 -13
- gitlab/v4/objects/groups.py +42 -37
- gitlab/v4/objects/hooks.py +4 -17
- gitlab/v4/objects/integrations.py +7 -18
- gitlab/v4/objects/invitations.py +12 -23
- gitlab/v4/objects/issues.py +21 -27
- gitlab/v4/objects/iterations.py +4 -8
- gitlab/v4/objects/job_token_scope.py +18 -14
- gitlab/v4/objects/jobs.py +17 -32
- gitlab/v4/objects/keys.py +8 -11
- gitlab/v4/objects/labels.py +19 -30
- gitlab/v4/objects/ldap.py +25 -9
- gitlab/v4/objects/member_roles.py +102 -0
- gitlab/v4/objects/members.py +11 -29
- gitlab/v4/objects/merge_request_approvals.py +31 -44
- gitlab/v4/objects/merge_requests.py +30 -40
- gitlab/v4/objects/merge_trains.py +3 -6
- gitlab/v4/objects/milestones.py +23 -29
- gitlab/v4/objects/namespaces.py +4 -10
- gitlab/v4/objects/notes.py +26 -69
- gitlab/v4/objects/notification_settings.py +5 -14
- gitlab/v4/objects/package_protection_rules.py +8 -8
- gitlab/v4/objects/packages.py +22 -37
- gitlab/v4/objects/pages.py +8 -14
- gitlab/v4/objects/personal_access_tokens.py +7 -10
- gitlab/v4/objects/pipelines.py +38 -47
- gitlab/v4/objects/project_access_tokens.py +6 -13
- gitlab/v4/objects/projects.py +63 -77
- gitlab/v4/objects/push_rules.py +13 -15
- gitlab/v4/objects/registry_protection_repository_rules.py +6 -7
- gitlab/v4/objects/registry_protection_rules.py +7 -11
- gitlab/v4/objects/releases.py +6 -20
- gitlab/v4/objects/repositories.py +25 -34
- gitlab/v4/objects/resource_groups.py +10 -15
- gitlab/v4/objects/reviewers.py +4 -2
- gitlab/v4/objects/runners.py +14 -13
- gitlab/v4/objects/secure_files.py +8 -21
- gitlab/v4/objects/service_accounts.py +7 -5
- gitlab/v4/objects/settings.py +13 -14
- gitlab/v4/objects/sidekiq.py +17 -18
- gitlab/v4/objects/snippets.py +78 -66
- gitlab/v4/objects/statistics.py +8 -23
- gitlab/v4/objects/status_checks.py +6 -3
- gitlab/v4/objects/tags.py +4 -13
- gitlab/v4/objects/templates.py +11 -59
- gitlab/v4/objects/todos.py +3 -6
- gitlab/v4/objects/topics.py +10 -21
- gitlab/v4/objects/triggers.py +3 -13
- gitlab/v4/objects/users.py +101 -93
- gitlab/v4/objects/variables.py +4 -19
- gitlab/v4/objects/wikis.py +4 -19
- {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info}/METADATA +3 -2
- python_gitlab-6.1.0.dist-info/RECORD +107 -0
- {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info}/WHEEL +1 -1
- python_gitlab-5.6.0.dist-info/RECORD +0 -106
- {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info}/entry_points.txt +0 -0
- {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info/licenses}/AUTHORS +0 -0
- {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info/licenses}/COPYING +0 -0
- {python_gitlab-5.6.0.dist-info → python_gitlab-6.1.0.dist-info}/top_level.txt +0 -0
gitlab/v4/objects/geo_nodes.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
from typing import Any,
|
1
|
+
from typing import Any, Dict, List, TYPE_CHECKING
|
2
2
|
|
3
3
|
from gitlab import cli
|
4
4
|
from gitlab import exceptions as exc
|
5
|
-
from gitlab.base import
|
5
|
+
from gitlab.base import RESTObject
|
6
6
|
from gitlab.mixins import (
|
7
7
|
DeleteMixin,
|
8
8
|
ObjectDeleteMixin,
|
@@ -12,10 +12,7 @@ from gitlab.mixins import (
|
|
12
12
|
)
|
13
13
|
from gitlab.types import RequiredOptional
|
14
14
|
|
15
|
-
__all__ = [
|
16
|
-
"GeoNode",
|
17
|
-
"GeoNodeManager",
|
18
|
-
]
|
15
|
+
__all__ = ["GeoNode", "GeoNodeManager"]
|
19
16
|
|
20
17
|
|
21
18
|
class GeoNode(SaveMixin, ObjectDeleteMixin, RESTObject):
|
@@ -59,16 +56,15 @@ class GeoNode(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
59
56
|
return result
|
60
57
|
|
61
58
|
|
62
|
-
class GeoNodeManager(
|
59
|
+
class GeoNodeManager(
|
60
|
+
RetrieveMixin[GeoNode], UpdateMixin[GeoNode], DeleteMixin[GeoNode]
|
61
|
+
):
|
63
62
|
_path = "/geo_nodes"
|
64
63
|
_obj_cls = GeoNode
|
65
64
|
_update_attrs = RequiredOptional(
|
66
|
-
optional=("enabled", "url", "files_max_capacity", "repos_max_capacity")
|
65
|
+
optional=("enabled", "url", "files_max_capacity", "repos_max_capacity")
|
67
66
|
)
|
68
67
|
|
69
|
-
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> GeoNode:
|
70
|
-
return cast(GeoNode, super().get(id=id, lazy=lazy, **kwargs))
|
71
|
-
|
72
68
|
@cli.register_custom_action(cls_names="GeoNodeManager")
|
73
69
|
@exc.on_http_error(exc.GitlabGetError)
|
74
70
|
def status(self, **kwargs: Any) -> List[Dict[str, Any]]:
|
@@ -1,6 +1,4 @@
|
|
1
|
-
from
|
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
|
-
"GroupAccessToken",
|
16
|
-
"GroupAccessTokenManager",
|
17
|
-
]
|
12
|
+
__all__ = ["GroupAccessToken", "GroupAccessTokenManager"]
|
18
13
|
|
19
14
|
|
20
15
|
class GroupAccessToken(ObjectDeleteMixin, ObjectRotateMixin, RESTObject):
|
@@ -22,7 +17,10 @@ class GroupAccessToken(ObjectDeleteMixin, ObjectRotateMixin, RESTObject):
|
|
22
17
|
|
23
18
|
|
24
19
|
class GroupAccessTokenManager(
|
25
|
-
CreateMixin,
|
20
|
+
CreateMixin[GroupAccessToken],
|
21
|
+
DeleteMixin[GroupAccessToken],
|
22
|
+
RetrieveMixin[GroupAccessToken],
|
23
|
+
RotateMixin[GroupAccessToken],
|
26
24
|
):
|
27
25
|
_path = "/groups/{group_id}/access_tokens"
|
28
26
|
_obj_cls = GroupAccessToken
|
@@ -31,8 +29,3 @@ class GroupAccessTokenManager(
|
|
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
|
-
) -> GroupAccessToken:
|
38
|
-
return cast(GroupAccessToken, super().get(id=id, lazy=lazy, **kwargs))
|
gitlab/v4/objects/groups.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Any, BinaryIO, TYPE_CHECKING
|
2
4
|
|
3
5
|
import requests
|
4
6
|
|
@@ -6,7 +8,7 @@ import gitlab
|
|
6
8
|
from gitlab import cli
|
7
9
|
from gitlab import exceptions as exc
|
8
10
|
from gitlab import types
|
9
|
-
from gitlab.base import
|
11
|
+
from gitlab.base import RESTObject, TObjCls
|
10
12
|
from gitlab.mixins import (
|
11
13
|
CreateMixin,
|
12
14
|
CRUDMixin,
|
@@ -22,6 +24,7 @@ from .access_requests import GroupAccessRequestManager # noqa: F401
|
|
22
24
|
from .audit_events import GroupAuditEventManager # noqa: F401
|
23
25
|
from .badges import GroupBadgeManager # noqa: F401
|
24
26
|
from .boards import GroupBoardManager # noqa: F401
|
27
|
+
from .branches import GroupProtectedBranchManager # noqa: F401
|
25
28
|
from .clusters import GroupClusterManager # noqa: F401
|
26
29
|
from .container_registry import GroupRegistryRepositoryManager # noqa: F401
|
27
30
|
from .custom_attributes import GroupCustomAttributeManager # noqa: F401
|
@@ -34,6 +37,7 @@ from .invitations import GroupInvitationManager # noqa: F401
|
|
34
37
|
from .issues import GroupIssueManager # noqa: F401
|
35
38
|
from .iterations import GroupIterationManager # noqa: F401
|
36
39
|
from .labels import GroupLabelManager # noqa: F401
|
40
|
+
from .member_roles import GroupMemberRoleManager # noqa: F401
|
37
41
|
from .members import ( # noqa: F401
|
38
42
|
GroupBillableMemberManager,
|
39
43
|
GroupMemberAllManager,
|
@@ -79,7 +83,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
79
83
|
clusters: GroupClusterManager
|
80
84
|
customattributes: GroupCustomAttributeManager
|
81
85
|
deploytokens: GroupDeployTokenManager
|
82
|
-
descendant_groups:
|
86
|
+
descendant_groups: GroupDescendantGroupManager
|
83
87
|
epics: GroupEpicManager
|
84
88
|
exports: GroupExportManager
|
85
89
|
hooks: GroupHookManager
|
@@ -89,7 +93,8 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
89
93
|
issues_statistics: GroupIssuesStatisticsManager
|
90
94
|
iterations: GroupIterationManager
|
91
95
|
labels: GroupLabelManager
|
92
|
-
ldap_group_links:
|
96
|
+
ldap_group_links: GroupLDAPGroupLinkManager
|
97
|
+
member_roles: GroupMemberRoleManager
|
93
98
|
members: GroupMemberManager
|
94
99
|
members_all: GroupMemberAllManager
|
95
100
|
mergerequests: GroupMergeRequestManager
|
@@ -98,14 +103,15 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
98
103
|
packages: GroupPackageManager
|
99
104
|
projects: GroupProjectManager
|
100
105
|
shared_projects: SharedProjectManager
|
106
|
+
protectedbranches: GroupProtectedBranchManager
|
101
107
|
pushrules: GroupPushRulesManager
|
102
108
|
registry_repositories: GroupRegistryRepositoryManager
|
103
109
|
runners: GroupRunnerManager
|
104
|
-
subgroups:
|
110
|
+
subgroups: GroupSubgroupManager
|
105
111
|
variables: GroupVariableManager
|
106
112
|
wikis: GroupWikiManager
|
107
|
-
saml_group_links:
|
108
|
-
service_accounts:
|
113
|
+
saml_group_links: GroupSAMLGroupLinkManager
|
114
|
+
service_accounts: GroupServiceAccountManager
|
109
115
|
|
110
116
|
@cli.register_custom_action(cls_names="Group", required=("project_id",))
|
111
117
|
@exc.on_http_error(exc.GitlabTransferProjectError)
|
@@ -125,7 +131,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
125
131
|
|
126
132
|
@cli.register_custom_action(cls_names="Group", required=(), optional=("group_id",))
|
127
133
|
@exc.on_http_error(exc.GitlabGroupTransferError)
|
128
|
-
def transfer(self, group_id:
|
134
|
+
def transfer(self, group_id: int | None = None, **kwargs: Any) -> None:
|
129
135
|
"""Transfer the group to a new parent group or make it a top-level group.
|
130
136
|
|
131
137
|
Requires GitLab ≥14.6.
|
@@ -149,7 +155,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
149
155
|
@exc.on_http_error(exc.GitlabSearchError)
|
150
156
|
def search(
|
151
157
|
self, scope: str, search: str, **kwargs: Any
|
152
|
-
) ->
|
158
|
+
) -> gitlab.GitlabList | list[dict[str, Any]]:
|
153
159
|
"""Search the group resources matching the provided string.
|
154
160
|
|
155
161
|
Args:
|
@@ -193,7 +199,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
193
199
|
self,
|
194
200
|
group_id: int,
|
195
201
|
group_access: int,
|
196
|
-
expires_at:
|
202
|
+
expires_at: str | None = None,
|
197
203
|
**kwargs: Any,
|
198
204
|
) -> None:
|
199
205
|
"""Share the group with a group.
|
@@ -253,7 +259,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
253
259
|
self.manager.gitlab.http_post(path, **kwargs)
|
254
260
|
|
255
261
|
|
256
|
-
class GroupManager(CRUDMixin
|
262
|
+
class GroupManager(CRUDMixin[Group]):
|
257
263
|
_path = "/groups"
|
258
264
|
_obj_cls = Group
|
259
265
|
_list_filters = (
|
@@ -315,22 +321,19 @@ class GroupManager(CRUDMixin, RESTManager):
|
|
315
321
|
"extra_shared_runners_minutes_limit",
|
316
322
|
"prevent_forking_outside_group",
|
317
323
|
"shared_runners_setting",
|
318
|
-
)
|
324
|
+
)
|
319
325
|
)
|
320
326
|
_types = {"avatar": types.ImageAttribute, "skip_groups": types.ArrayAttribute}
|
321
327
|
|
322
|
-
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Group:
|
323
|
-
return cast(Group, super().get(id=id, lazy=lazy, **kwargs))
|
324
|
-
|
325
328
|
@exc.on_http_error(exc.GitlabImportError)
|
326
329
|
def import_group(
|
327
330
|
self,
|
328
331
|
file: BinaryIO,
|
329
332
|
path: str,
|
330
333
|
name: str,
|
331
|
-
parent_id:
|
334
|
+
parent_id: int | str | None = None,
|
332
335
|
**kwargs: Any,
|
333
|
-
) ->
|
336
|
+
) -> dict[str, Any] | requests.Response:
|
334
337
|
"""Import a group from an archive file.
|
335
338
|
|
336
339
|
Args:
|
@@ -349,7 +352,7 @@ class GroupManager(CRUDMixin, RESTManager):
|
|
349
352
|
A representation of the import status.
|
350
353
|
"""
|
351
354
|
files = {"file": ("file.tar.gz", file, "application/octet-stream")}
|
352
|
-
data:
|
355
|
+
data: dict[str, Any] = {"path": path, "name": name}
|
353
356
|
if parent_id is not None:
|
354
357
|
data["parent_id"] = parent_id
|
355
358
|
|
@@ -358,13 +361,7 @@ class GroupManager(CRUDMixin, RESTManager):
|
|
358
361
|
)
|
359
362
|
|
360
363
|
|
361
|
-
class
|
362
|
-
pass
|
363
|
-
|
364
|
-
|
365
|
-
class GroupSubgroupManager(ListMixin, RESTManager):
|
366
|
-
_path = "/groups/{group_id}/subgroups"
|
367
|
-
_obj_cls: Union[Type["GroupDescendantGroup"], Type[GroupSubgroup]] = GroupSubgroup
|
364
|
+
class SubgroupBaseManager(ListMixin[TObjCls]):
|
368
365
|
_from_parent_attrs = {"group_id": "id"}
|
369
366
|
_list_filters = (
|
370
367
|
"skip_groups",
|
@@ -380,24 +377,33 @@ class GroupSubgroupManager(ListMixin, RESTManager):
|
|
380
377
|
_types = {"skip_groups": types.ArrayAttribute}
|
381
378
|
|
382
379
|
|
380
|
+
class GroupSubgroup(RESTObject):
|
381
|
+
pass
|
382
|
+
|
383
|
+
|
384
|
+
class GroupSubgroupManager(SubgroupBaseManager[GroupSubgroup]):
|
385
|
+
_path = "/groups/{group_id}/subgroups"
|
386
|
+
_obj_cls = GroupSubgroup
|
387
|
+
|
388
|
+
|
383
389
|
class GroupDescendantGroup(RESTObject):
|
384
390
|
pass
|
385
391
|
|
386
392
|
|
387
|
-
class GroupDescendantGroupManager(
|
393
|
+
class GroupDescendantGroupManager(SubgroupBaseManager[GroupDescendantGroup]):
|
388
394
|
"""
|
389
395
|
This manager inherits from GroupSubgroupManager as descendant groups
|
390
396
|
share all attributes with subgroups, except the path and object class.
|
391
397
|
"""
|
392
398
|
|
393
399
|
_path = "/groups/{group_id}/descendant_groups"
|
394
|
-
_obj_cls
|
400
|
+
_obj_cls = GroupDescendantGroup
|
395
401
|
|
396
402
|
|
397
403
|
class GroupLDAPGroupLink(RESTObject):
|
398
404
|
_repr_attr = "provider"
|
399
405
|
|
400
|
-
def _get_link_attrs(self) ->
|
406
|
+
def _get_link_attrs(self) -> dict[str, str]:
|
401
407
|
# https://docs.gitlab.com/ee/api/groups.html#add-ldap-group-link-with-cn-or-filter
|
402
408
|
# https://docs.gitlab.com/ee/api/groups.html#delete-ldap-group-link-with-cn-or-filter
|
403
409
|
# We can tell what attribute to use based on the data returned
|
@@ -426,9 +432,13 @@ class GroupLDAPGroupLink(RESTObject):
|
|
426
432
|
)
|
427
433
|
|
428
434
|
|
429
|
-
class GroupLDAPGroupLinkManager(
|
435
|
+
class GroupLDAPGroupLinkManager(
|
436
|
+
ListMixin[GroupLDAPGroupLink],
|
437
|
+
CreateMixin[GroupLDAPGroupLink],
|
438
|
+
DeleteMixin[GroupLDAPGroupLink],
|
439
|
+
):
|
430
440
|
_path = "/groups/{group_id}/ldap_group_links"
|
431
|
-
_obj_cls
|
441
|
+
_obj_cls = GroupLDAPGroupLink
|
432
442
|
_from_parent_attrs = {"group_id": "id"}
|
433
443
|
_create_attrs = RequiredOptional(
|
434
444
|
required=("provider", "group_access"), exclusive=("cn", "filter")
|
@@ -440,13 +450,8 @@ class GroupSAMLGroupLink(ObjectDeleteMixin, RESTObject):
|
|
440
450
|
_repr_attr = "name"
|
441
451
|
|
442
452
|
|
443
|
-
class GroupSAMLGroupLinkManager(NoUpdateMixin
|
453
|
+
class GroupSAMLGroupLinkManager(NoUpdateMixin[GroupSAMLGroupLink]):
|
444
454
|
_path = "/groups/{group_id}/saml_group_links"
|
445
|
-
_obj_cls
|
455
|
+
_obj_cls = GroupSAMLGroupLink
|
446
456
|
_from_parent_attrs = {"group_id": "id"}
|
447
457
|
_create_attrs = RequiredOptional(required=("saml_group_name", "access_level"))
|
448
|
-
|
449
|
-
def get(
|
450
|
-
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
|
451
|
-
) -> GroupSAMLGroupLink:
|
452
|
-
return cast(GroupSAMLGroupLink, super().get(id=id, lazy=lazy, **kwargs))
|
gitlab/v4/objects/hooks.py
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
from typing import Any, cast, Union
|
2
|
-
|
3
1
|
from gitlab import exceptions as exc
|
4
|
-
from gitlab.base import
|
2
|
+
from gitlab.base import RESTObject
|
5
3
|
from gitlab.mixins import CRUDMixin, NoUpdateMixin, ObjectDeleteMixin, SaveMixin
|
6
4
|
from gitlab.types import RequiredOptional
|
7
5
|
|
@@ -20,14 +18,11 @@ class Hook(ObjectDeleteMixin, RESTObject):
|
|
20
18
|
_repr_attr = "url"
|
21
19
|
|
22
20
|
|
23
|
-
class HookManager(NoUpdateMixin
|
21
|
+
class HookManager(NoUpdateMixin[Hook]):
|
24
22
|
_path = "/hooks"
|
25
23
|
_obj_cls = Hook
|
26
24
|
_create_attrs = RequiredOptional(required=("url",))
|
27
25
|
|
28
|
-
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Hook:
|
29
|
-
return cast(Hook, super().get(id=id, lazy=lazy, **kwargs))
|
30
|
-
|
31
26
|
|
32
27
|
class ProjectHook(SaveMixin, ObjectDeleteMixin, RESTObject):
|
33
28
|
_repr_attr = "url"
|
@@ -47,7 +42,7 @@ class ProjectHook(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
47
42
|
self.manager.gitlab.http_post(path)
|
48
43
|
|
49
44
|
|
50
|
-
class ProjectHookManager(CRUDMixin
|
45
|
+
class ProjectHookManager(CRUDMixin[ProjectHook]):
|
51
46
|
_path = "/projects/{project_id}/hooks"
|
52
47
|
_obj_cls = ProjectHook
|
53
48
|
_from_parent_attrs = {"project_id": "id"}
|
@@ -84,11 +79,6 @@ class ProjectHookManager(CRUDMixin, RESTManager):
|
|
84
79
|
),
|
85
80
|
)
|
86
81
|
|
87
|
-
def get(
|
88
|
-
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
|
89
|
-
) -> ProjectHook:
|
90
|
-
return cast(ProjectHook, super().get(id=id, lazy=lazy, **kwargs))
|
91
|
-
|
92
82
|
|
93
83
|
class GroupHook(SaveMixin, ObjectDeleteMixin, RESTObject):
|
94
84
|
_repr_attr = "url"
|
@@ -108,7 +98,7 @@ class GroupHook(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
108
98
|
self.manager.gitlab.http_post(path)
|
109
99
|
|
110
100
|
|
111
|
-
class GroupHookManager(CRUDMixin
|
101
|
+
class GroupHookManager(CRUDMixin[GroupHook]):
|
112
102
|
_path = "/groups/{group_id}/hooks"
|
113
103
|
_obj_cls = GroupHook
|
114
104
|
_from_parent_attrs = {"group_id": "id"}
|
@@ -152,6 +142,3 @@ class GroupHookManager(CRUDMixin, RESTManager):
|
|
152
142
|
"token",
|
153
143
|
),
|
154
144
|
)
|
155
|
-
|
156
|
-
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> GroupHook:
|
157
|
-
return cast(GroupHook, super().get(id=id, lazy=lazy, **kwargs))
|
@@ -3,10 +3,10 @@ GitLab API:
|
|
3
3
|
https://docs.gitlab.com/ee/api/integrations.html
|
4
4
|
"""
|
5
5
|
|
6
|
-
from typing import
|
6
|
+
from typing import List
|
7
7
|
|
8
8
|
from gitlab import cli
|
9
|
-
from gitlab.base import
|
9
|
+
from gitlab.base import RESTObject
|
10
10
|
from gitlab.mixins import (
|
11
11
|
DeleteMixin,
|
12
12
|
GetMixin,
|
@@ -29,7 +29,10 @@ class ProjectIntegration(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
29
29
|
|
30
30
|
|
31
31
|
class ProjectIntegrationManager(
|
32
|
-
GetMixin,
|
32
|
+
GetMixin[ProjectIntegration],
|
33
|
+
UpdateMixin[ProjectIntegration],
|
34
|
+
DeleteMixin[ProjectIntegration],
|
35
|
+
ListMixin[ProjectIntegration],
|
33
36
|
):
|
34
37
|
_path = "/projects/{project_id}/integrations"
|
35
38
|
_from_parent_attrs = {"project_id": "id"}
|
@@ -149,11 +152,7 @@ class ProjectIntegrationManager(
|
|
149
152
|
),
|
150
153
|
),
|
151
154
|
"jira": (
|
152
|
-
(
|
153
|
-
"url",
|
154
|
-
"username",
|
155
|
-
"password",
|
156
|
-
),
|
155
|
+
("url", "username", "password"),
|
157
156
|
(
|
158
157
|
"api_url",
|
159
158
|
"active",
|
@@ -265,11 +264,6 @@ class ProjectIntegrationManager(
|
|
265
264
|
"youtrack": (("issues_url", "project_url"), ("description", "push_events")),
|
266
265
|
}
|
267
266
|
|
268
|
-
def get(
|
269
|
-
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
|
270
|
-
) -> ProjectIntegration:
|
271
|
-
return cast(ProjectIntegration, super().get(id=id, lazy=lazy, **kwargs))
|
272
|
-
|
273
267
|
@cli.register_custom_action(
|
274
268
|
cls_names=("ProjectIntegrationManager", "ProjectServiceManager")
|
275
269
|
)
|
@@ -288,8 +282,3 @@ class ProjectService(ProjectIntegration):
|
|
288
282
|
|
289
283
|
class ProjectServiceManager(ProjectIntegrationManager):
|
290
284
|
_obj_cls = ProjectService
|
291
|
-
|
292
|
-
def get(
|
293
|
-
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
|
294
|
-
) -> ProjectService:
|
295
|
-
return cast(ProjectService, super().get(id=id, lazy=lazy, **kwargs))
|
gitlab/v4/objects/invitations.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
2
|
|
3
|
-
from
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
from gitlab.base import RESTObject, TObjCls
|
4
6
|
from gitlab.exceptions import GitlabInvitationError
|
5
7
|
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
|
6
8
|
from gitlab.types import ArrayAttribute, CommaSeparatedListAttribute, RequiredOptional
|
@@ -13,9 +15,10 @@ __all__ = [
|
|
13
15
|
]
|
14
16
|
|
15
17
|
|
16
|
-
class InvitationMixin(CRUDMixin):
|
17
|
-
|
18
|
-
|
18
|
+
class InvitationMixin(CRUDMixin[TObjCls]):
|
19
|
+
# pylint: disable=abstract-method
|
20
|
+
def create(self, data: dict[str, Any] | None = None, **kwargs: Any) -> TObjCls:
|
21
|
+
invitation = super().create(data, **kwargs)
|
19
22
|
|
20
23
|
if invitation.status == "error":
|
21
24
|
raise GitlabInvitationError(invitation.message)
|
@@ -27,7 +30,7 @@ class ProjectInvitation(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
27
30
|
_id_attr = "email"
|
28
31
|
|
29
32
|
|
30
|
-
class ProjectInvitationManager(InvitationMixin
|
33
|
+
class ProjectInvitationManager(InvitationMixin[ProjectInvitation]):
|
31
34
|
_path = "/projects/{project_id}/invitations"
|
32
35
|
_obj_cls = ProjectInvitation
|
33
36
|
_from_parent_attrs = {"project_id": "id"}
|
@@ -41,9 +44,7 @@ class ProjectInvitationManager(InvitationMixin, RESTManager):
|
|
41
44
|
),
|
42
45
|
exclusive=("email", "user_id"),
|
43
46
|
)
|
44
|
-
_update_attrs = RequiredOptional(
|
45
|
-
optional=("access_level", "expires_at"),
|
46
|
-
)
|
47
|
+
_update_attrs = RequiredOptional(optional=("access_level", "expires_at"))
|
47
48
|
_list_filters = ("query",)
|
48
49
|
_types = {
|
49
50
|
"email": CommaSeparatedListAttribute,
|
@@ -51,17 +52,12 @@ class ProjectInvitationManager(InvitationMixin, RESTManager):
|
|
51
52
|
"tasks_to_be_done": ArrayAttribute,
|
52
53
|
}
|
53
54
|
|
54
|
-
def get(
|
55
|
-
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
|
56
|
-
) -> ProjectInvitation:
|
57
|
-
return cast(ProjectInvitation, super().get(id=id, lazy=lazy, **kwargs))
|
58
|
-
|
59
55
|
|
60
56
|
class GroupInvitation(SaveMixin, ObjectDeleteMixin, RESTObject):
|
61
57
|
_id_attr = "email"
|
62
58
|
|
63
59
|
|
64
|
-
class GroupInvitationManager(InvitationMixin
|
60
|
+
class GroupInvitationManager(InvitationMixin[GroupInvitation]):
|
65
61
|
_path = "/groups/{group_id}/invitations"
|
66
62
|
_obj_cls = GroupInvitation
|
67
63
|
_from_parent_attrs = {"group_id": "id"}
|
@@ -75,17 +71,10 @@ class GroupInvitationManager(InvitationMixin, RESTManager):
|
|
75
71
|
),
|
76
72
|
exclusive=("email", "user_id"),
|
77
73
|
)
|
78
|
-
_update_attrs = RequiredOptional(
|
79
|
-
optional=("access_level", "expires_at"),
|
80
|
-
)
|
74
|
+
_update_attrs = RequiredOptional(optional=("access_level", "expires_at"))
|
81
75
|
_list_filters = ("query",)
|
82
76
|
_types = {
|
83
77
|
"email": CommaSeparatedListAttribute,
|
84
78
|
"user_id": CommaSeparatedListAttribute,
|
85
79
|
"tasks_to_be_done": ArrayAttribute,
|
86
80
|
}
|
87
|
-
|
88
|
-
def get(
|
89
|
-
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
|
90
|
-
) -> GroupInvitation:
|
91
|
-
return cast(GroupInvitation, super().get(id=id, lazy=lazy, **kwargs))
|
gitlab/v4/objects/issues.py
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
from
|
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, client
|
6
8
|
from gitlab import exceptions as exc
|
7
9
|
from gitlab import types
|
8
|
-
from gitlab.base import
|
10
|
+
from gitlab.base import RESTObject
|
9
11
|
from gitlab.mixins import (
|
10
12
|
CreateMixin,
|
11
13
|
CRUDMixin,
|
@@ -50,7 +52,7 @@ class Issue(RESTObject):
|
|
50
52
|
_repr_attr = "title"
|
51
53
|
|
52
54
|
|
53
|
-
class IssueManager(RetrieveMixin
|
55
|
+
class IssueManager(RetrieveMixin[Issue]):
|
54
56
|
_path = "/issues"
|
55
57
|
_obj_cls = Issue
|
56
58
|
_list_filters = (
|
@@ -73,15 +75,12 @@ class IssueManager(RetrieveMixin, RESTManager):
|
|
73
75
|
)
|
74
76
|
_types = {"iids": types.ArrayAttribute, "labels": types.CommaSeparatedListAttribute}
|
75
77
|
|
76
|
-
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Issue:
|
77
|
-
return cast(Issue, super().get(id=id, lazy=lazy, **kwargs))
|
78
|
-
|
79
78
|
|
80
79
|
class GroupIssue(RESTObject):
|
81
80
|
pass
|
82
81
|
|
83
82
|
|
84
|
-
class GroupIssueManager(ListMixin
|
83
|
+
class GroupIssueManager(ListMixin[GroupIssue]):
|
85
84
|
_path = "/groups/{group_id}/issues"
|
86
85
|
_obj_cls = GroupIssue
|
87
86
|
_from_parent_attrs = {"group_id": "id"}
|
@@ -120,7 +119,7 @@ class ProjectIssue(
|
|
120
119
|
|
121
120
|
awardemojis: ProjectIssueAwardEmojiManager
|
122
121
|
discussions: ProjectIssueDiscussionManager
|
123
|
-
links:
|
122
|
+
links: ProjectIssueLinkManager
|
124
123
|
notes: ProjectIssueNoteManager
|
125
124
|
resourcelabelevents: ProjectIssueResourceLabelEventManager
|
126
125
|
resourcemilestoneevents: ProjectIssueResourceMilestoneEventManager
|
@@ -154,8 +153,8 @@ class ProjectIssue(
|
|
154
153
|
@exc.on_http_error(exc.GitlabUpdateError)
|
155
154
|
def reorder(
|
156
155
|
self,
|
157
|
-
move_after_id:
|
158
|
-
move_before_id:
|
156
|
+
move_after_id: int | None = None,
|
157
|
+
move_before_id: int | None = None,
|
159
158
|
**kwargs: Any,
|
160
159
|
) -> None:
|
161
160
|
"""Reorder an issue on a board.
|
@@ -170,7 +169,7 @@ class ProjectIssue(
|
|
170
169
|
GitlabUpdateError: If the issue could not be reordered
|
171
170
|
"""
|
172
171
|
path = f"{self.manager.path}/{self.encoded_id}/reorder"
|
173
|
-
data:
|
172
|
+
data: dict[str, Any] = {}
|
174
173
|
|
175
174
|
if move_after_id is not None:
|
176
175
|
data["move_after_id"] = move_after_id
|
@@ -186,7 +185,7 @@ class ProjectIssue(
|
|
186
185
|
@exc.on_http_error(exc.GitlabGetError)
|
187
186
|
def related_merge_requests(
|
188
187
|
self, **kwargs: Any
|
189
|
-
) ->
|
188
|
+
) -> client.GitlabList | list[dict[str, Any]]:
|
190
189
|
"""List merge requests related to the issue.
|
191
190
|
|
192
191
|
Args:
|
@@ -207,9 +206,7 @@ class ProjectIssue(
|
|
207
206
|
|
208
207
|
@cli.register_custom_action(cls_names="ProjectIssue")
|
209
208
|
@exc.on_http_error(exc.GitlabGetError)
|
210
|
-
def closed_by(
|
211
|
-
self, **kwargs: Any
|
212
|
-
) -> Union[client.GitlabList, List[Dict[str, Any]]]:
|
209
|
+
def closed_by(self, **kwargs: Any) -> client.GitlabList | list[dict[str, Any]]:
|
213
210
|
"""List merge requests that will close the issue when merged.
|
214
211
|
|
215
212
|
Args:
|
@@ -229,7 +226,7 @@ class ProjectIssue(
|
|
229
226
|
return result
|
230
227
|
|
231
228
|
|
232
|
-
class ProjectIssueManager(CRUDMixin
|
229
|
+
class ProjectIssueManager(CRUDMixin[ProjectIssue]):
|
233
230
|
_path = "/projects/{project_id}/issues"
|
234
231
|
_obj_cls = ProjectIssue
|
235
232
|
_from_parent_attrs = {"project_id": "id"}
|
@@ -279,21 +276,20 @@ class ProjectIssueManager(CRUDMixin, RESTManager):
|
|
279
276
|
"updated_at",
|
280
277
|
"due_date",
|
281
278
|
"discussion_locked",
|
282
|
-
)
|
279
|
+
)
|
283
280
|
)
|
284
281
|
_types = {"iids": types.ArrayAttribute, "labels": types.CommaSeparatedListAttribute}
|
285
282
|
|
286
|
-
def get(
|
287
|
-
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
|
288
|
-
) -> ProjectIssue:
|
289
|
-
return cast(ProjectIssue, super().get(id=id, lazy=lazy, **kwargs))
|
290
|
-
|
291
283
|
|
292
284
|
class ProjectIssueLink(ObjectDeleteMixin, RESTObject):
|
293
285
|
_id_attr = "issue_link_id"
|
294
286
|
|
295
287
|
|
296
|
-
class ProjectIssueLinkManager(
|
288
|
+
class ProjectIssueLinkManager(
|
289
|
+
ListMixin[ProjectIssueLink],
|
290
|
+
CreateMixin[ProjectIssueLink],
|
291
|
+
DeleteMixin[ProjectIssueLink],
|
292
|
+
):
|
297
293
|
_path = "/projects/{project_id}/issues/{issue_iid}/links"
|
298
294
|
_obj_cls = ProjectIssueLink
|
299
295
|
_from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
|
@@ -303,8 +299,8 @@ class ProjectIssueLinkManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
|
|
303
299
|
# NOTE(jlvillal): Signature doesn't match CreateMixin.create() so ignore
|
304
300
|
# type error
|
305
301
|
def create( # type: ignore[override]
|
306
|
-
self, data:
|
307
|
-
) ->
|
302
|
+
self, data: dict[str, Any], **kwargs: Any
|
303
|
+
) -> tuple[ProjectIssue, ProjectIssue]:
|
308
304
|
"""Create a new object.
|
309
305
|
|
310
306
|
Args:
|
@@ -320,8 +316,6 @@ class ProjectIssueLinkManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
|
|
320
316
|
GitlabCreateError: If the server cannot perform the request
|
321
317
|
"""
|
322
318
|
self._create_attrs.validate_attrs(data=data)
|
323
|
-
if TYPE_CHECKING:
|
324
|
-
assert self.path is not None
|
325
319
|
server_data = self.gitlab.http_post(self.path, post_data=data, **kwargs)
|
326
320
|
if TYPE_CHECKING:
|
327
321
|
assert isinstance(server_data, dict)
|
gitlab/v4/objects/iterations.py
CHANGED
@@ -1,19 +1,15 @@
|
|
1
1
|
from gitlab import types
|
2
|
-
from gitlab.base import
|
2
|
+
from gitlab.base import RESTObject
|
3
3
|
from gitlab.mixins import ListMixin
|
4
4
|
|
5
|
-
__all__ = [
|
6
|
-
"ProjectIterationManager",
|
7
|
-
"GroupIteration",
|
8
|
-
"GroupIterationManager",
|
9
|
-
]
|
5
|
+
__all__ = ["ProjectIterationManager", "GroupIteration", "GroupIterationManager"]
|
10
6
|
|
11
7
|
|
12
8
|
class GroupIteration(RESTObject):
|
13
9
|
_repr_attr = "title"
|
14
10
|
|
15
11
|
|
16
|
-
class GroupIterationManager(ListMixin
|
12
|
+
class GroupIterationManager(ListMixin[GroupIteration]):
|
17
13
|
_path = "/groups/{group_id}/iterations"
|
18
14
|
_obj_cls = GroupIteration
|
19
15
|
_from_parent_attrs = {"group_id": "id"}
|
@@ -33,7 +29,7 @@ class GroupIterationManager(ListMixin, RESTManager):
|
|
33
29
|
_types = {"in": types.ArrayAttribute}
|
34
30
|
|
35
31
|
|
36
|
-
class ProjectIterationManager(ListMixin
|
32
|
+
class ProjectIterationManager(ListMixin[GroupIteration]):
|
37
33
|
_path = "/projects/{project_id}/iterations"
|
38
34
|
_obj_cls = GroupIteration
|
39
35
|
_from_parent_attrs = {"project_id": "id"}
|