summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNejc Habjan <hab.nejc@gmail.com>2021-09-08 20:40:32 +0200
committerGitHub <noreply@github.com>2021-09-08 20:40:32 +0200
commit5247e8bc5298bc017e117e1bfa6717183d07827f (patch)
treecf17de5ed2eb222375589ff7c76b1087fd05c7b8
parentb8a47bae3342400a411fb9bf4bef3c15ba91c98e (diff)
parent487b9a875a18bb3b4e0d49237bb7129d2c6dba2f (diff)
downloadgitlab-5247e8bc5298bc017e117e1bfa6717183d07827f.tar.gz
Merge pull request #1512 from JohnVillalovos/jlvillal/type_managers
chore: improve type-hinting for managers
-rw-r--r--gitlab/base.py19
-rw-r--r--gitlab/v4/cli.py5
-rw-r--r--gitlab/v4/objects/boards.py4
-rw-r--r--gitlab/v4/objects/commits.py9
-rw-r--r--gitlab/v4/objects/container_registry.py2
-rw-r--r--gitlab/v4/objects/deployments.py2
-rw-r--r--gitlab/v4/objects/discussions.py8
-rw-r--r--gitlab/v4/objects/epics.py7
-rw-r--r--gitlab/v4/objects/groups.py57
-rw-r--r--gitlab/v4/objects/issues.py17
-rw-r--r--gitlab/v4/objects/members.py3
-rw-r--r--gitlab/v4/objects/merge_requests.py22
-rw-r--r--gitlab/v4/objects/notes.py6
-rw-r--r--gitlab/v4/objects/packages.py2
-rw-r--r--gitlab/v4/objects/pipelines.py12
-rw-r--r--gitlab/v4/objects/projects.py107
-rw-r--r--gitlab/v4/objects/releases.py3
-rw-r--r--gitlab/v4/objects/runners.py2
-rw-r--r--gitlab/v4/objects/snippets.py9
-rw-r--r--gitlab/v4/objects/users.py38
-rw-r--r--tests/functional/api/test_merge_requests.py10
-rw-r--r--tests/unit/test_base.py2
22 files changed, 178 insertions, 168 deletions
diff --git a/gitlab/base.py b/gitlab/base.py
index bea1901..bc96e0f 100644
--- a/gitlab/base.py
+++ b/gitlab/base.py
@@ -150,13 +150,22 @@ class RESTObject(object):
return hash(self.get_id())
def _create_managers(self) -> None:
- managers = getattr(self, "_managers", None)
- if managers is None:
- return
-
- for attr, cls_name in self._managers:
+ # NOTE(jlvillal): We are creating our managers by looking at the class
+ # annotations. If an attribute is annotated as being a *Manager type
+ # then we create the manager and assign it to the attribute.
+ for attr, annotation in sorted(self.__annotations__.items()):
+ if not isinstance(annotation, (type, str)):
+ continue
+ if isinstance(annotation, type):
+ cls_name = annotation.__name__
+ else:
+ cls_name = annotation
+ # All *Manager classes are used except for the base "RESTManager" class
+ if cls_name == "RESTManager" or not cls_name.endswith("Manager"):
+ continue
cls = getattr(self._module, cls_name)
manager = cls(self.manager.gitlab, parent=self)
+ # Since we have our own __setattr__ method, we can't use setattr()
self.__dict__[attr] = manager
def _update_attrs(self, new_attrs: Dict[str, Any]) -> None:
diff --git a/gitlab/v4/cli.py b/gitlab/v4/cli.py
index 2fc1986..6986552 100644
--- a/gitlab/v4/cli.py
+++ b/gitlab/v4/cli.py
@@ -99,7 +99,10 @@ class GitlabCLI(object):
def do_project_export_download(self) -> None:
try:
project = self.gl.projects.get(int(self.args["project_id"]), lazy=True)
- data = project.exports.get().download()
+ export_status = project.exports.get()
+ if TYPE_CHECKING:
+ assert export_status is not None
+ data = export_status.download()
sys.stdout.buffer.write(data)
except Exception as e:
diff --git a/gitlab/v4/objects/boards.py b/gitlab/v4/objects/boards.py
index b517fde..8b2959d 100644
--- a/gitlab/v4/objects/boards.py
+++ b/gitlab/v4/objects/boards.py
@@ -26,7 +26,7 @@ class GroupBoardListManager(CRUDMixin, RESTManager):
class GroupBoard(SaveMixin, ObjectDeleteMixin, RESTObject):
- _managers = (("lists", "GroupBoardListManager"),)
+ lists: GroupBoardListManager
class GroupBoardManager(CRUDMixin, RESTManager):
@@ -49,7 +49,7 @@ class ProjectBoardListManager(CRUDMixin, RESTManager):
class ProjectBoard(SaveMixin, ObjectDeleteMixin, RESTObject):
- _managers = (("lists", "ProjectBoardListManager"),)
+ lists: ProjectBoardListManager
class ProjectBoardManager(CRUDMixin, RESTManager):
diff --git a/gitlab/v4/objects/commits.py b/gitlab/v4/objects/commits.py
index 76e582b..05b55b0 100644
--- a/gitlab/v4/objects/commits.py
+++ b/gitlab/v4/objects/commits.py
@@ -17,11 +17,10 @@ __all__ = [
class ProjectCommit(RESTObject):
_short_print_attr = "title"
- _managers = (
- ("comments", "ProjectCommitCommentManager"),
- ("discussions", "ProjectCommitDiscussionManager"),
- ("statuses", "ProjectCommitStatusManager"),
- )
+
+ comments: "ProjectCommitCommentManager"
+ discussions: ProjectCommitDiscussionManager
+ statuses: "ProjectCommitStatusManager"
@cli.register_custom_action("ProjectCommit")
@exc.on_http_error(exc.GitlabGetError)
diff --git a/gitlab/v4/objects/container_registry.py b/gitlab/v4/objects/container_registry.py
index 432cb7f..8164e17 100644
--- a/gitlab/v4/objects/container_registry.py
+++ b/gitlab/v4/objects/container_registry.py
@@ -12,7 +12,7 @@ __all__ = [
class ProjectRegistryRepository(ObjectDeleteMixin, RESTObject):
- _managers = (("tags", "ProjectRegistryTagManager"),)
+ tags: "ProjectRegistryTagManager"
class ProjectRegistryRepositoryManager(DeleteMixin, ListMixin, RESTManager):
diff --git a/gitlab/v4/objects/deployments.py b/gitlab/v4/objects/deployments.py
index 8cf0fd9..11c60d1 100644
--- a/gitlab/v4/objects/deployments.py
+++ b/gitlab/v4/objects/deployments.py
@@ -10,7 +10,7 @@ __all__ = [
class ProjectDeployment(SaveMixin, RESTObject):
- _managers = (("mergerequests", "ProjectDeploymentMergeRequestManager"),)
+ mergerequests: ProjectDeploymentMergeRequestManager
class ProjectDeploymentManager(RetrieveMixin, CreateMixin, UpdateMixin, RESTManager):
diff --git a/gitlab/v4/objects/discussions.py b/gitlab/v4/objects/discussions.py
index f91d8fb..ae7a4d5 100644
--- a/gitlab/v4/objects/discussions.py
+++ b/gitlab/v4/objects/discussions.py
@@ -21,7 +21,7 @@ __all__ = [
class ProjectCommitDiscussion(RESTObject):
- _managers = (("notes", "ProjectCommitDiscussionNoteManager"),)
+ notes: ProjectCommitDiscussionNoteManager
class ProjectCommitDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
@@ -32,7 +32,7 @@ class ProjectCommitDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
class ProjectIssueDiscussion(RESTObject):
- _managers = (("notes", "ProjectIssueDiscussionNoteManager"),)
+ notes: ProjectIssueDiscussionNoteManager
class ProjectIssueDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
@@ -43,7 +43,7 @@ class ProjectIssueDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
class ProjectMergeRequestDiscussion(SaveMixin, RESTObject):
- _managers = (("notes", "ProjectMergeRequestDiscussionNoteManager"),)
+ notes: ProjectMergeRequestDiscussionNoteManager
class ProjectMergeRequestDiscussionManager(
@@ -59,7 +59,7 @@ class ProjectMergeRequestDiscussionManager(
class ProjectSnippetDiscussion(RESTObject):
- _managers = (("notes", "ProjectSnippetDiscussionNoteManager"),)
+ notes: ProjectSnippetDiscussionNoteManager
class ProjectSnippetDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
diff --git a/gitlab/v4/objects/epics.py b/gitlab/v4/objects/epics.py
index 4311aa7..90dc6ad 100644
--- a/gitlab/v4/objects/epics.py
+++ b/gitlab/v4/objects/epics.py
@@ -23,10 +23,9 @@ __all__ = [
class GroupEpic(ObjectDeleteMixin, SaveMixin, RESTObject):
_id_attr = "iid"
- _managers = (
- ("issues", "GroupEpicIssueManager"),
- ("resourcelabelevents", "GroupEpicResourceLabelEventManager"),
- )
+
+ issues: "GroupEpicIssueManager"
+ resourcelabelevents: GroupEpicResourceLabelEventManager
class GroupEpicManager(CRUDMixin, RESTManager):
diff --git a/gitlab/v4/objects/groups.py b/gitlab/v4/objects/groups.py
index ee82415..7de4f84 100644
--- a/gitlab/v4/objects/groups.py
+++ b/gitlab/v4/objects/groups.py
@@ -43,35 +43,34 @@ __all__ = [
class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "name"
- _managers = (
- ("accessrequests", "GroupAccessRequestManager"),
- ("audit_events", "GroupAuditEventManager"),
- ("badges", "GroupBadgeManager"),
- ("billable_members", "GroupBillableMemberManager"),
- ("boards", "GroupBoardManager"),
- ("customattributes", "GroupCustomAttributeManager"),
- ("descendant_groups", "GroupDescendantGroupManager"),
- ("exports", "GroupExportManager"),
- ("epics", "GroupEpicManager"),
- ("hooks", "GroupHookManager"),
- ("imports", "GroupImportManager"),
- ("issues", "GroupIssueManager"),
- ("issues_statistics", "GroupIssuesStatisticsManager"),
- ("labels", "GroupLabelManager"),
- ("members", "GroupMemberManager"),
- ("members_all", "GroupMemberAllManager"),
- ("mergerequests", "GroupMergeRequestManager"),
- ("milestones", "GroupMilestoneManager"),
- ("notificationsettings", "GroupNotificationSettingsManager"),
- ("packages", "GroupPackageManager"),
- ("projects", "GroupProjectManager"),
- ("runners", "GroupRunnerManager"),
- ("subgroups", "GroupSubgroupManager"),
- ("variables", "GroupVariableManager"),
- ("clusters", "GroupClusterManager"),
- ("deploytokens", "GroupDeployTokenManager"),
- ("wikis", "GroupWikiManager"),
- )
+
+ accessrequests: GroupAccessRequestManager
+ audit_events: GroupAuditEventManager
+ badges: GroupBadgeManager
+ billable_members: GroupBillableMemberManager
+ boards: GroupBoardManager
+ clusters: GroupClusterManager
+ customattributes: GroupCustomAttributeManager
+ deploytokens: GroupDeployTokenManager
+ descendant_groups: "GroupDescendantGroupManager"
+ epics: GroupEpicManager
+ exports: GroupExportManager
+ hooks: GroupHookManager
+ imports: GroupImportManager
+ issues: GroupIssueManager
+ issues_statistics: GroupIssuesStatisticsManager
+ labels: GroupLabelManager
+ members: GroupMemberManager
+ members_all: GroupMemberAllManager
+ mergerequests: GroupMergeRequestManager
+ milestones: GroupMilestoneManager
+ notificationsettings: GroupNotificationSettingsManager
+ packages: GroupPackageManager
+ projects: GroupProjectManager
+ runners: GroupRunnerManager
+ subgroups: "GroupSubgroupManager"
+ variables: GroupVariableManager
+ wikis: GroupWikiManager
@cli.register_custom_action("Group", ("to_project_id",))
@exc.on_http_error(exc.GitlabTransferProjectError)
diff --git a/gitlab/v4/objects/issues.py b/gitlab/v4/objects/issues.py
index c77a8d5..9272908 100644
--- a/gitlab/v4/objects/issues.py
+++ b/gitlab/v4/objects/issues.py
@@ -105,15 +105,14 @@ class ProjectIssue(
):
_short_print_attr = "title"
_id_attr = "iid"
- _managers = (
- ("awardemojis", "ProjectIssueAwardEmojiManager"),
- ("discussions", "ProjectIssueDiscussionManager"),
- ("links", "ProjectIssueLinkManager"),
- ("notes", "ProjectIssueNoteManager"),
- ("resourcelabelevents", "ProjectIssueResourceLabelEventManager"),
- ("resourcemilestoneevents", "ProjectIssueResourceMilestoneEventManager"),
- ("resourcestateevents", "ProjectIssueResourceStateEventManager"),
- )
+
+ awardemojis: ProjectIssueAwardEmojiManager
+ discussions: ProjectIssueDiscussionManager
+ links: "ProjectIssueLinkManager"
+ notes: ProjectIssueNoteManager
+ resourcelabelevents: ProjectIssueResourceLabelEventManager
+ resourcemilestoneevents: ProjectIssueResourceMilestoneEventManager
+ resourcestateevents: ProjectIssueResourceStateEventManager
@cli.register_custom_action("ProjectIssue", ("to_project_id",))
@exc.on_http_error(exc.GitlabUpdateError)
diff --git a/gitlab/v4/objects/members.py b/gitlab/v4/objects/members.py
index 3ff8de5..b2f4c07 100644
--- a/gitlab/v4/objects/members.py
+++ b/gitlab/v4/objects/members.py
@@ -43,7 +43,8 @@ class GroupMemberManager(MemberAllMixin, CRUDMixin, RESTManager):
class GroupBillableMember(ObjectDeleteMixin, RESTObject):
_short_print_attr = "username"
- _managers = (("memberships", "GroupBillableMemberMembershipManager"),)
+
+ memberships: "GroupBillableMemberMembershipManager"
class GroupBillableMemberManager(ListMixin, DeleteMixin, RESTManager):
diff --git a/gitlab/v4/objects/merge_requests.py b/gitlab/v4/objects/merge_requests.py
index 2559207..4def98c 100644
--- a/gitlab/v4/objects/merge_requests.py
+++ b/gitlab/v4/objects/merge_requests.py
@@ -139,18 +139,16 @@ class ProjectMergeRequest(
):
_id_attr = "iid"
- _managers = (
- ("approvals", "ProjectMergeRequestApprovalManager"),
- ("approval_rules", "ProjectMergeRequestApprovalRuleManager"),
- ("awardemojis", "ProjectMergeRequestAwardEmojiManager"),
- ("diffs", "ProjectMergeRequestDiffManager"),
- ("discussions", "ProjectMergeRequestDiscussionManager"),
- ("notes", "ProjectMergeRequestNoteManager"),
- ("pipelines", "ProjectMergeRequestPipelineManager"),
- ("resourcelabelevents", "ProjectMergeRequestResourceLabelEventManager"),
- ("resourcemilestoneevents", "ProjectMergeRequestResourceMilestoneEventManager"),
- ("resourcestateevents", "ProjectMergeRequestResourceStateEventManager"),
- )
+ approval_rules: ProjectMergeRequestApprovalRuleManager
+ approvals: ProjectMergeRequestApprovalManager
+ awardemojis: ProjectMergeRequestAwardEmojiManager
+ diffs: "ProjectMergeRequestDiffManager"
+ discussions: ProjectMergeRequestDiscussionManager
+ notes: ProjectMergeRequestNoteManager
+ pipelines: ProjectMergeRequestPipelineManager
+ resourcelabelevents: ProjectMergeRequestResourceLabelEventManager
+ resourcemilestoneevents: ProjectMergeRequestResourceMilestoneEventManager
+ resourcestateevents: ProjectMergeRequestResourceStateEventManager
@cli.register_custom_action("ProjectMergeRequest")
@exc.on_http_error(exc.GitlabMROnBuildSuccessError)
diff --git a/gitlab/v4/objects/notes.py b/gitlab/v4/objects/notes.py
index d85fea7..cbd237e 100644
--- a/gitlab/v4/objects/notes.py
+++ b/gitlab/v4/objects/notes.py
@@ -71,7 +71,7 @@ class ProjectCommitDiscussionNoteManager(
class ProjectIssueNote(SaveMixin, ObjectDeleteMixin, RESTObject):
- _managers = (("awardemojis", "ProjectIssueNoteAwardEmojiManager"),)
+ awardemojis: ProjectIssueNoteAwardEmojiManager
class ProjectIssueNoteManager(CRUDMixin, RESTManager):
@@ -104,7 +104,7 @@ class ProjectIssueDiscussionNoteManager(
class ProjectMergeRequestNote(SaveMixin, ObjectDeleteMixin, RESTObject):
- _managers = (("awardemojis", "ProjectMergeRequestNoteAwardEmojiManager"),)
+ awardemojis: ProjectMergeRequestNoteAwardEmojiManager
class ProjectMergeRequestNoteManager(CRUDMixin, RESTManager):
@@ -137,7 +137,7 @@ class ProjectMergeRequestDiscussionNoteManager(
class ProjectSnippetNote(SaveMixin, ObjectDeleteMixin, RESTObject):
- _managers = (("awardemojis", "ProjectSnippetNoteAwardEmojiManager"),)
+ awardemojis: ProjectMergeRequestNoteAwardEmojiManager
class ProjectSnippetNoteManager(CRUDMixin, RESTManager):
diff --git a/gitlab/v4/objects/packages.py b/gitlab/v4/objects/packages.py
index 3e9d9f2..d7fe9dc 100644
--- a/gitlab/v4/objects/packages.py
+++ b/gitlab/v4/objects/packages.py
@@ -143,7 +143,7 @@ class GroupPackageManager(ListMixin, RESTManager):
class ProjectPackage(ObjectDeleteMixin, RESTObject):
- _managers = (("package_files", "ProjectPackageFileManager"),)
+ package_files: "ProjectPackageFileManager"
class ProjectPackageManager(ListMixin, GetMixin, DeleteMixin, RESTManager):
diff --git a/gitlab/v4/objects/pipelines.py b/gitlab/v4/objects/pipelines.py
index 5118e78..d604a3a 100644
--- a/gitlab/v4/objects/pipelines.py
+++ b/gitlab/v4/objects/pipelines.py
@@ -74,12 +74,10 @@ class ProjectMergeRequestPipelineManager(CreateMixin, ListMixin, RESTManager):
class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
- _managers = (
- ("jobs", "ProjectPipelineJobManager"),
- ("bridges", "ProjectPipelineBridgeManager"),
- ("variables", "ProjectPipelineVariableManager"),
- ("test_report", "ProjectPipelineTestReportManager"),
- )
+ bridges: "ProjectPipelineBridgeManager"
+ jobs: "ProjectPipelineJobManager"
+ test_report: "ProjectPipelineTestReportManager"
+ variables: "ProjectPipelineVariableManager"
@cli.register_custom_action("ProjectPipeline")
@exc.on_http_error(exc.GitlabPipelineCancelError)
@@ -199,7 +197,7 @@ class ProjectPipelineScheduleVariableManager(
class ProjectPipelineSchedule(SaveMixin, ObjectDeleteMixin, RESTObject):
- _managers = (("variables", "ProjectPipelineScheduleVariableManager"),)
+ variables: ProjectPipelineScheduleVariableManager
@cli.register_custom_action("ProjectPipelineSchedule")
@exc.on_http_error(exc.GitlabOwnershipError)
diff --git a/gitlab/v4/objects/projects.py b/gitlab/v4/objects/projects.py
index ee7aca8..8392dda 100644
--- a/gitlab/v4/objects/projects.py
+++ b/gitlab/v4/objects/projects.py
@@ -110,60 +110,59 @@ class GroupProjectManager(ListMixin, RESTManager):
class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTObject):
_short_print_attr = "path"
- _managers = (
- ("access_tokens", "ProjectAccessTokenManager"),
- ("accessrequests", "ProjectAccessRequestManager"),
- ("approvals", "ProjectApprovalManager"),
- ("approvalrules", "ProjectApprovalRuleManager"),
- ("badges", "ProjectBadgeManager"),
- ("boards", "ProjectBoardManager"),
- ("branches", "ProjectBranchManager"),
- ("jobs", "ProjectJobManager"),
- ("commits", "ProjectCommitManager"),
- ("customattributes", "ProjectCustomAttributeManager"),
- ("deployments", "ProjectDeploymentManager"),
- ("environments", "ProjectEnvironmentManager"),
- ("events", "ProjectEventManager"),
- ("audit_events", "ProjectAuditEventManager"),
- ("exports", "ProjectExportManager"),
- ("files", "ProjectFileManager"),
- ("forks", "ProjectForkManager"),
- ("generic_packages", "GenericPackageManager"),
- ("hooks", "ProjectHookManager"),
- ("keys", "ProjectKeyManager"),
- ("imports", "ProjectImportManager"),
- ("issues", "ProjectIssueManager"),
- ("labels", "ProjectLabelManager"),
- ("members", "ProjectMemberManager"),
- ("members_all", "ProjectMemberAllManager"),
- ("mergerequests", "ProjectMergeRequestManager"),
- ("milestones", "ProjectMilestoneManager"),
- ("notes", "ProjectNoteManager"),
- ("notificationsettings", "ProjectNotificationSettingsManager"),
- ("packages", "ProjectPackageManager"),
- ("pagesdomains", "ProjectPagesDomainManager"),
- ("pipelines", "ProjectPipelineManager"),
- ("protectedbranches", "ProjectProtectedBranchManager"),
- ("protectedtags", "ProjectProtectedTagManager"),
- ("pipelineschedules", "ProjectPipelineScheduleManager"),
- ("pushrules", "ProjectPushRulesManager"),
- ("releases", "ProjectReleaseManager"),
- ("remote_mirrors", "ProjectRemoteMirrorManager"),
- ("repositories", "ProjectRegistryRepositoryManager"),
- ("runners", "ProjectRunnerManager"),
- ("services", "ProjectServiceManager"),
- ("snippets", "ProjectSnippetManager"),
- ("tags", "ProjectTagManager"),
- ("users", "ProjectUserManager"),
- ("triggers", "ProjectTriggerManager"),
- ("variables", "ProjectVariableManager"),
- ("wikis", "ProjectWikiManager"),
- ("clusters", "ProjectClusterManager"),
- ("additionalstatistics", "ProjectAdditionalStatisticsManager"),
- ("issues_statistics", "ProjectIssuesStatisticsManager"),
- ("issuesstatistics", "ProjectIssuesStatisticsManager"), # Deprecated
- ("deploytokens", "ProjectDeployTokenManager"),
- )
+
+ access_tokens: ProjectAccessTokenManager
+ accessrequests: ProjectAccessRequestManager
+ additionalstatistics: ProjectAdditionalStatisticsManager
+ approvalrules: ProjectApprovalRuleManager
+ approvals: ProjectApprovalManager
+ audit_events: ProjectAuditEventManager
+ badges: ProjectBadgeManager
+ boards: ProjectBoardManager
+ branches: ProjectBranchManager
+ clusters: ProjectClusterManager
+ commits: ProjectCommitManager
+ customattributes: ProjectCustomAttributeManager
+ deployments: ProjectDeploymentManager
+ deploytokens: ProjectDeployTokenManager
+ environments: ProjectEnvironmentManager
+ events: ProjectEventManager
+ exports: ProjectExportManager
+ files: ProjectFileManager
+ forks: "ProjectForkManager"
+ generic_packages: GenericPackageManager
+ hooks: ProjectHookManager
+ imports: ProjectImportManager
+ issues: ProjectIssueManager
+ issues_statistics: ProjectIssuesStatisticsManager
+ issuesstatistics: ProjectIssuesStatisticsManager # Deprecated
+ jobs: ProjectJobManager
+ keys: ProjectKeyManager
+ labels: ProjectLabelManager
+ members: ProjectMemberManager
+ members_all: ProjectMemberAllManager
+ mergerequests: ProjectMergeRequestManager
+ milestones: ProjectMilestoneManager
+ notes: ProjectNoteManager
+ notificationsettings: ProjectNotificationSettingsManager
+ packages: ProjectPackageManager
+ pagesdomains: ProjectPagesDomainManager
+ pipelines: ProjectPipelineManager
+ pipelineschedules: ProjectPipelineScheduleManager
+ protectedbranches: ProjectProtectedBranchManager
+ protectedtags: ProjectProtectedTagManager
+ pushrules: ProjectPushRulesManager
+ releases: ProjectReleaseManager
+ remote_mirrors: "ProjectRemoteMirrorManager"
+ repositories: ProjectRegistryRepositoryManager
+ runners: ProjectRunnerManager
+ services: ProjectServiceManager
+ snippets: ProjectSnippetManager
+ tags: ProjectTagManager
+ triggers: ProjectTriggerManager
+ users: ProjectUserManager
+ variables: ProjectVariableManager
+ wikis: ProjectWikiManager
@cli.register_custom_action("Project", ("forked_from_id",))
@exc.on_http_error(exc.GitlabCreateError)
diff --git a/gitlab/v4/objects/releases.py b/gitlab/v4/objects/releases.py
index e27052d..2af3248 100644
--- a/gitlab/v4/objects/releases.py
+++ b/gitlab/v4/objects/releases.py
@@ -11,7 +11,8 @@ __all__ = [
class ProjectRelease(SaveMixin, RESTObject):
_id_attr = "tag_name"
- _managers = (("links", "ProjectReleaseLinkManager"),)
+
+ links: "ProjectReleaseLinkManager"
class ProjectReleaseManager(CRUDMixin, RESTManager):
diff --git a/gitlab/v4/objects/runners.py b/gitlab/v4/objects/runners.py
index 8a18f9b..a32dc84 100644
--- a/gitlab/v4/objects/runners.py
+++ b/gitlab/v4/objects/runners.py
@@ -34,7 +34,7 @@ class RunnerJobManager(ListMixin, RESTManager):
class Runner(SaveMixin, ObjectDeleteMixin, RESTObject):
- _managers = (("jobs", "RunnerJobManager"),)
+ jobs: RunnerJobManager
class RunnerManager(CRUDMixin, RESTManager):
diff --git a/gitlab/v4/objects/snippets.py b/gitlab/v4/objects/snippets.py
index b893eca..164b30c 100644
--- a/gitlab/v4/objects/snippets.py
+++ b/gitlab/v4/objects/snippets.py
@@ -77,11 +77,10 @@ class SnippetManager(CRUDMixin, RESTManager):
class ProjectSnippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
_url = "/projects/%(project_id)s/snippets"
_short_print_attr = "title"
- _managers = (
- ("awardemojis", "ProjectSnippetAwardEmojiManager"),
- ("discussions", "ProjectSnippetDiscussionManager"),
- ("notes", "ProjectSnippetNoteManager"),
- )
+
+ awardemojis: ProjectSnippetAwardEmojiManager
+ discussions: ProjectSnippetDiscussionManager
+ notes: ProjectSnippetNoteManager
@cli.register_custom_action("ProjectSnippet")
@exc.on_http_error(exc.GitlabGetError)
diff --git a/gitlab/v4/objects/users.py b/gitlab/v4/objects/users.py
index cc5cfd8..c0f8745 100644
--- a/gitlab/v4/objects/users.py
+++ b/gitlab/v4/objects/users.py
@@ -97,12 +97,11 @@ class CurrentUserStatusManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
class CurrentUser(RESTObject):
_id_attr = None
_short_print_attr = "username"
- _managers = (
- ("status", "CurrentUserStatusManager"),
- ("emails", "CurrentUserEmailManager"),
- ("gpgkeys", "CurrentUserGPGKeyManager"),
- ("keys", "CurrentUserKeyManager"),
- )
+
+ emails: CurrentUserEmailManager
+ gpgkeys: CurrentUserGPGKeyManager
+ keys: CurrentUserKeyManager
+ status: CurrentUserStatusManager
class CurrentUserManager(GetWithoutIdMixin, RESTManager):
@@ -112,20 +111,19 @@ class CurrentUserManager(GetWithoutIdMixin, RESTManager):
class User(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "username"
- _managers = (
- ("customattributes", "UserCustomAttributeManager"),
- ("emails", "UserEmailManager"),
- ("followers_users", "UserFollowersManager"),
- ("following_users", "UserFollowingManager"),
- ("events", "UserEventManager"),
- ("gpgkeys", "UserGPGKeyManager"),
- ("identityproviders", "UserIdentityProviderManager"),
- ("impersonationtokens", "UserImpersonationTokenManager"),
- ("keys", "UserKeyManager"),
- ("memberships", "UserMembershipManager"),
- ("projects", "UserProjectManager"),
- ("status", "UserStatusManager"),
- )
+
+ customattributes: UserCustomAttributeManager
+ emails: "UserEmailManager"
+ events: UserEventManager
+ followers_users: "UserFollowersManager"
+ following_users: "UserFollowingManager"
+ gpgkeys: "UserGPGKeyManager"
+ identityproviders: "UserIdentityProviderManager"
+ impersonationtokens: "UserImpersonationTokenManager"
+ keys: "UserKeyManager"
+ memberships: "UserMembershipManager"
+ projects: "UserProjectManager"
+ status: "UserStatusManager"
@cli.register_custom_action("User")
@exc.on_http_error(exc.GitlabBlockError)
diff --git a/tests/functional/api/test_merge_requests.py b/tests/functional/api/test_merge_requests.py
index 179ae6f..b20b66a 100644
--- a/tests/functional/api/test_merge_requests.py
+++ b/tests/functional/api/test_merge_requests.py
@@ -125,10 +125,18 @@ def test_merge_request_should_remove_source_branch(
time.sleep(0.5)
assert mr.merged_at is not None
time.sleep(0.5)
+ result = wait_for_sidekiq(timeout=60)
+ assert result is True, "sidekiq process should have terminated but did not"
# Ensure we can NOT get the MR branch
with pytest.raises(gitlab.exceptions.GitlabGetError):
- project.branches.get(source_branch)
+ result = project.branches.get(source_branch)
+ # Help to debug in case the expected exception doesn't happen.
+ import pprint
+
+ print("mr:", pprint.pformat(mr))
+ print("mr.merged_at:", pprint.pformat(mr.merged_at))
+ print("result:", pprint.pformat(result))
def test_merge_request_large_commit_message(
diff --git a/tests/unit/test_base.py b/tests/unit/test_base.py
index 8872dbd..cccdfad 100644
--- a/tests/unit/test_base.py
+++ b/tests/unit/test_base.py
@@ -147,7 +147,7 @@ class TestRESTObject:
def test_create_managers(self, fake_gitlab, fake_manager):
class ObjectWithManager(FakeObject):
- _managers = (("fakes", "FakeManager"),)
+ fakes: "FakeManager"
obj = ObjectWithManager(fake_manager, {"foo": "bar"})
obj.id = 42