Skip to content

feat: display human-readable attribute in repr() if present #2010

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions gitlab/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,20 @@ class RESTObject:
another. This allows smart updates, if the object allows it.

You can redefine ``_id_attr`` in child classes to specify which attribute
must be used as uniq ID. ``None`` means that the object can be updated
must be used as the unique ID. ``None`` means that the object can be updated
without ID in the url.

Likewise, you can define a ``_repr_attr`` in subclasses to specify which
attribute should be added as a human-readable identifier when called in the
object's ``__repr__()`` method.
"""

_id_attr: Optional[str] = "id"
_attrs: Dict[str, Any]
_created_from_list: bool # Indicates if object was created from a list() action
_module: ModuleType
_parent_attrs: Dict[str, Any]
_short_print_attr: Optional[str] = None
_repr_attr: Optional[str] = None
_updated_attrs: Dict[str, Any]
manager: "RESTManager"

Expand Down Expand Up @@ -158,10 +162,19 @@ def pprint(self) -> None:
print(self.pformat())

def __repr__(self) -> str:
name = self.__class__.__name__

if (self._id_attr and self._repr_attr) and (self._id_attr != self._repr_attr):
return (
f"<{name} {self._id_attr}:{self.get_id()} "
f"{self._repr_attr}:{getattr(self, self._repr_attr)}>"
)
if self._id_attr:
return f"<{self.__class__.__name__} {self._id_attr}:{self.get_id()}>"
else:
return f"<{self.__class__.__name__}>"
return f"<{name} {self._id_attr}:{self.get_id()}>"
if self._repr_attr:
return f"<{name} {self._repr_attr}:{getattr(self, self._repr_attr)}>"

return f"<{name}>"

def __eq__(self, other: object) -> bool:
if not isinstance(other, RESTObject):
Expand Down
6 changes: 3 additions & 3 deletions gitlab/v4/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,12 @@ def display_dict(d: Dict[str, Any], padding: int) -> None:
if obj._id_attr:
id = getattr(obj, obj._id_attr)
print(f"{obj._id_attr.replace('_', '-')}: {id}")
if obj._short_print_attr:
value = getattr(obj, obj._short_print_attr) or "None"
if obj._repr_attr:
value = getattr(obj, obj._repr_attr, "None")
value = value.replace("\r", "").replace("\n", " ")
# If the attribute is a note (ProjectCommitComment) then we do
# some modifications to fit everything on one line
line = f"{obj._short_print_attr}: {value}"
line = f"{obj._repr_attr}: {value}"
# ellipsize long lines (comments)
if len(line) > 79:
line = f"{line[:76]}..."
Expand Down
2 changes: 1 addition & 1 deletion gitlab/v4/objects/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class Application(ObjectDeleteMixin, RESTObject):
_url = "/applications"
_short_print_attr = "name"
_repr_attr = "name"


class ApplicationManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
Expand Down
4 changes: 2 additions & 2 deletions gitlab/v4/objects/commits.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


class ProjectCommit(RESTObject):
_short_print_attr = "title"
_repr_attr = "title"

comments: "ProjectCommitCommentManager"
discussions: ProjectCommitDiscussionManager
Expand Down Expand Up @@ -172,7 +172,7 @@ def get(

class ProjectCommitComment(RESTObject):
_id_attr = None
_short_print_attr = "note"
_repr_attr = "note"


class ProjectCommitCommentManager(ListMixin, CreateMixin, RESTManager):
Expand Down
2 changes: 1 addition & 1 deletion gitlab/v4/objects/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

class Event(RESTObject):
_id_attr = None
_short_print_attr = "target_title"
_repr_attr = "target_title"


class EventManager(ListMixin, RESTManager):
Expand Down
2 changes: 1 addition & 1 deletion gitlab/v4/objects/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

class ProjectFile(SaveMixin, ObjectDeleteMixin, RESTObject):
_id_attr = "file_path"
_short_print_attr = "file_path"
_repr_attr = "file_path"
file_path: str
manager: "ProjectFileManager"

Expand Down
2 changes: 1 addition & 1 deletion gitlab/v4/objects/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@


class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "name"
_repr_attr = "name"

access_tokens: GroupAccessTokenManager
accessrequests: GroupAccessRequestManager
Expand Down
6 changes: 3 additions & 3 deletions gitlab/v4/objects/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

class Hook(ObjectDeleteMixin, RESTObject):
_url = "/hooks"
_short_print_attr = "url"
_repr_attr = "url"


class HookManager(NoUpdateMixin, RESTManager):
Expand All @@ -28,7 +28,7 @@ def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Hook:


class ProjectHook(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "url"
_repr_attr = "url"


class ProjectHookManager(CRUDMixin, RESTManager):
Expand Down Expand Up @@ -75,7 +75,7 @@ def get(


class GroupHook(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "url"
_repr_attr = "url"


class GroupHookManager(CRUDMixin, RESTManager):
Expand Down
4 changes: 2 additions & 2 deletions gitlab/v4/objects/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

class Issue(RESTObject):
_url = "/issues"
_short_print_attr = "title"
_repr_attr = "title"


class IssueManager(RetrieveMixin, RESTManager):
Expand Down Expand Up @@ -108,7 +108,7 @@ class ProjectIssue(
ObjectDeleteMixin,
RESTObject,
):
_short_print_attr = "title"
_repr_attr = "title"
_id_attr = "iid"

awardemojis: ProjectIssueAwardEmojiManager
Expand Down
10 changes: 5 additions & 5 deletions gitlab/v4/objects/members.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@


class GroupMember(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "username"
_repr_attr = "username"


class GroupMemberManager(CRUDMixin, RESTManager):
Expand All @@ -50,7 +50,7 @@ def get(


class GroupBillableMember(ObjectDeleteMixin, RESTObject):
_short_print_attr = "username"
_repr_attr = "username"

memberships: "GroupBillableMemberMembershipManager"

Expand All @@ -73,7 +73,7 @@ class GroupBillableMemberMembershipManager(ListMixin, RESTManager):


class GroupMemberAll(RESTObject):
_short_print_attr = "username"
_repr_attr = "username"


class GroupMemberAllManager(RetrieveMixin, RESTManager):
Expand All @@ -88,7 +88,7 @@ def get(


class ProjectMember(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "username"
_repr_attr = "username"


class ProjectMemberManager(CRUDMixin, RESTManager):
Expand All @@ -110,7 +110,7 @@ def get(


class ProjectMemberAll(RESTObject):
_short_print_attr = "username"
_repr_attr = "username"


class ProjectMemberAllManager(RetrieveMixin, RESTManager):
Expand Down
2 changes: 1 addition & 1 deletion gitlab/v4/objects/merge_request_approvals.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def set_approvers(

class ProjectMergeRequestApprovalRule(SaveMixin, ObjectDeleteMixin, RESTObject):
_id_attr = "approval_rule_id"
_short_print_attr = "approval_rule"
_repr_attr = "approval_rule"
id: int

@exc.on_http_error(exc.GitlabUpdateError)
Expand Down
4 changes: 2 additions & 2 deletions gitlab/v4/objects/milestones.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


class GroupMilestone(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "title"
_repr_attr = "title"

@cli.register_custom_action("GroupMilestone")
@exc.on_http_error(exc.GitlabListError)
Expand Down Expand Up @@ -102,7 +102,7 @@ def get(


class ProjectMilestone(PromoteMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "title"
_repr_attr = "title"
_update_uses_post = True

@cli.register_custom_action("ProjectMilestone")
Expand Down
12 changes: 1 addition & 11 deletions gitlab/v4/objects/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class ProjectGroupManager(ListMixin, RESTManager):


class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTObject):
_short_print_attr = "path"
_repr_attr = "path"

access_tokens: ProjectAccessTokenManager
accessrequests: ProjectAccessRequestManager
Expand Down Expand Up @@ -186,16 +186,6 @@ class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTO
variables: ProjectVariableManager
wikis: ProjectWikiManager

def __repr__(self) -> str:
project_repr = super().__repr__()

if hasattr(self, "name_with_namespace"):
return (
f'{project_repr[:-1]} name_with_namespace:"{self.name_with_namespace}">'
)
else:
return project_repr

@cli.register_custom_action("Project", ("forked_from_id",))
@exc.on_http_error(exc.GitlabCreateError)
def create_fork_relation(self, forked_from_id: int, **kwargs: Any) -> None:
Expand Down
4 changes: 2 additions & 2 deletions gitlab/v4/objects/snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


class Snippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "title"
_repr_attr = "title"

@cli.register_custom_action("Snippet")
@exc.on_http_error(exc.GitlabGetError)
Expand Down Expand Up @@ -91,7 +91,7 @@ def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Snippet

class ProjectSnippet(UserAgentDetailMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
_url = "/projects/{project_id}/snippets"
_short_print_attr = "title"
_repr_attr = "title"

awardemojis: ProjectSnippetAwardEmojiManager
discussions: ProjectSnippetDiscussionManager
Expand Down
4 changes: 2 additions & 2 deletions gitlab/v4/objects/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class ProjectTag(ObjectDeleteMixin, RESTObject):
_id_attr = "name"
_short_print_attr = "name"
_repr_attr = "name"


class ProjectTagManager(NoUpdateMixin, RESTManager):
Expand All @@ -30,7 +30,7 @@ def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Project

class ProjectProtectedTag(ObjectDeleteMixin, RESTObject):
_id_attr = "name"
_short_print_attr = "name"
_repr_attr = "name"


class ProjectProtectedTagManager(NoUpdateMixin, RESTManager):
Expand Down
14 changes: 7 additions & 7 deletions gitlab/v4/objects/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@


class CurrentUserEmail(ObjectDeleteMixin, RESTObject):
_short_print_attr = "email"
_repr_attr = "email"


class CurrentUserEmailManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
Expand Down Expand Up @@ -96,7 +96,7 @@ def get(


class CurrentUserKey(ObjectDeleteMixin, RESTObject):
_short_print_attr = "title"
_repr_attr = "title"


class CurrentUserKeyManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
Expand All @@ -112,7 +112,7 @@ def get(

class CurrentUserStatus(SaveMixin, RESTObject):
_id_attr = None
_short_print_attr = "message"
_repr_attr = "message"


class CurrentUserStatusManager(GetWithoutIdMixin, UpdateMixin, RESTManager):
Expand All @@ -128,7 +128,7 @@ def get(

class CurrentUser(RESTObject):
_id_attr = None
_short_print_attr = "username"
_repr_attr = "username"

emails: CurrentUserEmailManager
gpgkeys: CurrentUserGPGKeyManager
Expand All @@ -147,7 +147,7 @@ def get(


class User(SaveMixin, ObjectDeleteMixin, RESTObject):
_short_print_attr = "username"
_repr_attr = "username"

customattributes: UserCustomAttributeManager
emails: "UserEmailManager"
Expand Down Expand Up @@ -373,7 +373,7 @@ class ProjectUserManager(ListMixin, RESTManager):


class UserEmail(ObjectDeleteMixin, RESTObject):
_short_print_attr = "email"
_repr_attr = "email"


class UserEmailManager(RetrieveMixin, CreateMixin, DeleteMixin, RESTManager):
Expand All @@ -392,7 +392,7 @@ class UserActivities(RESTObject):

class UserStatus(RESTObject):
_id_attr = None
_short_print_attr = "message"
_repr_attr = "message"


class UserStatusManager(GetWithoutIdMixin, RESTManager):
Expand Down
4 changes: 2 additions & 2 deletions gitlab/v4/objects/wikis.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class ProjectWiki(SaveMixin, ObjectDeleteMixin, RESTObject):
_id_attr = "slug"
_short_print_attr = "slug"
_repr_attr = "slug"


class ProjectWikiManager(CRUDMixin, RESTManager):
Expand All @@ -34,7 +34,7 @@ def get(

class GroupWiki(SaveMixin, ObjectDeleteMixin, RESTObject):
_id_attr = "slug"
_short_print_attr = "slug"
_repr_attr = "slug"


class GroupWikiManager(CRUDMixin, RESTManager):
Expand Down
Loading