Skip to content

Commit 5247e8b

Browse files
authored
Merge pull request #1512 from JohnVillalovos/jlvillal/type_managers
chore: improve type-hinting for managers
2 parents b8a47ba + 487b9a8 commit 5247e8b

22 files changed

+178
-168
lines changed

gitlab/base.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,22 @@ def __hash__(self) -> int:
150150
return hash(self.get_id())
151151

152152
def _create_managers(self) -> None:
153-
managers = getattr(self, "_managers", None)
154-
if managers is None:
155-
return
156-
157-
for attr, cls_name in self._managers:
153+
# NOTE(jlvillal): We are creating our managers by looking at the class
154+
# annotations. If an attribute is annotated as being a *Manager type
155+
# then we create the manager and assign it to the attribute.
156+
for attr, annotation in sorted(self.__annotations__.items()):
157+
if not isinstance(annotation, (type, str)):
158+
continue
159+
if isinstance(annotation, type):
160+
cls_name = annotation.__name__
161+
else:
162+
cls_name = annotation
163+
# All *Manager classes are used except for the base "RESTManager" class
164+
if cls_name == "RESTManager" or not cls_name.endswith("Manager"):
165+
continue
158166
cls = getattr(self._module, cls_name)
159167
manager = cls(self.manager.gitlab, parent=self)
168+
# Since we have our own __setattr__ method, we can't use setattr()
160169
self.__dict__[attr] = manager
161170

162171
def _update_attrs(self, new_attrs: Dict[str, Any]) -> None:

gitlab/v4/cli.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,10 @@ def do_custom(self) -> Any:
9999
def do_project_export_download(self) -> None:
100100
try:
101101
project = self.gl.projects.get(int(self.args["project_id"]), lazy=True)
102-
data = project.exports.get().download()
102+
export_status = project.exports.get()
103+
if TYPE_CHECKING:
104+
assert export_status is not None
105+
data = export_status.download()
103106
sys.stdout.buffer.write(data)
104107

105108
except Exception as e:

gitlab/v4/objects/boards.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class GroupBoardListManager(CRUDMixin, RESTManager):
2626

2727

2828
class GroupBoard(SaveMixin, ObjectDeleteMixin, RESTObject):
29-
_managers = (("lists", "GroupBoardListManager"),)
29+
lists: GroupBoardListManager
3030

3131

3232
class GroupBoardManager(CRUDMixin, RESTManager):
@@ -49,7 +49,7 @@ class ProjectBoardListManager(CRUDMixin, RESTManager):
4949

5050

5151
class ProjectBoard(SaveMixin, ObjectDeleteMixin, RESTObject):
52-
_managers = (("lists", "ProjectBoardListManager"),)
52+
lists: ProjectBoardListManager
5353

5454

5555
class ProjectBoardManager(CRUDMixin, RESTManager):

gitlab/v4/objects/commits.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@
1717

1818
class ProjectCommit(RESTObject):
1919
_short_print_attr = "title"
20-
_managers = (
21-
("comments", "ProjectCommitCommentManager"),
22-
("discussions", "ProjectCommitDiscussionManager"),
23-
("statuses", "ProjectCommitStatusManager"),
24-
)
20+
21+
comments: "ProjectCommitCommentManager"
22+
discussions: ProjectCommitDiscussionManager
23+
statuses: "ProjectCommitStatusManager"
2524

2625
@cli.register_custom_action("ProjectCommit")
2726
@exc.on_http_error(exc.GitlabGetError)

gitlab/v4/objects/container_registry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
class ProjectRegistryRepository(ObjectDeleteMixin, RESTObject):
15-
_managers = (("tags", "ProjectRegistryTagManager"),)
15+
tags: "ProjectRegistryTagManager"
1616

1717

1818
class ProjectRegistryRepositoryManager(DeleteMixin, ListMixin, RESTManager):

gitlab/v4/objects/deployments.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
class ProjectDeployment(SaveMixin, RESTObject):
13-
_managers = (("mergerequests", "ProjectDeploymentMergeRequestManager"),)
13+
mergerequests: ProjectDeploymentMergeRequestManager
1414

1515

1616
class ProjectDeploymentManager(RetrieveMixin, CreateMixin, UpdateMixin, RESTManager):

gitlab/v4/objects/discussions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222

2323
class ProjectCommitDiscussion(RESTObject):
24-
_managers = (("notes", "ProjectCommitDiscussionNoteManager"),)
24+
notes: ProjectCommitDiscussionNoteManager
2525

2626

2727
class ProjectCommitDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
@@ -32,7 +32,7 @@ class ProjectCommitDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
3232

3333

3434
class ProjectIssueDiscussion(RESTObject):
35-
_managers = (("notes", "ProjectIssueDiscussionNoteManager"),)
35+
notes: ProjectIssueDiscussionNoteManager
3636

3737

3838
class ProjectIssueDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
@@ -43,7 +43,7 @@ class ProjectIssueDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
4343

4444

4545
class ProjectMergeRequestDiscussion(SaveMixin, RESTObject):
46-
_managers = (("notes", "ProjectMergeRequestDiscussionNoteManager"),)
46+
notes: ProjectMergeRequestDiscussionNoteManager
4747

4848

4949
class ProjectMergeRequestDiscussionManager(
@@ -59,7 +59,7 @@ class ProjectMergeRequestDiscussionManager(
5959

6060

6161
class ProjectSnippetDiscussion(RESTObject):
62-
_managers = (("notes", "ProjectSnippetDiscussionNoteManager"),)
62+
notes: ProjectSnippetDiscussionNoteManager
6363

6464

6565
class ProjectSnippetDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):

gitlab/v4/objects/epics.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@
2323

2424
class GroupEpic(ObjectDeleteMixin, SaveMixin, RESTObject):
2525
_id_attr = "iid"
26-
_managers = (
27-
("issues", "GroupEpicIssueManager"),
28-
("resourcelabelevents", "GroupEpicResourceLabelEventManager"),
29-
)
26+
27+
issues: "GroupEpicIssueManager"
28+
resourcelabelevents: GroupEpicResourceLabelEventManager
3029

3130

3231
class GroupEpicManager(CRUDMixin, RESTManager):

gitlab/v4/objects/groups.py

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,35 +43,34 @@
4343

4444
class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
4545
_short_print_attr = "name"
46-
_managers = (
47-
("accessrequests", "GroupAccessRequestManager"),
48-
("audit_events", "GroupAuditEventManager"),
49-
("badges", "GroupBadgeManager"),
50-
("billable_members", "GroupBillableMemberManager"),
51-
("boards", "GroupBoardManager"),
52-
("customattributes", "GroupCustomAttributeManager"),
53-
("descendant_groups", "GroupDescendantGroupManager"),
54-
("exports", "GroupExportManager"),
55-
("epics", "GroupEpicManager"),
56-
("hooks", "GroupHookManager"),
57-
("imports", "GroupImportManager"),
58-
("issues", "GroupIssueManager"),
59-
("issues_statistics", "GroupIssuesStatisticsManager"),
60-
("labels", "GroupLabelManager"),
61-
("members", "GroupMemberManager"),
62-
("members_all", "GroupMemberAllManager"),
63-
("mergerequests", "GroupMergeRequestManager"),
64-
("milestones", "GroupMilestoneManager"),
65-
("notificationsettings", "GroupNotificationSettingsManager"),
66-
("packages", "GroupPackageManager"),
67-
("projects", "GroupProjectManager"),
68-
("runners", "GroupRunnerManager"),
69-
("subgroups", "GroupSubgroupManager"),
70-
("variables", "GroupVariableManager"),
71-
("clusters", "GroupClusterManager"),
72-
("deploytokens", "GroupDeployTokenManager"),
73-
("wikis", "GroupWikiManager"),
74-
)
46+
47+
accessrequests: GroupAccessRequestManager
48+
audit_events: GroupAuditEventManager
49+
badges: GroupBadgeManager
50+
billable_members: GroupBillableMemberManager
51+
boards: GroupBoardManager
52+
clusters: GroupClusterManager
53+
customattributes: GroupCustomAttributeManager
54+
deploytokens: GroupDeployTokenManager
55+
descendant_groups: "GroupDescendantGroupManager"
56+
epics: GroupEpicManager
57+
exports: GroupExportManager
58+
hooks: GroupHookManager
59+
imports: GroupImportManager
60+
issues: GroupIssueManager
61+
issues_statistics: GroupIssuesStatisticsManager
62+
labels: GroupLabelManager
63+
members: GroupMemberManager
64+
members_all: GroupMemberAllManager
65+
mergerequests: GroupMergeRequestManager
66+
milestones: GroupMilestoneManager
67+
notificationsettings: GroupNotificationSettingsManager
68+
packages: GroupPackageManager
69+
projects: GroupProjectManager
70+
runners: GroupRunnerManager
71+
subgroups: "GroupSubgroupManager"
72+
variables: GroupVariableManager
73+
wikis: GroupWikiManager
7574

7675
@cli.register_custom_action("Group", ("to_project_id",))
7776
@exc.on_http_error(exc.GitlabTransferProjectError)

gitlab/v4/objects/issues.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,14 @@ class ProjectIssue(
105105
):
106106
_short_print_attr = "title"
107107
_id_attr = "iid"
108-
_managers = (
109-
("awardemojis", "ProjectIssueAwardEmojiManager"),
110-
("discussions", "ProjectIssueDiscussionManager"),
111-
("links", "ProjectIssueLinkManager"),
112-
("notes", "ProjectIssueNoteManager"),
113-
("resourcelabelevents", "ProjectIssueResourceLabelEventManager"),
114-
("resourcemilestoneevents", "ProjectIssueResourceMilestoneEventManager"),
115-
("resourcestateevents", "ProjectIssueResourceStateEventManager"),
116-
)
108+
109+
awardemojis: ProjectIssueAwardEmojiManager
110+
discussions: ProjectIssueDiscussionManager
111+
links: "ProjectIssueLinkManager"
112+
notes: ProjectIssueNoteManager
113+
resourcelabelevents: ProjectIssueResourceLabelEventManager
114+
resourcemilestoneevents: ProjectIssueResourceMilestoneEventManager
115+
resourcestateevents: ProjectIssueResourceStateEventManager
117116

118117
@cli.register_custom_action("ProjectIssue", ("to_project_id",))
119118
@exc.on_http_error(exc.GitlabUpdateError)

gitlab/v4/objects/members.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ class GroupMemberManager(MemberAllMixin, CRUDMixin, RESTManager):
4343

4444
class GroupBillableMember(ObjectDeleteMixin, RESTObject):
4545
_short_print_attr = "username"
46-
_managers = (("memberships", "GroupBillableMemberMembershipManager"),)
46+
47+
memberships: "GroupBillableMemberMembershipManager"
4748

4849

4950
class GroupBillableMemberManager(ListMixin, DeleteMixin, RESTManager):

gitlab/v4/objects/merge_requests.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,18 +139,16 @@ class ProjectMergeRequest(
139139
):
140140
_id_attr = "iid"
141141

142-
_managers = (
143-
("approvals", "ProjectMergeRequestApprovalManager"),
144-
("approval_rules", "ProjectMergeRequestApprovalRuleManager"),
145-
("awardemojis", "ProjectMergeRequestAwardEmojiManager"),
146-
("diffs", "ProjectMergeRequestDiffManager"),
147-
("discussions", "ProjectMergeRequestDiscussionManager"),
148-
("notes", "ProjectMergeRequestNoteManager"),
149-
("pipelines", "ProjectMergeRequestPipelineManager"),
150-
("resourcelabelevents", "ProjectMergeRequestResourceLabelEventManager"),
151-
("resourcemilestoneevents", "ProjectMergeRequestResourceMilestoneEventManager"),
152-
("resourcestateevents", "ProjectMergeRequestResourceStateEventManager"),
153-
)
142+
approval_rules: ProjectMergeRequestApprovalRuleManager
143+
approvals: ProjectMergeRequestApprovalManager
144+
awardemojis: ProjectMergeRequestAwardEmojiManager
145+
diffs: "ProjectMergeRequestDiffManager"
146+
discussions: ProjectMergeRequestDiscussionManager
147+
notes: ProjectMergeRequestNoteManager
148+
pipelines: ProjectMergeRequestPipelineManager
149+
resourcelabelevents: ProjectMergeRequestResourceLabelEventManager
150+
resourcemilestoneevents: ProjectMergeRequestResourceMilestoneEventManager
151+
resourcestateevents: ProjectMergeRequestResourceStateEventManager
154152

155153
@cli.register_custom_action("ProjectMergeRequest")
156154
@exc.on_http_error(exc.GitlabMROnBuildSuccessError)

gitlab/v4/objects/notes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class ProjectCommitDiscussionNoteManager(
7171

7272

7373
class ProjectIssueNote(SaveMixin, ObjectDeleteMixin, RESTObject):
74-
_managers = (("awardemojis", "ProjectIssueNoteAwardEmojiManager"),)
74+
awardemojis: ProjectIssueNoteAwardEmojiManager
7575

7676

7777
class ProjectIssueNoteManager(CRUDMixin, RESTManager):
@@ -104,7 +104,7 @@ class ProjectIssueDiscussionNoteManager(
104104

105105

106106
class ProjectMergeRequestNote(SaveMixin, ObjectDeleteMixin, RESTObject):
107-
_managers = (("awardemojis", "ProjectMergeRequestNoteAwardEmojiManager"),)
107+
awardemojis: ProjectMergeRequestNoteAwardEmojiManager
108108

109109

110110
class ProjectMergeRequestNoteManager(CRUDMixin, RESTManager):
@@ -137,7 +137,7 @@ class ProjectMergeRequestDiscussionNoteManager(
137137

138138

139139
class ProjectSnippetNote(SaveMixin, ObjectDeleteMixin, RESTObject):
140-
_managers = (("awardemojis", "ProjectSnippetNoteAwardEmojiManager"),)
140+
awardemojis: ProjectMergeRequestNoteAwardEmojiManager
141141

142142

143143
class ProjectSnippetNoteManager(CRUDMixin, RESTManager):

gitlab/v4/objects/packages.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ class GroupPackageManager(ListMixin, RESTManager):
143143

144144

145145
class ProjectPackage(ObjectDeleteMixin, RESTObject):
146-
_managers = (("package_files", "ProjectPackageFileManager"),)
146+
package_files: "ProjectPackageFileManager"
147147

148148

149149
class ProjectPackageManager(ListMixin, GetMixin, DeleteMixin, RESTManager):

gitlab/v4/objects/pipelines.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,10 @@ def __call__(self, **kwargs):
7474

7575

7676
class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
77-
_managers = (
78-
("jobs", "ProjectPipelineJobManager"),
79-
("bridges", "ProjectPipelineBridgeManager"),
80-
("variables", "ProjectPipelineVariableManager"),
81-
("test_report", "ProjectPipelineTestReportManager"),
82-
)
77+
bridges: "ProjectPipelineBridgeManager"
78+
jobs: "ProjectPipelineJobManager"
79+
test_report: "ProjectPipelineTestReportManager"
80+
variables: "ProjectPipelineVariableManager"
8381

8482
@cli.register_custom_action("ProjectPipeline")
8583
@exc.on_http_error(exc.GitlabPipelineCancelError)
@@ -199,7 +197,7 @@ class ProjectPipelineScheduleVariableManager(
199197

200198

201199
class ProjectPipelineSchedule(SaveMixin, ObjectDeleteMixin, RESTObject):
202-
_managers = (("variables", "ProjectPipelineScheduleVariableManager"),)
200+
variables: ProjectPipelineScheduleVariableManager
203201

204202
@cli.register_custom_action("ProjectPipelineSchedule")
205203
@exc.on_http_error(exc.GitlabOwnershipError)

0 commit comments

Comments
 (0)