summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gitlab/base.py12
-rw-r--r--gitlab/mixins.py6
-rw-r--r--gitlab/tests/mixins/test_mixin_methods.py32
-rw-r--r--gitlab/v4/cli.py8
-rw-r--r--gitlab/v4/objects/appearance.py7
-rw-r--r--gitlab/v4/objects/applications.py6
-rw-r--r--gitlab/v4/objects/award_emojis.py14
-rw-r--r--gitlab/v4/objects/badges.py10
-rw-r--r--gitlab/v4/objects/boards.py14
-rw-r--r--gitlab/v4/objects/branches.py10
-rw-r--r--gitlab/v4/objects/broadcast_messages.py10
-rw-r--r--gitlab/v4/objects/clusters.py24
-rw-r--r--gitlab/v4/objects/commits.py18
-rw-r--r--gitlab/v4/objects/deploy_keys.py6
-rw-r--r--gitlab/v4/objects/deploy_tokens.py14
-rw-r--r--gitlab/v4/objects/deployments.py6
-rw-r--r--gitlab/v4/objects/discussions.py14
-rw-r--r--gitlab/v4/objects/environments.py6
-rw-r--r--gitlab/v4/objects/epics.py16
-rw-r--r--gitlab/v4/objects/export_import.py4
-rw-r--r--gitlab/v4/objects/files.py14
-rw-r--r--gitlab/v4/objects/geo_nodes.py7
-rw-r--r--gitlab/v4/objects/groups.py13
-rw-r--r--gitlab/v4/objects/hooks.py16
-rw-r--r--gitlab/v4/objects/issues.py15
-rw-r--r--gitlab/v4/objects/labels.py18
-rw-r--r--gitlab/v4/objects/members.py18
-rw-r--r--gitlab/v4/objects/merge_request_approvals.py31
-rw-r--r--gitlab/v4/objects/merge_requests.py13
-rw-r--r--gitlab/v4/objects/milestones.py22
-rw-r--r--gitlab/v4/objects/notes.py34
-rw-r--r--gitlab/v4/objects/notification_settings.py7
-rw-r--r--gitlab/v4/objects/pages.py8
-rw-r--r--gitlab/v4/objects/pipelines.py16
-rw-r--r--gitlab/v4/objects/projects.py20
-rw-r--r--gitlab/v4/objects/push_rules.py12
-rw-r--r--gitlab/v4/objects/releases.py12
-rw-r--r--gitlab/v4/objects/runners.py17
-rw-r--r--gitlab/v4/objects/settings.py7
-rw-r--r--gitlab/v4/objects/snippets.py20
-rw-r--r--gitlab/v4/objects/tags.py10
-rw-r--r--gitlab/v4/objects/triggers.py6
-rw-r--r--gitlab/v4/objects/users.py37
-rw-r--r--gitlab/v4/objects/variables.py30
-rw-r--r--gitlab/v4/objects/wikis.py8
45 files changed, 362 insertions, 286 deletions
diff --git a/gitlab/base.py b/gitlab/base.py
index 5eb1118..7b4e3f8 100644
--- a/gitlab/base.py
+++ b/gitlab/base.py
@@ -17,12 +17,13 @@
import importlib
from types import ModuleType
-from typing import Any, Dict, Optional, Tuple, Type
+from typing import Any, Dict, NamedTuple, Optional, Tuple, Type
from .client import Gitlab, GitlabList
from gitlab import types as g_types
__all__ = [
+ "RequiredOptional",
"RESTObject",
"RESTObjectList",
"RESTManager",
@@ -249,6 +250,11 @@ class RESTObjectList(object):
return self._list.total
+class RequiredOptional(NamedTuple):
+ required: Tuple[str, ...] = tuple()
+ optional: Tuple[str, ...] = tuple()
+
+
class RESTManager(object):
"""Base class for CRUD operations on objects.
@@ -258,8 +264,8 @@ class RESTManager(object):
``_obj_cls``: The class of objects that will be created
"""
- _create_attrs: Tuple[Tuple[str, ...], Tuple[str, ...]] = (tuple(), tuple())
- _update_attrs: Tuple[Tuple[str, ...], Tuple[str, ...]] = (tuple(), tuple())
+ _create_attrs: RequiredOptional = RequiredOptional()
+ _update_attrs: RequiredOptional = RequiredOptional()
_path: Optional[str] = None
_obj_cls: Optional[Type[RESTObject]] = None
_from_parent_attrs: Dict[str, Any] = {}
diff --git a/gitlab/mixins.py b/gitlab/mixins.py
index fd77904..a809151 100644
--- a/gitlab/mixins.py
+++ b/gitlab/mixins.py
@@ -267,7 +267,7 @@ class CreateMixin(_RestManagerBase):
def _check_missing_create_attrs(self, data: Dict[str, Any]) -> None:
missing = []
- for attr in self._create_attrs[0]:
+ for attr in self._create_attrs.required:
if attr not in data:
missing.append(attr)
continue
@@ -339,7 +339,7 @@ class UpdateMixin(_RestManagerBase):
# Remove the id field from the required list as it was previously moved
# to the http path.
required = tuple(
- [k for k in self._update_attrs[0] if k != self._obj_cls._id_attr]
+ [k for k in self._update_attrs.required if k != self._obj_cls._id_attr]
)
missing = []
for attr in required:
@@ -518,7 +518,7 @@ class SaveMixin(_RestObjectBase):
def _get_updated_data(self) -> Dict[str, Any]:
updated_data = {}
- for attr in self.manager._update_attrs[0]:
+ for attr in self.manager._update_attrs.required:
# Get everything required, no matter if it's been updated
updated_data[attr] = getattr(self, attr)
# Add the updated attributes
diff --git a/gitlab/tests/mixins/test_mixin_methods.py b/gitlab/tests/mixins/test_mixin_methods.py
index 1dafa74..557c020 100644
--- a/gitlab/tests/mixins/test_mixin_methods.py
+++ b/gitlab/tests/mixins/test_mixin_methods.py
@@ -131,7 +131,9 @@ def test_list_other_url(gl):
def test_create_mixin_missing_attrs(gl):
class M(CreateMixin, FakeManager):
- _create_attrs = (("foo",), ("bar", "baz"))
+ _create_attrs = base.RequiredOptional(
+ required=("foo",), optional=("bar", "baz")
+ )
mgr = M(gl)
data = {"foo": "bar", "baz": "blah"}
@@ -145,8 +147,10 @@ def test_create_mixin_missing_attrs(gl):
def test_create_mixin(gl):
class M(CreateMixin, FakeManager):
- _create_attrs = (("foo",), ("bar", "baz"))
- _update_attrs = (("foo",), ("bam",))
+ _create_attrs = base.RequiredOptional(
+ required=("foo",), optional=("bar", "baz")
+ )
+ _update_attrs = base.RequiredOptional(required=("foo",), optional=("bam",))
@urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests", method="post")
def resp_cont(url, request):
@@ -164,8 +168,10 @@ def test_create_mixin(gl):
def test_create_mixin_custom_path(gl):
class M(CreateMixin, FakeManager):
- _create_attrs = (("foo",), ("bar", "baz"))
- _update_attrs = (("foo",), ("bam",))
+ _create_attrs = base.RequiredOptional(
+ required=("foo",), optional=("bar", "baz")
+ )
+ _update_attrs = base.RequiredOptional(required=("foo",), optional=("bam",))
@urlmatch(scheme="http", netloc="localhost", path="/api/v4/others", method="post")
def resp_cont(url, request):
@@ -183,7 +189,9 @@ def test_create_mixin_custom_path(gl):
def test_update_mixin_missing_attrs(gl):
class M(UpdateMixin, FakeManager):
- _update_attrs = (("foo",), ("bar", "baz"))
+ _update_attrs = base.RequiredOptional(
+ required=("foo",), optional=("bar", "baz")
+ )
mgr = M(gl)
data = {"foo": "bar", "baz": "blah"}
@@ -197,8 +205,10 @@ def test_update_mixin_missing_attrs(gl):
def test_update_mixin(gl):
class M(UpdateMixin, FakeManager):
- _create_attrs = (("foo",), ("bar", "baz"))
- _update_attrs = (("foo",), ("bam",))
+ _create_attrs = base.RequiredOptional(
+ required=("foo",), optional=("bar", "baz")
+ )
+ _update_attrs = base.RequiredOptional(required=("foo",), optional=("bam",))
@urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests/42", method="put")
def resp_cont(url, request):
@@ -216,8 +226,10 @@ def test_update_mixin(gl):
def test_update_mixin_no_id(gl):
class M(UpdateMixin, FakeManager):
- _create_attrs = (("foo",), ("bar", "baz"))
- _update_attrs = (("foo",), ("bam",))
+ _create_attrs = base.RequiredOptional(
+ required=("foo",), optional=("bar", "baz")
+ )
+ _update_attrs = base.RequiredOptional(required=("foo",), optional=("bam",))
@urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests", method="put")
def resp_cont(url, request):
diff --git a/gitlab/v4/cli.py b/gitlab/v4/cli.py
index df645bf..d036d12 100644
--- a/gitlab/v4/cli.py
+++ b/gitlab/v4/cli.py
@@ -177,11 +177,11 @@ def _populate_sub_parser_by_class(cls, sub_parser):
]
if action_name == "create":
- for x in mgr_cls._create_attrs[0]:
+ for x in mgr_cls._create_attrs.required:
sub_parser_action.add_argument(
"--%s" % x.replace("_", "-"), required=True
)
- for x in mgr_cls._create_attrs[1]:
+ for x in mgr_cls._create_attrs.optional:
sub_parser_action.add_argument(
"--%s" % x.replace("_", "-"), required=False
)
@@ -191,13 +191,13 @@ def _populate_sub_parser_by_class(cls, sub_parser):
id_attr = cls._id_attr.replace("_", "-")
sub_parser_action.add_argument("--%s" % id_attr, required=True)
- for x in mgr_cls._update_attrs[0]:
+ for x in mgr_cls._update_attrs.required:
if x != cls._id_attr:
sub_parser_action.add_argument(
"--%s" % x.replace("_", "-"), required=True
)
- for x in mgr_cls._update_attrs[1]:
+ for x in mgr_cls._update_attrs.optional:
if x != cls._id_attr:
sub_parser_action.add_argument(
"--%s" % x.replace("_", "-"), required=False
diff --git a/gitlab/v4/objects/appearance.py b/gitlab/v4/objects/appearance.py
index bbb3ff2..9d81ad6 100644
--- a/gitlab/v4/objects/appearance.py
+++ b/gitlab/v4/objects/appearance.py
@@ -1,5 +1,5 @@
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import GetWithoutIdMixin, SaveMixin, UpdateMixin
@@ -16,9 +16,8 @@ class ApplicationAppearance(SaveMixin, RESTObject):
class ApplicationAppearanceManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
_path = "/application/appearance"
_obj_cls = ApplicationAppearance
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"title",
"description",
"logo",
diff --git a/gitlab/v4/objects/applications.py b/gitlab/v4/objects/applications.py
index ddb9d23..c91dee1 100644
--- a/gitlab/v4/objects/applications.py
+++ b/gitlab/v4/objects/applications.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CreateMixin, DeleteMixin, ListMixin, ObjectDeleteMixin
__all__ = [
@@ -15,4 +15,6 @@ class Application(ObjectDeleteMixin, RESTObject):
class ApplicationManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/applications"
_obj_cls = Application
- _create_attrs = (("name", "redirect_uri", "scopes"), ("confidential",))
+ _create_attrs = RequiredOptional(
+ required=("name", "redirect_uri", "scopes"), optional=("confidential",)
+ )
diff --git a/gitlab/v4/objects/award_emojis.py b/gitlab/v4/objects/award_emojis.py
index 806121c..1070fc7 100644
--- a/gitlab/v4/objects/award_emojis.py
+++ b/gitlab/v4/objects/award_emojis.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin
@@ -26,7 +26,7 @@ class ProjectIssueAwardEmojiManager(NoUpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/issues/%(issue_iid)s/award_emoji"
_obj_cls = ProjectIssueAwardEmoji
_from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
- _create_attrs = (("name",), tuple())
+ _create_attrs = RequiredOptional(required=("name",))
class ProjectIssueNoteAwardEmoji(ObjectDeleteMixin, RESTObject):
@@ -43,7 +43,7 @@ class ProjectIssueNoteAwardEmojiManager(NoUpdateMixin, RESTManager):
"issue_iid": "issue_iid",
"note_id": "id",
}
- _create_attrs = (("name",), tuple())
+ _create_attrs = RequiredOptional(required=("name",))
class ProjectMergeRequestAwardEmoji(ObjectDeleteMixin, RESTObject):
@@ -54,7 +54,7 @@ class ProjectMergeRequestAwardEmojiManager(NoUpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/award_emoji"
_obj_cls = ProjectMergeRequestAwardEmoji
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
- _create_attrs = (("name",), tuple())
+ _create_attrs = RequiredOptional(required=("name",))
class ProjectMergeRequestNoteAwardEmoji(ObjectDeleteMixin, RESTObject):
@@ -72,7 +72,7 @@ class ProjectMergeRequestNoteAwardEmojiManager(NoUpdateMixin, RESTManager):
"mr_iid": "mr_iid",
"note_id": "id",
}
- _create_attrs = (("name",), tuple())
+ _create_attrs = RequiredOptional(required=("name",))
class ProjectSnippetAwardEmoji(ObjectDeleteMixin, RESTObject):
@@ -83,7 +83,7 @@ class ProjectSnippetAwardEmojiManager(NoUpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/snippets/%(snippet_id)s/award_emoji"
_obj_cls = ProjectSnippetAwardEmoji
_from_parent_attrs = {"project_id": "project_id", "snippet_id": "id"}
- _create_attrs = (("name",), tuple())
+ _create_attrs = RequiredOptional(required=("name",))
class ProjectSnippetNoteAwardEmoji(ObjectDeleteMixin, RESTObject):
@@ -101,4 +101,4 @@ class ProjectSnippetNoteAwardEmojiManager(NoUpdateMixin, RESTManager):
"snippet_id": "snippet_id",
"note_id": "id",
}
- _create_attrs = (("name",), tuple())
+ _create_attrs = RequiredOptional(required=("name",))
diff --git a/gitlab/v4/objects/badges.py b/gitlab/v4/objects/badges.py
index 4edcc51..ba1d41f 100644
--- a/gitlab/v4/objects/badges.py
+++ b/gitlab/v4/objects/badges.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import BadgeRenderMixin, CRUDMixin, ObjectDeleteMixin, SaveMixin
@@ -18,8 +18,8 @@ class GroupBadgeManager(BadgeRenderMixin, CRUDMixin, RESTManager):
_path = "/groups/%(group_id)s/badges"
_obj_cls = GroupBadge
_from_parent_attrs = {"group_id": "id"}
- _create_attrs = (("link_url", "image_url"), tuple())
- _update_attrs = (tuple(), ("link_url", "image_url"))
+ _create_attrs = RequiredOptional(required=("link_url", "image_url"))
+ _update_attrs = RequiredOptional(optional=("link_url", "image_url"))
class ProjectBadge(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -30,5 +30,5 @@ class ProjectBadgeManager(BadgeRenderMixin, CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/badges"
_obj_cls = ProjectBadge
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("link_url", "image_url"), tuple())
- _update_attrs = (tuple(), ("link_url", "image_url"))
+ _create_attrs = RequiredOptional(required=("link_url", "image_url"))
+ _update_attrs = RequiredOptional(optional=("link_url", "image_url"))
diff --git a/gitlab/v4/objects/boards.py b/gitlab/v4/objects/boards.py
index d0176b7..cf36af1 100644
--- a/gitlab/v4/objects/boards.py
+++ b/gitlab/v4/objects/boards.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
@@ -22,8 +22,8 @@ class GroupBoardListManager(CRUDMixin, RESTManager):
_path = "/groups/%(group_id)s/boards/%(board_id)s/lists"
_obj_cls = GroupBoardList
_from_parent_attrs = {"group_id": "group_id", "board_id": "id"}
- _create_attrs = (("label_id",), tuple())
- _update_attrs = (("position",), tuple())
+ _create_attrs = RequiredOptional(required=("label_id",))
+ _update_attrs = RequiredOptional(required=("position",))
class GroupBoard(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -34,7 +34,7 @@ class GroupBoardManager(CRUDMixin, RESTManager):
_path = "/groups/%(group_id)s/boards"
_obj_cls = GroupBoard
_from_parent_attrs = {"group_id": "id"}
- _create_attrs = (("name",), tuple())
+ _create_attrs = RequiredOptional(required=("name",))
class ProjectBoardList(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -45,8 +45,8 @@ class ProjectBoardListManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/boards/%(board_id)s/lists"
_obj_cls = ProjectBoardList
_from_parent_attrs = {"project_id": "project_id", "board_id": "id"}
- _create_attrs = (("label_id",), tuple())
- _update_attrs = (("position",), tuple())
+ _create_attrs = RequiredOptional(required=("label_id",))
+ _update_attrs = RequiredOptional(required=("position",))
class ProjectBoard(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -57,4 +57,4 @@ class ProjectBoardManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/boards"
_obj_cls = ProjectBoard
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("name",), tuple())
+ _create_attrs = RequiredOptional(required=("name",))
diff --git a/gitlab/v4/objects/branches.py b/gitlab/v4/objects/branches.py
index ff9ed99..11e53a0 100644
--- a/gitlab/v4/objects/branches.py
+++ b/gitlab/v4/objects/branches.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin
@@ -64,7 +64,7 @@ class ProjectBranchManager(NoUpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/repository/branches"
_obj_cls = ProjectBranch
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("branch", "ref"), tuple())
+ _create_attrs = RequiredOptional(required=("branch", "ref"))
class ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):
@@ -75,9 +75,9 @@ class ProjectProtectedBranchManager(NoUpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/protected_branches"
_obj_cls = ProjectProtectedBranch
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (
- ("name",),
- (
+ _create_attrs = RequiredOptional(
+ required=("name",),
+ optional=(
"push_access_level",
"merge_access_level",
"unprotect_access_level",
diff --git a/gitlab/v4/objects/broadcast_messages.py b/gitlab/v4/objects/broadcast_messages.py
index dc2cb94..d6de53f 100644
--- a/gitlab/v4/objects/broadcast_messages.py
+++ b/gitlab/v4/objects/broadcast_messages.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
@@ -16,5 +16,9 @@ class BroadcastMessageManager(CRUDMixin, RESTManager):
_path = "/broadcast_messages"
_obj_cls = BroadcastMessage
- _create_attrs = (("message",), ("starts_at", "ends_at", "color", "font"))
- _update_attrs = (tuple(), ("message", "starts_at", "ends_at", "color", "font"))
+ _create_attrs = RequiredOptional(
+ required=("message",), optional=("starts_at", "ends_at", "color", "font")
+ )
+ _update_attrs = RequiredOptional(
+ optional=("message", "starts_at", "ends_at", "color", "font")
+ )
diff --git a/gitlab/v4/objects/clusters.py b/gitlab/v4/objects/clusters.py
index 2a7064e..50b3fa3 100644
--- a/gitlab/v4/objects/clusters.py
+++ b/gitlab/v4/objects/clusters.py
@@ -1,5 +1,5 @@
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, CreateMixin, ObjectDeleteMixin, SaveMixin
@@ -19,13 +19,12 @@ class GroupClusterManager(CRUDMixin, RESTManager):
_path = "/groups/%(group_id)s/clusters"
_obj_cls = GroupCluster
_from_parent_attrs = {"group_id": "id"}
- _create_attrs = (
- ("name", "platform_kubernetes_attributes"),
- ("domain", "enabled", "managed", "environment_scope"),
+ _create_attrs = RequiredOptional(
+ required=("name", "platform_kubernetes_attributes"),
+ optional=("domain", "enabled", "managed", "environment_scope"),
)
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"name",
"domain",
"management_project_id",
@@ -64,13 +63,12 @@ class ProjectClusterManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/clusters"
_obj_cls = ProjectCluster
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (
- ("name", "platform_kubernetes_attributes"),
- ("domain", "enabled", "managed", "environment_scope"),
+ _create_attrs = RequiredOptional(
+ required=("name", "platform_kubernetes_attributes"),
+ optional=("domain", "enabled", "managed", "environment_scope"),
)
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"name",
"domain",
"management_project_id",
diff --git a/gitlab/v4/objects/commits.py b/gitlab/v4/objects/commits.py
index 1d66e23..bb81407 100644
--- a/gitlab/v4/objects/commits.py
+++ b/gitlab/v4/objects/commits.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CreateMixin, ListMixin, RefreshMixin, RetrieveMixin
from .discussions import ProjectCommitDiscussionManager
@@ -139,9 +139,9 @@ class ProjectCommitManager(RetrieveMixin, CreateMixin, RESTManager):
_path = "/projects/%(project_id)s/repository/commits"
_obj_cls = ProjectCommit
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (
- ("branch", "commit_message", "actions"),
- ("author_email", "author_name"),
+ _create_attrs = RequiredOptional(
+ required=("branch", "commit_message", "actions"),
+ optional=("author_email", "author_name"),
)
@@ -154,7 +154,9 @@ class ProjectCommitCommentManager(ListMixin, CreateMixin, RESTManager):
_path = "/projects/%(project_id)s/repository/commits/%(commit_id)s" "/comments"
_obj_cls = ProjectCommitComment
_from_parent_attrs = {"project_id": "project_id", "commit_id": "id"}
- _create_attrs = (("note",), ("path", "line", "line_type"))
+ _create_attrs = RequiredOptional(
+ required=("note",), optional=("path", "line", "line_type")
+ )
class ProjectCommitStatus(RESTObject, RefreshMixin):
@@ -165,9 +167,9 @@ class ProjectCommitStatusManager(ListMixin, CreateMixin, RESTManager):
_path = "/projects/%(project_id)s/repository/commits/%(commit_id)s" "/statuses"
_obj_cls = ProjectCommitStatus
_from_parent_attrs = {"project_id": "project_id", "commit_id": "id"}
- _create_attrs = (
- ("state",),
- ("description", "name", "context", "ref", "target_url", "coverage"),
+ _create_attrs = RequiredOptional(
+ required=("state",),
+ optional=("description", "name", "context", "ref", "target_url", "coverage"),
)
@exc.on_http_error(exc.GitlabCreateError)
diff --git a/gitlab/v4/objects/deploy_keys.py b/gitlab/v4/objects/deploy_keys.py
index d674c04..9c3dbfd 100644
--- a/gitlab/v4/objects/deploy_keys.py
+++ b/gitlab/v4/objects/deploy_keys.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ListMixin, ObjectDeleteMixin, SaveMixin
@@ -29,8 +29,8 @@ class ProjectKeyManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/deploy_keys"
_obj_cls = ProjectKey
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("title", "key"), ("can_push",))
- _update_attrs = (tuple(), ("title", "can_push"))
+ _create_attrs = RequiredOptional(required=("title", "key"), optional=("can_push",))
+ _update_attrs = RequiredOptional(optional=("title", "can_push"))
@cli.register_custom_action("ProjectKeyManager", ("key_id",))
@exc.on_http_error(exc.GitlabProjectDeployKeyError)
diff --git a/gitlab/v4/objects/deploy_tokens.py b/gitlab/v4/objects/deploy_tokens.py
index b9d0bad..59cccd4 100644
--- a/gitlab/v4/objects/deploy_tokens.py
+++ b/gitlab/v4/objects/deploy_tokens.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CreateMixin, DeleteMixin, ListMixin, ObjectDeleteMixin
@@ -29,12 +29,12 @@ class GroupDeployTokenManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/groups/%(group_id)s/deploy_tokens"
_from_parent_attrs = {"group_id": "id"}
_obj_cls = GroupDeployToken
- _create_attrs = (
- (
+ _create_attrs = RequiredOptional(
+ required=(
"name",
"scopes",
),
- (
+ optional=(
"expires_at",
"username",
),
@@ -49,12 +49,12 @@ class ProjectDeployTokenManager(ListMixin, CreateMixin, DeleteMixin, RESTManager
_path = "/projects/%(project_id)s/deploy_tokens"
_from_parent_attrs = {"project_id": "id"}
_obj_cls = ProjectDeployToken
- _create_attrs = (
- (
+ _create_attrs = RequiredOptional(
+ required=(
"name",
"scopes",
),
- (
+ optional=(
"expires_at",
"username",
),
diff --git a/gitlab/v4/objects/deployments.py b/gitlab/v4/objects/deployments.py
index 300d26b..395bc24 100644
--- a/gitlab/v4/objects/deployments.py
+++ b/gitlab/v4/objects/deployments.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CreateMixin, RetrieveMixin, SaveMixin, UpdateMixin
@@ -17,4 +17,6 @@ class ProjectDeploymentManager(RetrieveMixin, CreateMixin, UpdateMixin, RESTMana
_obj_cls = ProjectDeployment
_from_parent_attrs = {"project_id": "id"}
_list_filters = ("order_by", "sort")
- _create_attrs = (("sha", "ref", "tag", "status", "environment"), tuple())
+ _create_attrs = RequiredOptional(
+ required=("sha", "ref", "tag", "status", "environment")
+ )
diff --git a/gitlab/v4/objects/discussions.py b/gitlab/v4/objects/discussions.py
index b65c27b..3477158 100644
--- a/gitlab/v4/objects/discussions.py
+++ b/gitlab/v4/objects/discussions.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CreateMixin, RetrieveMixin, SaveMixin, UpdateMixin
from .notes import (
ProjectCommitDiscussionNoteManager,
@@ -28,7 +28,7 @@ class ProjectCommitDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
_path = "/projects/%(project_id)s/repository/commits/%(commit_id)s/" "discussions"
_obj_cls = ProjectCommitDiscussion
_from_parent_attrs = {"project_id": "project_id", "commit_id": "id"}
- _create_attrs = (("body",), ("created_at",))
+ _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
class ProjectIssueDiscussion(RESTObject):
@@ -39,7 +39,7 @@ class ProjectIssueDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
_path = "/projects/%(project_id)s/issues/%(issue_iid)s/discussions"
_obj_cls = ProjectIssueDiscussion
_from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
- _create_attrs = (("body",), ("created_at",))
+ _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
class ProjectMergeRequestDiscussion(SaveMixin, RESTObject):
@@ -52,8 +52,10 @@ class ProjectMergeRequestDiscussionManager(
_path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/discussions"
_obj_cls = ProjectMergeRequestDiscussion
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
- _create_attrs = (("body",), ("created_at", "position"))
- _update_attrs = (("resolved",), tuple())
+ _create_attrs = RequiredOptional(
+ required=("body",), optional=("created_at", "position")
+ )
+ _update_attrs = RequiredOptional(required=("resolved",))
class ProjectSnippetDiscussion(RESTObject):
@@ -64,4 +66,4 @@ class ProjectSnippetDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
_path = "/projects/%(project_id)s/snippets/%(snippet_id)s/discussions"
_obj_cls = ProjectSnippetDiscussion
_from_parent_attrs = {"project_id": "project_id", "snippet_id": "id"}
- _create_attrs = (("body",), ("created_at",))
+ _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
diff --git a/gitlab/v4/objects/environments.py b/gitlab/v4/objects/environments.py
index d969203..f540927 100644
--- a/gitlab/v4/objects/environments.py
+++ b/gitlab/v4/objects/environments.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CreateMixin,
DeleteMixin,
@@ -40,5 +40,5 @@ class ProjectEnvironmentManager(
_path = "/projects/%(project_id)s/environments"
_obj_cls = ProjectEnvironment
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("name",), ("external_url",))
- _update_attrs = (tuple(), ("name", "external_url"))
+ _create_attrs = RequiredOptional(required=("name",), optional=("external_url",))
+ _update_attrs = RequiredOptional(optional=("name", "external_url"))
diff --git a/gitlab/v4/objects/epics.py b/gitlab/v4/objects/epics.py
index 8cf6fc3..600378d 100644
--- a/gitlab/v4/objects/epics.py
+++ b/gitlab/v4/objects/epics.py
@@ -1,6 +1,6 @@
from gitlab import types
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CRUDMixin,
CreateMixin,
@@ -34,10 +34,12 @@ class GroupEpicManager(CRUDMixin, RESTManager):
_obj_cls = GroupEpic
_from_parent_attrs = {"group_id": "id"}
_list_filters = ("author_id", "labels", "order_by", "sort", "search")
- _create_attrs = (("title",), ("labels", "description", "start_date", "end_date"))
- _update_attrs = (
- tuple(),
- ("title", "labels", "description", "start_date", "end_date"),
+ _create_attrs = RequiredOptional(
+ required=("title",),
+ optional=("labels", "description", "start_date", "end_date"),
+ )
+ _update_attrs = RequiredOptional(
+ optional=("title", "labels", "description", "start_date", "end_date"),
)
_types = {"labels": types.ListAttribute}
@@ -73,8 +75,8 @@ class GroupEpicIssueManager(
_path = "/groups/%(group_id)s/epics/%(epic_iid)s/issues"
_obj_cls = GroupEpicIssue
_from_parent_attrs = {"group_id": "group_id", "epic_iid": "iid"}
- _create_attrs = (("issue_id",), tuple())
- _update_attrs = (tuple(), ("move_before_id", "move_after_id"))
+ _create_attrs = RequiredOptional(required=("issue_id",))
+ _update_attrs = RequiredOptional(optional=("move_before_id", "move_after_id"))
@exc.on_http_error(exc.GitlabCreateError)
def create(self, data, **kwargs):
diff --git a/gitlab/v4/objects/export_import.py b/gitlab/v4/objects/export_import.py
index 054517c..050874b 100644
--- a/gitlab/v4/objects/export_import.py
+++ b/gitlab/v4/objects/export_import.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CreateMixin, DownloadMixin, GetWithoutIdMixin, RefreshMixin
@@ -42,7 +42,7 @@ class ProjectExportManager(GetWithoutIdMixin, CreateMixin, RESTManager):
_path = "/projects/%(project_id)s/export"
_obj_cls = ProjectExport
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (tuple(), ("description",))
+ _create_attrs = RequiredOptional(optional=("description",))
class ProjectImport(RefreshMixin, RESTObject):
diff --git a/gitlab/v4/objects/files.py b/gitlab/v4/objects/files.py
index bb43498..10a1b4f 100644
--- a/gitlab/v4/objects/files.py
+++ b/gitlab/v4/objects/files.py
@@ -1,7 +1,7 @@
import base64
from gitlab import cli, utils
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CreateMixin,
DeleteMixin,
@@ -69,13 +69,13 @@ class ProjectFileManager(GetMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTMa
_path = "/projects/%(project_id)s/repository/files"
_obj_cls = ProjectFile
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (
- ("file_path", "branch", "content", "commit_message"),
- ("encoding", "author_email", "author_name"),
+ _create_attrs = RequiredOptional(
+ required=("file_path", "branch", "content", "commit_message"),
+ optional=("encoding", "author_email", "author_name"),
)
- _update_attrs = (
- ("file_path", "branch", "content", "commit_message"),
- ("encoding", "author_email", "author_name"),
+ _update_attrs = RequiredOptional(
+ required=("file_path", "branch", "content", "commit_message"),
+ optional=("encoding", "author_email", "author_name"),
)
@cli.register_custom_action("ProjectFileManager", ("file_path", "ref"))
diff --git a/gitlab/v4/objects/geo_nodes.py b/gitlab/v4/objects/geo_nodes.py
index b9a1e49..3aaffd7 100644
--- a/gitlab/v4/objects/geo_nodes.py
+++ b/gitlab/v4/objects/geo_nodes.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
DeleteMixin,
ObjectDeleteMixin,
@@ -55,9 +55,8 @@ class GeoNode(SaveMixin, ObjectDeleteMixin, RESTObject):
class GeoNodeManager(RetrieveMixin, UpdateMixin, DeleteMixin, RESTManager):
_path = "/geo_nodes"
_obj_cls = GeoNode
- _update_attrs = (
- tuple(),
- ("enabled", "url", "files_max_capacity", "repos_max_capacity"),
+ _update_attrs = RequiredOptional(
+ optional=("enabled", "url", "files_max_capacity", "repos_max_capacity"),
)
@cli.register_custom_action("GeoNodeManager")
diff --git a/gitlab/v4/objects/groups.py b/gitlab/v4/objects/groups.py
index e859e0e..588c506 100644
--- a/gitlab/v4/objects/groups.py
+++ b/gitlab/v4/objects/groups.py
@@ -1,6 +1,6 @@
from gitlab import cli, types
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ListMixin, ObjectDeleteMixin, SaveMixin
from .access_requests import GroupAccessRequestManager
from .audit_events import GroupAuditEventManager
@@ -202,9 +202,9 @@ class GroupManager(CRUDMixin, RESTManager):
"with_custom_attributes",
"min_access_level",
)
- _create_attrs = (
- ("name", "path"),
- (
+ _create_attrs = RequiredOptional(
+ required=("name", "path"),
+ optional=(
"description",
"membership_lock",
"visibility",
@@ -223,9 +223,8 @@ class GroupManager(CRUDMixin, RESTManager):
"default_branch_protection",
),
)
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"name",
"path",
"description",
diff --git a/gitlab/v4/objects/hooks.py b/gitlab/v4/objects/hooks.py
index 85acf4e..b0eab07 100644
--- a/gitlab/v4/objects/hooks.py
+++ b/gitlab/v4/objects/hooks.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, NoUpdateMixin, ObjectDeleteMixin, SaveMixin
@@ -18,7 +18,7 @@ class Hook(ObjectDeleteMixin, RESTObject):
class HookManager(NoUpdateMixin, RESTManager):
_path = "/hooks"
_obj_cls = Hook
- _create_attrs = (("url",), tuple())
+ _create_attrs = RequiredOptional(required=("url",))
class ProjectHook(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -29,9 +29,9 @@ class ProjectHookManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/hooks"
_obj_cls = ProjectHook
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (
- ("url",),
- (
+ _create_attrs = RequiredOptional(
+ required=("url",),
+ optional=(
"push_events",
"issues_events",
"confidential_issues_events",
@@ -45,9 +45,9 @@ class ProjectHookManager(CRUDMixin, RESTManager):
"token",
),
)
- _update_attrs = (
- ("url",),
- (
+ _update_attrs = RequiredOptional(
+ required=("url",),
+ optional=(
"push_events",
"issues_events",
"confidential_issues_events",
diff --git a/gitlab/v4/objects/issues.py b/gitlab/v4/objects/issues.py
index dfd43f5..4da7f91 100644
--- a/gitlab/v4/objects/issues.py
+++ b/gitlab/v4/objects/issues.py
@@ -1,6 +1,6 @@
from gitlab import cli, types
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CRUDMixin,
CreateMixin,
@@ -188,9 +188,9 @@ class ProjectIssueManager(CRUDMixin, RESTManager):
"updated_after",
"updated_before",
)
- _create_attrs = (
- ("title",),
- (
+ _create_attrs = RequiredOptional(
+ required=("title",),
+ optional=(
"description",
"confidential",
"assignee_ids",
@@ -203,9 +203,8 @@ class ProjectIssueManager(CRUDMixin, RESTManager):
"discussion_to_resolve",
),
)
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"title",
"description",
"confidential",
@@ -230,7 +229,7 @@ class ProjectIssueLinkManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/projects/%(project_id)s/issues/%(issue_iid)s/links"
_obj_cls = ProjectIssueLink
_from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
- _create_attrs = (("target_project_id", "target_issue_iid"), tuple())
+ _create_attrs = RequiredOptional(required=("target_project_id", "target_issue_iid"))
@exc.on_http_error(exc.GitlabCreateError)
def create(self, data, **kwargs):
diff --git a/gitlab/v4/objects/labels.py b/gitlab/v4/objects/labels.py
index 513f1eb..682c64f 100644
--- a/gitlab/v4/objects/labels.py
+++ b/gitlab/v4/objects/labels.py
@@ -1,5 +1,5 @@
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CreateMixin,
DeleteMixin,
@@ -48,8 +48,12 @@ class GroupLabelManager(ListMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTMa
_path = "/groups/%(group_id)s/labels"
_obj_cls = GroupLabel
_from_parent_attrs = {"group_id": "id"}
- _create_attrs = (("name", "color"), ("description", "priority"))
- _update_attrs = (("name",), ("new_name", "color", "description", "priority"))
+ _create_attrs = RequiredOptional(
+ required=("name", "color"), optional=("description", "priority")
+ )
+ _update_attrs = RequiredOptional(
+ required=("name",), optional=("new_name", "color", "description", "priority")
+ )
# Update without ID.
def update(self, name, new_data=None, **kwargs):
@@ -110,8 +114,12 @@ class ProjectLabelManager(
_path = "/projects/%(project_id)s/labels"
_obj_cls = ProjectLabel
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("name", "color"), ("description", "priority"))
- _update_attrs = (("name",), ("new_name", "color", "description", "priority"))
+ _create_attrs = RequiredOptional(
+ required=("name", "color"), optional=("description", "priority")
+ )
+ _update_attrs = RequiredOptional(
+ required=("name",), optional=("new_name", "color", "description", "priority")
+ )
# Update without ID.
def update(self, name, new_data=None, **kwargs):
diff --git a/gitlab/v4/objects/members.py b/gitlab/v4/objects/members.py
index 5802aa8..2bb9d54 100644
--- a/gitlab/v4/objects/members.py
+++ b/gitlab/v4/objects/members.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
@@ -20,8 +20,12 @@ class GroupMemberManager(CRUDMixin, RESTManager):
_path = "/groups/%(group_id)s/members"
_obj_cls = GroupMember
_from_parent_attrs = {"group_id": "id"}
- _create_attrs = (("access_level", "user_id"), ("expires_at",))
- _update_attrs = (("access_level",), ("expires_at",))
+ _create_attrs = RequiredOptional(
+ required=("access_level", "user_id"), optional=("expires_at",)
+ )
+ _update_attrs = RequiredOptional(
+ required=("access_level",), optional=("expires_at",)
+ )
@cli.register_custom_action("GroupMemberManager")
@exc.on_http_error(exc.GitlabListError)
@@ -57,8 +61,12 @@ class ProjectMemberManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/members"
_obj_cls = ProjectMember
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("access_level", "user_id"), ("expires_at",))
- _update_attrs = (("access_level",), ("expires_at",))
+ _create_attrs = RequiredOptional(
+ required=("access_level", "user_id"), optional=("expires_at",)
+ )
+ _update_attrs = RequiredOptional(
+ required=("access_level",), optional=("expires_at",)
+ )
@cli.register_custom_action("ProjectMemberManager")
@exc.on_http_error(exc.GitlabListError)
diff --git a/gitlab/v4/objects/merge_request_approvals.py b/gitlab/v4/objects/merge_request_approvals.py
index cd09e32..8c0b420 100644
--- a/gitlab/v4/objects/merge_request_approvals.py
+++ b/gitlab/v4/objects/merge_request_approvals.py
@@ -1,5 +1,5 @@
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CreateMixin,
DeleteMixin,
@@ -31,9 +31,8 @@ class ProjectApprovalManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/approvals"
_obj_cls = ProjectApproval
_from_parent_attrs = {"project_id": "id"}
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"approvals_before_merge",
"reset_approvals_on_push",
"disable_overriding_approvers_per_merge_request",
@@ -73,7 +72,9 @@ class ProjectApprovalRuleManager(
_path = "/projects/%(project_id)s/approval_rules"
_obj_cls = ProjectApprovalRule
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("name", "approvals_required"), ("user_ids", "group_ids"))
+ _create_attrs = RequiredOptional(
+ required=("name", "approvals_required"), optional=("user_ids", "group_ids")
+ )
class ProjectMergeRequestApproval(SaveMixin, RESTObject):
@@ -84,7 +85,7 @@ class ProjectMergeRequestApprovalManager(GetWithoutIdMixin, UpdateMixin, RESTMan
_path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/approvals"
_obj_cls = ProjectMergeRequestApproval
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
- _update_attrs = (("approvals_required",), tuple())
+ _update_attrs = RequiredOptional(required=("approvals_required",))
_update_uses_post = True
@exc.on_http_error(exc.GitlabUpdateError)
@@ -165,15 +166,21 @@ class ProjectMergeRequestApprovalRuleManager(
_obj_cls = ProjectMergeRequestApprovalRule
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
_list_filters = ("name", "rule_type")
- _update_attrs = (
- ("id", "merge_request_iid", "approval_rule_id", "name", "approvals_required"),
- ("user_ids", "group_ids"),
+ _update_attrs = RequiredOptional(
+ required=(
+ "id",
+ "merge_request_iid",
+ "approval_rule_id",
+ "name",
+ "approvals_required",
+ ),
+ optional=("user_ids", "group_ids"),
)
# Important: When approval_project_rule_id is set, the name, users and groups of
# project-level rule will be copied. The approvals_required specified will be used. """
- _create_attrs = (
- ("id", "merge_request_iid", "name", "approvals_required"),
- ("approval_project_rule_id", "user_ids", "group_ids"),
+ _create_attrs = RequiredOptional(
+ required=("id", "merge_request_iid", "name", "approvals_required"),
+ optional=("approval_project_rule_id", "user_ids", "group_ids"),
)
def create(self, data, **kwargs):
diff --git a/gitlab/v4/objects/merge_requests.py b/gitlab/v4/objects/merge_requests.py
index f749ba8..f9b305a 100644
--- a/gitlab/v4/objects/merge_requests.py
+++ b/gitlab/v4/objects/merge_requests.py
@@ -1,6 +1,6 @@
from gitlab import cli, types
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject, RESTObjectList
+from gitlab.base import RequiredOptional, RESTManager, RESTObject, RESTObjectList
from gitlab.mixins import (
CRUDMixin,
ListMixin,
@@ -335,9 +335,9 @@ class ProjectMergeRequestManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/merge_requests"
_obj_cls = ProjectMergeRequest
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (
- ("source_branch", "target_branch", "title"),
- (
+ _create_attrs = RequiredOptional(
+ required=("source_branch", "target_branch", "title"),
+ optional=(
"assignee_id",
"description",
"target_project_id",
@@ -348,9 +348,8 @@ class ProjectMergeRequestManager(CRUDMixin, RESTManager):
"squash",
),
)
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"target_branch",
"assignee_id",
"title",
diff --git a/gitlab/v4/objects/milestones.py b/gitlab/v4/objects/milestones.py
index 7aebc8e..748f0c6 100644
--- a/gitlab/v4/objects/milestones.py
+++ b/gitlab/v4/objects/milestones.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject, RESTObjectList
+from gitlab.base import RequiredOptional, RESTManager, RESTObject, RESTObjectList
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
from .issues import GroupIssue, GroupIssueManager, ProjectIssue, ProjectIssueManager
from .merge_requests import (
@@ -80,10 +80,11 @@ class GroupMilestoneManager(CRUDMixin, RESTManager):
_path = "/groups/%(group_id)s/milestones"
_obj_cls = GroupMilestone
_from_parent_attrs = {"group_id": "id"}
- _create_attrs = (("title",), ("description", "due_date", "start_date"))
- _update_attrs = (
- tuple(),
- ("title", "description", "due_date", "start_date", "state_event"),
+ _create_attrs = RequiredOptional(
+ required=("title",), optional=("description", "due_date", "start_date")
+ )
+ _update_attrs = RequiredOptional(
+ optional=("title", "description", "due_date", "start_date", "state_event"),
)
_list_filters = ("iids", "state", "search")
@@ -151,12 +152,11 @@ class ProjectMilestoneManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/milestones"
_obj_cls = ProjectMilestone
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (
- ("title",),
- ("description", "due_date", "start_date", "state_event"),
+ _create_attrs = RequiredOptional(
+ required=("title",),
+ optional=("description", "due_date", "start_date", "state_event"),
)
- _update_attrs = (
- tuple(),
- ("title", "description", "due_date", "start_date", "state_event"),
+ _update_attrs = RequiredOptional(
+ optional=("title", "description", "due_date", "start_date", "state_event"),
)
_list_filters = ("iids", "state", "search")
diff --git a/gitlab/v4/objects/notes.py b/gitlab/v4/objects/notes.py
index 88a461a..362f901 100644
--- a/gitlab/v4/objects/notes.py
+++ b/gitlab/v4/objects/notes.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CRUDMixin,
CreateMixin,
@@ -46,7 +46,7 @@ class ProjectNoteManager(RetrieveMixin, RESTManager):
_path = "/projects/%(project_id)s/notes"
_obj_cls = ProjectNote
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("body",), tuple())
+ _create_attrs = RequiredOptional(required=("body",))
class ProjectCommitDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -66,8 +66,10 @@ class ProjectCommitDiscussionNoteManager(
"commit_id": "commit_id",
"discussion_id": "id",
}
- _create_attrs = (("body",), ("created_at", "position"))
- _update_attrs = (("body",), tuple())
+ _create_attrs = RequiredOptional(
+ required=("body",), optional=("created_at", "position")
+ )
+ _update_attrs = RequiredOptional(required=("body",))
class ProjectIssueNote(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -78,8 +80,8 @@ class ProjectIssueNoteManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/issues/%(issue_iid)s/notes"
_obj_cls = ProjectIssueNote
_from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
- _create_attrs = (("body",), ("created_at",))
- _update_attrs = (("body",), tuple())
+ _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
+ _update_attrs = RequiredOptional(required=("body",))
class ProjectIssueDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -99,8 +101,8 @@ class ProjectIssueDiscussionNoteManager(
"issue_iid": "issue_iid",
"discussion_id": "id",
}
- _create_attrs = (("body",), ("created_at",))
- _update_attrs = (("body",), tuple())
+ _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
+ _update_attrs = RequiredOptional(required=("body",))
class ProjectMergeRequestNote(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -111,8 +113,8 @@ class ProjectMergeRequestNoteManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/notes"
_obj_cls = ProjectMergeRequestNote
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
- _create_attrs = (("body",), tuple())
- _update_attrs = (("body",), tuple())
+ _create_attrs = RequiredOptional(required=("body",))
+ _update_attrs = RequiredOptional(required=("body",))
class ProjectMergeRequestDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -132,8 +134,8 @@ class ProjectMergeRequestDiscussionNoteManager(
"mr_iid": "mr_iid",
"discussion_id": "id",
}
- _create_attrs = (("body",), ("created_at",))
- _update_attrs = (("body",), tuple())
+ _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
+ _update_attrs = RequiredOptional(required=("body",))
class ProjectSnippetNote(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -144,8 +146,8 @@ class ProjectSnippetNoteManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/snippets/%(snippet_id)s/notes"
_obj_cls = ProjectSnippetNote
_from_parent_attrs = {"project_id": "project_id", "snippet_id": "id"}
- _create_attrs = (("body",), tuple())
- _update_attrs = (("body",), tuple())
+ _create_attrs = RequiredOptional(required=("body",))
+ _update_attrs = RequiredOptional(required=("body",))
class ProjectSnippetDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -165,5 +167,5 @@ class ProjectSnippetDiscussionNoteManager(
"snippet_id": "snippet_id",
"discussion_id": "id",
}
- _create_attrs = (("body",), ("created_at",))
- _update_attrs = (("body",), tuple())
+ _create_attrs = RequiredOptional(required=("body",), optional=("created_at",))
+ _update_attrs = RequiredOptional(required=("body",))
diff --git a/gitlab/v4/objects/notification_settings.py b/gitlab/v4/objects/notification_settings.py
index 3aee514..1738ab9 100644
--- a/gitlab/v4/objects/notification_settings.py
+++ b/gitlab/v4/objects/notification_settings.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import GetWithoutIdMixin, SaveMixin, UpdateMixin
@@ -20,9 +20,8 @@ class NotificationSettingsManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
_path = "/notification_settings"
_obj_cls = NotificationSettings
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"level",
"notification_email",
"new_note",
diff --git a/gitlab/v4/objects/pages.py b/gitlab/v4/objects/pages.py
index 4cd1a5a..9f9c97d 100644
--- a/gitlab/v4/objects/pages.py
+++ b/gitlab/v4/objects/pages.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ListMixin, ObjectDeleteMixin, SaveMixin
@@ -27,5 +27,7 @@ class ProjectPagesDomainManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/pages/domains"
_obj_cls = ProjectPagesDomain
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("domain",), ("certificate", "key"))
- _update_attrs = (tuple(), ("certificate", "key"))
+ _create_attrs = RequiredOptional(
+ required=("domain",), optional=("certificate", "key")
+ )
+ _update_attrs = RequiredOptional(optional=("certificate", "key"))
diff --git a/gitlab/v4/objects/pipelines.py b/gitlab/v4/objects/pipelines.py
index 9f0516a..703d40b 100644
--- a/gitlab/v4/objects/pipelines.py
+++ b/gitlab/v4/objects/pipelines.py
@@ -1,6 +1,6 @@
from gitlab import cli, types
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CRUDMixin,
CreateMixin,
@@ -83,7 +83,7 @@ class ProjectPipelineManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManage
"order_by",
"sort",
)
- _create_attrs = (("ref",), tuple())
+ _create_attrs = RequiredOptional(required=("ref",))
def create(self, data, **kwargs):
"""Creates a new object.
@@ -150,8 +150,8 @@ class ProjectPipelineScheduleVariableManager(
)
_obj_cls = ProjectPipelineScheduleVariable
_from_parent_attrs = {"project_id": "project_id", "pipeline_schedule_id": "id"}
- _create_attrs = (("key", "value"), tuple())
- _update_attrs = (("key", "value"), tuple())
+ _create_attrs = RequiredOptional(required=("key", "value"))
+ _update_attrs = RequiredOptional(required=("key", "value"))
class ProjectPipelineSchedule(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -196,5 +196,9 @@ class ProjectPipelineScheduleManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/pipeline_schedules"
_obj_cls = ProjectPipelineSchedule
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("description", "ref", "cron"), ("cron_timezone", "active"))
- _update_attrs = (tuple(), ("description", "ref", "cron", "cron_timezone", "active"))
+ _create_attrs = RequiredOptional(
+ required=("description", "ref", "cron"), optional=("cron_timezone", "active")
+ )
+ _update_attrs = RequiredOptional(
+ optional=("description", "ref", "cron", "cron_timezone", "active"),
+ )
diff --git a/gitlab/v4/objects/projects.py b/gitlab/v4/objects/projects.py
index f4de18d..c78c8c9 100644
--- a/gitlab/v4/objects/projects.py
+++ b/gitlab/v4/objects/projects.py
@@ -1,6 +1,6 @@
from gitlab import cli, types, utils
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CRUDMixin,
CreateMixin,
@@ -558,9 +558,8 @@ class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTO
class ProjectManager(CRUDMixin, RESTManager):
_path = "/projects"
_obj_cls = Project
- _create_attrs = (
- tuple(),
- (
+ _create_attrs = RequiredOptional(
+ optional=(
"name",
"path",
"namespace_id",
@@ -617,9 +616,8 @@ class ProjectManager(CRUDMixin, RESTManager):
"packages_enabled",
),
)
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"name",
"path",
"default_branch",
@@ -919,7 +917,7 @@ class ProjectForkManager(CreateMixin, ListMixin, RESTManager):
"with_issues_enabled",
"with_merge_requests_enabled",
)
- _create_attrs = (tuple(), ("namespace",))
+ _create_attrs = RequiredOptional(optional=("namespace",))
def create(self, data, **kwargs):
"""Creates a new object.
@@ -949,5 +947,7 @@ class ProjectRemoteMirrorManager(ListMixin, CreateMixin, UpdateMixin, RESTManage
_path = "/projects/%(project_id)s/remote_mirrors"
_obj_cls = ProjectRemoteMirror
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("url",), ("enabled", "only_protected_branches"))
- _update_attrs = (tuple(), ("enabled", "only_protected_branches"))
+ _create_attrs = RequiredOptional(
+ required=("url",), optional=("enabled", "only_protected_branches")
+ )
+ _update_attrs = RequiredOptional(optional=("enabled", "only_protected_branches"))
diff --git a/gitlab/v4/objects/push_rules.py b/gitlab/v4/objects/push_rules.py
index e580ab8..19062bf 100644
--- a/gitlab/v4/objects/push_rules.py
+++ b/gitlab/v4/objects/push_rules.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CreateMixin,
DeleteMixin,
@@ -25,9 +25,8 @@ class ProjectPushRulesManager(
_path = "/projects/%(project_id)s/push_rule"
_obj_cls = ProjectPushRules
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (
- tuple(),
- (
+ _create_attrs = RequiredOptional(
+ optional=(
"deny_delete_tag",
"member_check",
"prevent_secrets",
@@ -38,9 +37,8 @@ class ProjectPushRulesManager(
"max_file_size",
),
)
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"deny_delete_tag",
"member_check",
"prevent_secrets",
diff --git a/gitlab/v4/objects/releases.py b/gitlab/v4/objects/releases.py
index bbeea24..2c549b1 100644
--- a/gitlab/v4/objects/releases.py
+++ b/gitlab/v4/objects/releases.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, NoUpdateMixin, ObjectDeleteMixin, SaveMixin
@@ -21,7 +21,9 @@ class ProjectReleaseManager(NoUpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/releases"
_obj_cls = ProjectRelease
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("name", "tag_name", "description"), ("ref", "assets"))
+ _create_attrs = RequiredOptional(
+ required=("name", "tag_name", "description"), optional=("ref", "assets")
+ )
class ProjectReleaseLink(RESTObject, ObjectDeleteMixin, SaveMixin):
@@ -32,5 +34,7 @@ class ProjectReleaseLinkManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/releases/%(tag_name)s/assets/links"
_obj_cls = ProjectReleaseLink
_from_parent_attrs = {"project_id": "project_id", "tag_name": "tag_name"}
- _create_attrs = (("name", "url"), ("filepath", "link_type"))
- _update_attrs = ((), ("name", "url", "filepath", "link_type"))
+ _create_attrs = RequiredOptional(
+ required=("name", "url"), optional=("filepath", "link_type")
+ )
+ _update_attrs = RequiredOptional(optional=("name", "url", "filepath", "link_type"))
diff --git a/gitlab/v4/objects/runners.py b/gitlab/v4/objects/runners.py
index dd7f0e3..e6ac511 100644
--- a/gitlab/v4/objects/runners.py
+++ b/gitlab/v4/objects/runners.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CRUDMixin,
ListMixin,
@@ -41,9 +41,9 @@ class RunnerManager(CRUDMixin, RESTManager):
_path = "/runners"
_obj_cls = Runner
_list_filters = ("scope",)
- _create_attrs = (
- ("token",),
- (
+ _create_attrs = RequiredOptional(
+ required=("token",),
+ optional=(
"description",
"info",
"active",
@@ -54,9 +54,8 @@ class RunnerManager(CRUDMixin, RESTManager):
"maximum_timeout",
),
)
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"description",
"active",
"tag_list",
@@ -122,7 +121,7 @@ class GroupRunnerManager(NoUpdateMixin, RESTManager):
_path = "/groups/%(group_id)s/runners"
_obj_cls = GroupRunner
_from_parent_attrs = {"group_id": "id"}
- _create_attrs = (("runner_id",), tuple())
+ _create_attrs = RequiredOptional(required=("runner_id",))
class ProjectRunner(ObjectDeleteMixin, RESTObject):
@@ -133,4 +132,4 @@ class ProjectRunnerManager(NoUpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/runners"
_obj_cls = ProjectRunner
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("runner_id",), tuple())
+ _create_attrs = RequiredOptional(required=("runner_id",))
diff --git a/gitlab/v4/objects/settings.py b/gitlab/v4/objects/settings.py
index 0d07488..a3d6ed9 100644
--- a/gitlab/v4/objects/settings.py
+++ b/gitlab/v4/objects/settings.py
@@ -1,5 +1,5 @@
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import GetWithoutIdMixin, SaveMixin, UpdateMixin
@@ -16,9 +16,8 @@ class ApplicationSettings(SaveMixin, RESTObject):
class ApplicationSettingsManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
_path = "/application/settings"
_obj_cls = ApplicationSettings
- _update_attrs = (
- tuple(),
- (
+ _update_attrs = RequiredOptional(
+ optional=(
"id",
"default_projects_limit",
"signup_enabled",
diff --git a/gitlab/v4/objects/snippets.py b/gitlab/v4/objects/snippets.py
index 20db75f..6159442 100644
--- a/gitlab/v4/objects/snippets.py
+++ b/gitlab/v4/objects/snippets.py
@@ -1,6 +1,6 @@
from gitlab import cli, utils
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin, UserAgentDetailMixin
from .award_emojis import ProjectSnippetAwardEmojiManager
@@ -50,8 +50,12 @@ class Snippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
class SnippetManager(CRUDMixin, RESTManager):
_path = "/snippets"
_obj_cls = Snippet
- _create_attrs = (("title", "file_name", "content"), ("lifetime", "visibility"))
- _update_attrs = (tuple(), ("title", "file_name", "content", "visibility"))
+ _create_attrs = RequiredOptional(
+ required=("title", "file_name", "content"), optional=("lifetime", "visibility")
+ )
+ _update_attrs = RequiredOptional(
+ optional=("title", "file_name", "content", "visibility")
+ )
@cli.register_custom_action("SnippetManager")
def public(self, **kwargs):
@@ -111,8 +115,10 @@ class ProjectSnippetManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/snippets"
_obj_cls = ProjectSnippet
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("title", "file_name", "content", "visibility"), ("description",))
- _update_attrs = (
- tuple(),
- ("title", "file_name", "content", "visibility", "description"),
+ _create_attrs = RequiredOptional(
+ required=("title", "file_name", "content", "visibility"),
+ optional=("description",),
+ )
+ _update_attrs = RequiredOptional(
+ optional=("title", "file_name", "content", "visibility", "description"),
)
diff --git a/gitlab/v4/objects/tags.py b/gitlab/v4/objects/tags.py
index 56d7fb6..cb3b11f 100644
--- a/gitlab/v4/objects/tags.py
+++ b/gitlab/v4/objects/tags.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin
@@ -56,7 +56,9 @@ class ProjectTagManager(NoUpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/repository/tags"
_obj_cls = ProjectTag
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("tag_name", "ref"), ("message",))
+ _create_attrs = RequiredOptional(
+ required=("tag_name", "ref"), optional=("message",)
+ )
class ProjectProtectedTag(ObjectDeleteMixin, RESTObject):
@@ -68,4 +70,6 @@ class ProjectProtectedTagManager(NoUpdateMixin, RESTManager):
_path = "/projects/%(project_id)s/protected_tags"
_obj_cls = ProjectProtectedTag
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("name",), ("create_access_level",))
+ _create_attrs = RequiredOptional(
+ required=("name",), optional=("create_access_level",)
+ )
diff --git a/gitlab/v4/objects/triggers.py b/gitlab/v4/objects/triggers.py
index 822a1df..f45f4ef 100644
--- a/gitlab/v4/objects/triggers.py
+++ b/gitlab/v4/objects/triggers.py
@@ -1,6 +1,6 @@
from gitlab import cli
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
@@ -32,5 +32,5 @@ class ProjectTriggerManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/triggers"
_obj_cls = ProjectTrigger
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("description",), tuple())
- _update_attrs = (("description",), tuple())
+ _create_attrs = RequiredOptional(required=("description",))
+ _update_attrs = RequiredOptional(required=("description",))
diff --git a/gitlab/v4/objects/users.py b/gitlab/v4/objects/users.py
index 4f14e86..940cf07 100644
--- a/gitlab/v4/objects/users.py
+++ b/gitlab/v4/objects/users.py
@@ -1,6 +1,6 @@
from gitlab import cli, types
from gitlab import exceptions as exc
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import (
CRUDMixin,
CreateMixin,
@@ -60,7 +60,7 @@ class CurrentUserEmail(ObjectDeleteMixin, RESTObject):
class CurrentUserEmailManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/user/emails"
_obj_cls = CurrentUserEmail
- _create_attrs = (("email",), tuple())
+ _create_attrs = RequiredOptional(required=("email",))
class CurrentUserGPGKey(ObjectDeleteMixin, RESTObject):
@@ -70,7 +70,7 @@ class CurrentUserGPGKey(ObjectDeleteMixin, RESTObject):
class CurrentUserGPGKeyManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/user/gpg_keys"
_obj_cls = CurrentUserGPGKey
- _create_attrs = (("key",), tuple())
+ _create_attrs = RequiredOptional(required=("key",))
class CurrentUserKey(ObjectDeleteMixin, RESTObject):
@@ -80,7 +80,7 @@ class CurrentUserKey(ObjectDeleteMixin, RESTObject):
class CurrentUserKeyManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/user/keys"
_obj_cls = CurrentUserKey
- _create_attrs = (("title", "key"), tuple())
+ _create_attrs = RequiredOptional(required=("title", "key"))
class CurrentUserStatus(SaveMixin, RESTObject):
@@ -91,7 +91,7 @@ class CurrentUserStatus(SaveMixin, RESTObject):
class CurrentUserStatusManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
_path = "/user/status"
_obj_cls = CurrentUserStatus
- _update_attrs = (tuple(), ("emoji", "message"))
+ _update_attrs = RequiredOptional(optional=("emoji", "message"))
class CurrentUser(RESTObject):
@@ -264,9 +264,8 @@ class UserManager(CRUDMixin, RESTManager):
"status",
"two_factor",
)
- _create_attrs = (
- tuple(),
- (
+ _create_attrs = RequiredOptional(
+ optional=(
"email",
"username",
"name",
@@ -293,9 +292,9 @@ class UserManager(CRUDMixin, RESTManager):
"theme_id",
),
)
- _update_attrs = (
- ("email", "username", "name"),
- (
+ _update_attrs = RequiredOptional(
+ required=("email", "username", "name"),
+ optional=(
"password",
"skype",
"linkedin",
@@ -340,7 +339,7 @@ class UserEmailManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/users/%(user_id)s/emails"
_obj_cls = UserEmail
_from_parent_attrs = {"user_id": "id"}
- _create_attrs = (("email",), tuple())
+ _create_attrs = RequiredOptional(required=("email",))
class UserActivities(RESTObject):
@@ -371,7 +370,7 @@ class UserGPGKeyManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/users/%(user_id)s/gpg_keys"
_obj_cls = UserGPGKey
_from_parent_attrs = {"user_id": "id"}
- _create_attrs = (("key",), tuple())
+ _create_attrs = RequiredOptional(required=("key",))
class UserKey(ObjectDeleteMixin, RESTObject):
@@ -382,7 +381,7 @@ class UserKeyManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
_path = "/users/%(user_id)s/keys"
_obj_cls = UserKey
_from_parent_attrs = {"user_id": "id"}
- _create_attrs = (("title", "key"), tuple())
+ _create_attrs = RequiredOptional(required=("title", "key"))
class UserIdentityProviderManager(DeleteMixin, RESTManager):
@@ -404,7 +403,9 @@ class UserImpersonationTokenManager(NoUpdateMixin, RESTManager):
_path = "/users/%(user_id)s/impersonation_tokens"
_obj_cls = UserImpersonationToken
_from_parent_attrs = {"user_id": "id"}
- _create_attrs = (("name", "scopes"), ("expires_at",))
+ _create_attrs = RequiredOptional(
+ required=("name", "scopes"), optional=("expires_at",)
+ )
_list_filters = ("state",)
@@ -428,9 +429,9 @@ class UserProjectManager(ListMixin, CreateMixin, RESTManager):
_path = "/projects/user/%(user_id)s"
_obj_cls = UserProject
_from_parent_attrs = {"user_id": "id"}
- _create_attrs = (
- ("name",),
- (
+ _create_attrs = RequiredOptional(
+ required=("name",),
+ optional=(
"default_branch",
"issues_enabled",
"wall_enabled",
diff --git a/gitlab/v4/objects/variables.py b/gitlab/v4/objects/variables.py
index 025e3be..54ee149 100644
--- a/gitlab/v4/objects/variables.py
+++ b/gitlab/v4/objects/variables.py
@@ -4,7 +4,7 @@ https://docs.gitlab.com/ee/api/instance_level_ci_variables.html
https://docs.gitlab.com/ee/api/project_level_variables.html
https://docs.gitlab.com/ee/api/group_level_variables.html
"""
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
@@ -25,8 +25,12 @@ class Variable(SaveMixin, ObjectDeleteMixin, RESTObject):
class VariableManager(CRUDMixin, RESTManager):
_path = "/admin/ci/variables"
_obj_cls = Variable
- _create_attrs = (("key", "value"), ("protected", "variable_type", "masked"))
- _update_attrs = (("key", "value"), ("protected", "variable_type", "masked"))
+ _create_attrs = RequiredOptional(
+ required=("key", "value"), optional=("protected", "variable_type", "masked")
+ )
+ _update_attrs = RequiredOptional(
+ required=("key", "value"), optional=("protected", "variable_type", "masked")
+ )
class GroupVariable(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -37,8 +41,12 @@ class GroupVariableManager(CRUDMixin, RESTManager):
_path = "/groups/%(group_id)s/variables"
_obj_cls = GroupVariable
_from_parent_attrs = {"group_id": "id"}
- _create_attrs = (("key", "value"), ("protected", "variable_type", "masked"))
- _update_attrs = (("key", "value"), ("protected", "variable_type", "masked"))
+ _create_attrs = RequiredOptional(
+ required=("key", "value"), optional=("protected", "variable_type", "masked")
+ )
+ _update_attrs = RequiredOptional(
+ required=("key", "value"), optional=("protected", "variable_type", "masked")
+ )
class ProjectVariable(SaveMixin, ObjectDeleteMixin, RESTObject):
@@ -49,11 +57,11 @@ class ProjectVariableManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/variables"
_obj_cls = ProjectVariable
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (
- ("key", "value"),
- ("protected", "variable_type", "masked", "environment_scope"),
+ _create_attrs = RequiredOptional(
+ required=("key", "value"),
+ optional=("protected", "variable_type", "masked", "environment_scope"),
)
- _update_attrs = (
- ("key", "value"),
- ("protected", "variable_type", "masked", "environment_scope"),
+ _update_attrs = RequiredOptional(
+ required=("key", "value"),
+ optional=("protected", "variable_type", "masked", "environment_scope"),
)
diff --git a/gitlab/v4/objects/wikis.py b/gitlab/v4/objects/wikis.py
index f2c1c2a..722095d 100644
--- a/gitlab/v4/objects/wikis.py
+++ b/gitlab/v4/objects/wikis.py
@@ -1,4 +1,4 @@
-from gitlab.base import RESTManager, RESTObject
+from gitlab.base import RequiredOptional, RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
@@ -17,6 +17,8 @@ class ProjectWikiManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/wikis"
_obj_cls = ProjectWiki
_from_parent_attrs = {"project_id": "id"}
- _create_attrs = (("title", "content"), ("format",))
- _update_attrs = (tuple(), ("title", "content", "format"))
+ _create_attrs = RequiredOptional(
+ required=("title", "content"), optional=("format",)
+ )
+ _update_attrs = RequiredOptional(optional=("title", "content", "format"))
_list_filters = ("with_content",)