Skip to content

Commit c9b5d3b

Browse files
chore: improve type-hinting for managers
The 'managers' are dynamically created. This unfortunately means that we don't have any type-hints for them and so editors which understand type-hints won't know that they are valid attributes. * Add the type-hints for the managers we define. * Add a unit test that makes sure that the type-hints and the '_managers' attribute are kept in sync with each other. * Add unit test that makes sure specified managers in '_managers' have a name ending in 'Managers' to keep with current convention. * Make RESTObject._managers always present with a default value of None. * Fix a type-issue revealed now that mypy knows what the type is
1 parent b8a47ba commit c9b5d3b

21 files changed

+249
-20
lines changed

gitlab/base.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class RESTObject(object):
4949
_parent_attrs: Dict[str, Any]
5050
_short_print_attr: Optional[str] = None
5151
_updated_attrs: Dict[str, Any]
52+
_managers: Optional[Iterable[Tuple[str, str]]] = None
5253
manager: "RESTManager"
5354

5455
def __init__(self, manager: "RESTManager", attrs: Dict[str, Any]) -> None:
@@ -150,13 +151,13 @@ def __hash__(self) -> int:
150151
return hash(self.get_id())
151152

152153
def _create_managers(self) -> None:
153-
managers = getattr(self, "_managers", None)
154-
if managers is None:
154+
if self._managers is None:
155155
return
156156

157157
for attr, cls_name in self._managers:
158158
cls = getattr(self._module, cls_name)
159159
manager = cls(self.manager.gitlab, parent=self)
160+
# Since we have our own __setattr__ method, we can't use setattr()
160161
self.__dict__[attr] = manager
161162

162163
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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class GroupBoardListManager(CRUDMixin, RESTManager):
2626

2727

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

3132

@@ -49,6 +50,7 @@ class ProjectBoardListManager(CRUDMixin, RESTManager):
4950

5051

5152
class ProjectBoard(SaveMixin, ObjectDeleteMixin, RESTObject):
53+
lists: ProjectBoardListManager
5254
_managers = (("lists", "ProjectBoardListManager"),)
5355

5456

gitlab/v4/objects/commits.py

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

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

gitlab/v4/objects/container_registry.py

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

1313

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

1718

gitlab/v4/objects/deployments.py

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

1111

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

1516

gitlab/v4/objects/discussions.py

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

2222

2323
class ProjectCommitDiscussion(RESTObject):
24+
notes: ProjectCommitDiscussionNoteManager
2425
_managers = (("notes", "ProjectCommitDiscussionNoteManager"),)
2526

2627

@@ -32,6 +33,7 @@ class ProjectCommitDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
3233

3334

3435
class ProjectIssueDiscussion(RESTObject):
36+
notes: ProjectIssueDiscussionNoteManager
3537
_managers = (("notes", "ProjectIssueDiscussionNoteManager"),)
3638

3739

@@ -43,6 +45,7 @@ class ProjectIssueDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
4345

4446

4547
class ProjectMergeRequestDiscussion(SaveMixin, RESTObject):
48+
notes: ProjectMergeRequestDiscussionNoteManager
4649
_managers = (("notes", "ProjectMergeRequestDiscussionNoteManager"),)
4750

4851

@@ -59,6 +62,7 @@ class ProjectMergeRequestDiscussionManager(
5962

6063

6164
class ProjectSnippetDiscussion(RESTObject):
65+
notes: ProjectSnippetDiscussionNoteManager
6266
_managers = (("notes", "ProjectSnippetDiscussionNoteManager"),)
6367

6468

gitlab/v4/objects/epics.py

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

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

gitlab/v4/objects/groups.py

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

4444
class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
4545
_short_print_attr = "name"
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
4674
_managers = (
4775
("accessrequests", "GroupAccessRequestManager"),
4876
("audit_events", "GroupAuditEventManager"),

gitlab/v4/objects/issues.py

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

0 commit comments

Comments
 (0)