python-gitlab 5.5.0__py3-none-any.whl → 6.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +14 -24
- gitlab/client.py +114 -140
- gitlab/config.py +16 -17
- gitlab/exceptions.py +7 -5
- gitlab/mixins.py +154 -238
- gitlab/types.py +13 -14
- gitlab/utils.py +32 -43
- gitlab/v4/cli.py +50 -53
- 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 +3 -15
- 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 +47 -38
- 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 +54 -76
- 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 +3 -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 +87 -93
- gitlab/v4/objects/variables.py +4 -19
- gitlab/v4/objects/wikis.py +4 -19
- {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info}/METADATA +3 -2
- python_gitlab-6.0.0.dist-info/RECORD +107 -0
- {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info}/WHEEL +1 -1
- python_gitlab-5.5.0.dist-info/RECORD +0 -106
- {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info}/entry_points.txt +0 -0
- {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info/licenses}/AUTHORS +0 -0
- {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.0.dist-info/licenses}/COPYING +0 -0
- {python_gitlab-5.5.0.dist-info → python_gitlab-6.0.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,
|
@@ -34,11 +36,13 @@ from .invitations import GroupInvitationManager # noqa: F401
|
|
34
36
|
from .issues import GroupIssueManager # noqa: F401
|
35
37
|
from .iterations import GroupIterationManager # noqa: F401
|
36
38
|
from .labels import GroupLabelManager # noqa: F401
|
39
|
+
from .member_roles import GroupMemberRoleManager # noqa: F401
|
37
40
|
from .members import ( # noqa: F401
|
38
41
|
GroupBillableMemberManager,
|
39
42
|
GroupMemberAllManager,
|
40
43
|
GroupMemberManager,
|
41
44
|
)
|
45
|
+
from .merge_request_approvals import GroupApprovalRuleManager
|
42
46
|
from .merge_requests import GroupMergeRequestManager # noqa: F401
|
43
47
|
from .milestones import GroupMilestoneManager # noqa: F401
|
44
48
|
from .notification_settings import GroupNotificationSettingsManager # noqa: F401
|
@@ -70,6 +74,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
70
74
|
|
71
75
|
access_tokens: GroupAccessTokenManager
|
72
76
|
accessrequests: GroupAccessRequestManager
|
77
|
+
approval_rules: GroupApprovalRuleManager
|
73
78
|
audit_events: GroupAuditEventManager
|
74
79
|
badges: GroupBadgeManager
|
75
80
|
billable_members: GroupBillableMemberManager
|
@@ -77,7 +82,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
77
82
|
clusters: GroupClusterManager
|
78
83
|
customattributes: GroupCustomAttributeManager
|
79
84
|
deploytokens: GroupDeployTokenManager
|
80
|
-
descendant_groups:
|
85
|
+
descendant_groups: GroupDescendantGroupManager
|
81
86
|
epics: GroupEpicManager
|
82
87
|
exports: GroupExportManager
|
83
88
|
hooks: GroupHookManager
|
@@ -87,7 +92,8 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
87
92
|
issues_statistics: GroupIssuesStatisticsManager
|
88
93
|
iterations: GroupIterationManager
|
89
94
|
labels: GroupLabelManager
|
90
|
-
ldap_group_links:
|
95
|
+
ldap_group_links: GroupLDAPGroupLinkManager
|
96
|
+
member_roles: GroupMemberRoleManager
|
91
97
|
members: GroupMemberManager
|
92
98
|
members_all: GroupMemberAllManager
|
93
99
|
mergerequests: GroupMergeRequestManager
|
@@ -99,11 +105,11 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
99
105
|
pushrules: GroupPushRulesManager
|
100
106
|
registry_repositories: GroupRegistryRepositoryManager
|
101
107
|
runners: GroupRunnerManager
|
102
|
-
subgroups:
|
108
|
+
subgroups: GroupSubgroupManager
|
103
109
|
variables: GroupVariableManager
|
104
110
|
wikis: GroupWikiManager
|
105
|
-
saml_group_links:
|
106
|
-
service_accounts:
|
111
|
+
saml_group_links: GroupSAMLGroupLinkManager
|
112
|
+
service_accounts: GroupServiceAccountManager
|
107
113
|
|
108
114
|
@cli.register_custom_action(cls_names="Group", required=("project_id",))
|
109
115
|
@exc.on_http_error(exc.GitlabTransferProjectError)
|
@@ -123,7 +129,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
123
129
|
|
124
130
|
@cli.register_custom_action(cls_names="Group", required=(), optional=("group_id",))
|
125
131
|
@exc.on_http_error(exc.GitlabGroupTransferError)
|
126
|
-
def transfer(self, group_id:
|
132
|
+
def transfer(self, group_id: int | None = None, **kwargs: Any) -> None:
|
127
133
|
"""Transfer the group to a new parent group or make it a top-level group.
|
128
134
|
|
129
135
|
Requires GitLab ≥14.6.
|
@@ -147,7 +153,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
147
153
|
@exc.on_http_error(exc.GitlabSearchError)
|
148
154
|
def search(
|
149
155
|
self, scope: str, search: str, **kwargs: Any
|
150
|
-
) ->
|
156
|
+
) -> gitlab.GitlabList | list[dict[str, Any]]:
|
151
157
|
"""Search the group resources matching the provided string.
|
152
158
|
|
153
159
|
Args:
|
@@ -191,7 +197,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
191
197
|
self,
|
192
198
|
group_id: int,
|
193
199
|
group_access: int,
|
194
|
-
expires_at:
|
200
|
+
expires_at: str | None = None,
|
195
201
|
**kwargs: Any,
|
196
202
|
) -> None:
|
197
203
|
"""Share the group with a group.
|
@@ -251,7 +257,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
251
257
|
self.manager.gitlab.http_post(path, **kwargs)
|
252
258
|
|
253
259
|
|
254
|
-
class GroupManager(CRUDMixin
|
260
|
+
class GroupManager(CRUDMixin[Group]):
|
255
261
|
_path = "/groups"
|
256
262
|
_obj_cls = Group
|
257
263
|
_list_filters = (
|
@@ -313,22 +319,19 @@ class GroupManager(CRUDMixin, RESTManager):
|
|
313
319
|
"extra_shared_runners_minutes_limit",
|
314
320
|
"prevent_forking_outside_group",
|
315
321
|
"shared_runners_setting",
|
316
|
-
)
|
322
|
+
)
|
317
323
|
)
|
318
324
|
_types = {"avatar": types.ImageAttribute, "skip_groups": types.ArrayAttribute}
|
319
325
|
|
320
|
-
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Group:
|
321
|
-
return cast(Group, super().get(id=id, lazy=lazy, **kwargs))
|
322
|
-
|
323
326
|
@exc.on_http_error(exc.GitlabImportError)
|
324
327
|
def import_group(
|
325
328
|
self,
|
326
329
|
file: BinaryIO,
|
327
330
|
path: str,
|
328
331
|
name: str,
|
329
|
-
parent_id:
|
332
|
+
parent_id: int | str | None = None,
|
330
333
|
**kwargs: Any,
|
331
|
-
) ->
|
334
|
+
) -> dict[str, Any] | requests.Response:
|
332
335
|
"""Import a group from an archive file.
|
333
336
|
|
334
337
|
Args:
|
@@ -347,7 +350,7 @@ class GroupManager(CRUDMixin, RESTManager):
|
|
347
350
|
A representation of the import status.
|
348
351
|
"""
|
349
352
|
files = {"file": ("file.tar.gz", file, "application/octet-stream")}
|
350
|
-
data:
|
353
|
+
data: dict[str, Any] = {"path": path, "name": name}
|
351
354
|
if parent_id is not None:
|
352
355
|
data["parent_id"] = parent_id
|
353
356
|
|
@@ -356,13 +359,7 @@ class GroupManager(CRUDMixin, RESTManager):
|
|
356
359
|
)
|
357
360
|
|
358
361
|
|
359
|
-
class
|
360
|
-
pass
|
361
|
-
|
362
|
-
|
363
|
-
class GroupSubgroupManager(ListMixin, RESTManager):
|
364
|
-
_path = "/groups/{group_id}/subgroups"
|
365
|
-
_obj_cls: Union[Type["GroupDescendantGroup"], Type[GroupSubgroup]] = GroupSubgroup
|
362
|
+
class SubgroupBaseManager(ListMixin[TObjCls]):
|
366
363
|
_from_parent_attrs = {"group_id": "id"}
|
367
364
|
_list_filters = (
|
368
365
|
"skip_groups",
|
@@ -378,24 +375,33 @@ class GroupSubgroupManager(ListMixin, RESTManager):
|
|
378
375
|
_types = {"skip_groups": types.ArrayAttribute}
|
379
376
|
|
380
377
|
|
378
|
+
class GroupSubgroup(RESTObject):
|
379
|
+
pass
|
380
|
+
|
381
|
+
|
382
|
+
class GroupSubgroupManager(SubgroupBaseManager[GroupSubgroup]):
|
383
|
+
_path = "/groups/{group_id}/subgroups"
|
384
|
+
_obj_cls = GroupSubgroup
|
385
|
+
|
386
|
+
|
381
387
|
class GroupDescendantGroup(RESTObject):
|
382
388
|
pass
|
383
389
|
|
384
390
|
|
385
|
-
class GroupDescendantGroupManager(
|
391
|
+
class GroupDescendantGroupManager(SubgroupBaseManager[GroupDescendantGroup]):
|
386
392
|
"""
|
387
393
|
This manager inherits from GroupSubgroupManager as descendant groups
|
388
394
|
share all attributes with subgroups, except the path and object class.
|
389
395
|
"""
|
390
396
|
|
391
397
|
_path = "/groups/{group_id}/descendant_groups"
|
392
|
-
_obj_cls
|
398
|
+
_obj_cls = GroupDescendantGroup
|
393
399
|
|
394
400
|
|
395
401
|
class GroupLDAPGroupLink(RESTObject):
|
396
402
|
_repr_attr = "provider"
|
397
403
|
|
398
|
-
def _get_link_attrs(self) ->
|
404
|
+
def _get_link_attrs(self) -> dict[str, str]:
|
399
405
|
# https://docs.gitlab.com/ee/api/groups.html#add-ldap-group-link-with-cn-or-filter
|
400
406
|
# https://docs.gitlab.com/ee/api/groups.html#delete-ldap-group-link-with-cn-or-filter
|
401
407
|
# We can tell what attribute to use based on the data returned
|
@@ -424,9 +430,13 @@ class GroupLDAPGroupLink(RESTObject):
|
|
424
430
|
)
|
425
431
|
|
426
432
|
|
427
|
-
class GroupLDAPGroupLinkManager(
|
433
|
+
class GroupLDAPGroupLinkManager(
|
434
|
+
ListMixin[GroupLDAPGroupLink],
|
435
|
+
CreateMixin[GroupLDAPGroupLink],
|
436
|
+
DeleteMixin[GroupLDAPGroupLink],
|
437
|
+
):
|
428
438
|
_path = "/groups/{group_id}/ldap_group_links"
|
429
|
-
_obj_cls
|
439
|
+
_obj_cls = GroupLDAPGroupLink
|
430
440
|
_from_parent_attrs = {"group_id": "id"}
|
431
441
|
_create_attrs = RequiredOptional(
|
432
442
|
required=("provider", "group_access"), exclusive=("cn", "filter")
|
@@ -438,13 +448,8 @@ class GroupSAMLGroupLink(ObjectDeleteMixin, RESTObject):
|
|
438
448
|
_repr_attr = "name"
|
439
449
|
|
440
450
|
|
441
|
-
class GroupSAMLGroupLinkManager(NoUpdateMixin
|
451
|
+
class GroupSAMLGroupLinkManager(NoUpdateMixin[GroupSAMLGroupLink]):
|
442
452
|
_path = "/groups/{group_id}/saml_group_links"
|
443
|
-
_obj_cls
|
453
|
+
_obj_cls = GroupSAMLGroupLink
|
444
454
|
_from_parent_attrs = {"group_id": "id"}
|
445
455
|
_create_attrs = RequiredOptional(required=("saml_group_name", "access_level"))
|
446
|
-
|
447
|
-
def get(
|
448
|
-
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
|
449
|
-
) -> GroupSAMLGroupLink:
|
450
|
-
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"}
|