Skip to content

Role

attrs class Role (DiscordObject)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

Source code in naff/models/discord/role.py
@define()
@total_ordering
class Role(DiscordObject):
    _sentinel = object()

    name: str = field(repr=True)
    color: "Color" = field(converter=Color)
    hoist: bool = field(default=False)
    position: int = field(repr=True)
    permissions: "Permissions" = field(converter=Permissions)
    managed: bool = field(default=False)
    mentionable: bool = field(default=True)
    premium_subscriber: bool = field(default=_sentinel, converter=partial(sentinel_converter, sentinel=_sentinel))
    _icon: Optional[Asset] = field(default=None)
    _unicode_emoji: Optional[PartialEmoji] = field(default=None, converter=optional_c(PartialEmoji.from_str))
    _guild_id: "Snowflake_Type" = field()
    _bot_id: Optional["Snowflake_Type"] = field(default=None)
    _integration_id: Optional["Snowflake_Type"] = field(default=None)  # todo integration object?

    def __lt__(self: "Role", other: "Role") -> bool:
        if not isinstance(self, Role) or not isinstance(other, Role):
            return NotImplemented

        if self._guild_id != other._guild_id:
            raise RuntimeError("Unable to compare Roles from different guilds.")

        if self.id == self._guild_id:  # everyone role
            # everyone role is on the bottom, so check if the other role is, well, not it
            # because then it must be higher than it
            return other.id != self.id

        if self.position < other.position:
            return True

        if self.position == other.position:
            # if two roles have the same position, which can happen thanks to discord, then
            # we can thankfully use their ids to determine which one is lower
            return self.id < other.id

        return False

    @classmethod
    def _process_dict(cls, data: Dict[str, Any], client: "Client") -> Dict[str, Any]:
        data.update(data.pop("tags", {}))

        if icon_hash := data.get("icon"):
            data["icon"] = Asset.from_path_hash(client, f"role-icons/{data['id']}/{{}}", icon_hash)

        return data

    async def fetch_bot(self) -> Optional["Member"]:
        """
        Fetch the bot associated with this role if any.

        Returns:
            Member object if any

        """
        if self._bot_id is None:
            return None
        return await self._client.cache.fetch_member(self._guild_id, self._bot_id)

    def get_bot(self) -> Optional["Member"]:
        """
        Get the bot associated with this role if any.

        Returns:
            Member object if any

        """
        if self._bot_id is None:
            return None
        return self._client.cache.get_member(self._guild_id, self._bot_id)

    @property
    def guild(self) -> "Guild":
        """The guild object this role is from."""
        return self._client.cache.get_guild(self._guild_id)

    @property
    def default(self) -> bool:
        """Is this the `@everyone` role."""
        return self.id == self._guild_id

    @property
    def bot_managed(self) -> bool:
        """Is this role owned/managed by a bot."""
        return self._bot_id is not None

    @property
    def mention(self) -> str:
        """Returns a string that would mention the role."""
        return f"<@&{self.id}>" if self.id != self._guild_id else "@everyone"

    @property
    def integration(self) -> bool:
        """Is this role owned/managed by an integration."""
        return self._integration_id is not None

    @property
    def members(self) -> list["Member"]:
        """List of members with this role"""
        return [member for member in self.guild.members if member.has_role(self)]

    @property
    def icon(self) -> Optional[Asset | PartialEmoji]:
        """
        The icon of this role

        Note:
            You have to use this method instead of the `_icon` attribute, because the first does account for unicode emojis
        """
        return self._icon or self._unicode_emoji

    @property
    def is_assignable(self) -> bool:
        """
        Can this role be assigned or removed by this bot?

        Note:
            This does not account for permissions, only the role hierarchy

        """
        return (self.default or self.guild.me.top_role > self) and not self.managed

    async def delete(self, reason: str = None) -> None:
        """
        Delete this role.

        Args:
            reason: An optional reason for this deletion

        """
        await self._client.http.delete_guild_role(self._guild_id, self.id, reason)

    async def edit(
        self,
        name: Absent[str] = MISSING,
        permissions: Absent[str] = MISSING,
        color: Absent[Union[int, Color]] = MISSING,
        hoist: Absent[bool] = MISSING,
        mentionable: Absent[bool] = MISSING,
    ) -> "Role":
        """
        Edit this role, all arguments are optional.

        Args:
            name: name of the role
            permissions: New permissions to use
            color: The color of the role
            hoist: whether the role should be displayed separately in the sidebar
            mentionable: whether the role should be mentionable

        Returns:
            Role with updated information

        """
        if isinstance(color, Color):
            color = color.value

        payload = dict_filter(
            {"name": name, "permissions": permissions, "color": color, "hoist": hoist, "mentionable": mentionable}
        )

        r_data = await self._client.http.modify_guild_role(self._guild_id, self.id, payload)
        r_data["guild_id"] = self._guild_id
        return self.from_dict(r_data, self._client)

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/role.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

async method fetch_bot(self)

Fetch the bot associated with this role if any.

Returns:

Type Description
Optional[Member]

Member object if any

Source code in naff/models/discord/role.py
async def fetch_bot(self) -> Optional["Member"]:
    """
    Fetch the bot associated with this role if any.

    Returns:
        Member object if any

    """
    if self._bot_id is None:
        return None
    return await self._client.cache.fetch_member(self._guild_id, self._bot_id)

method get_bot(self)

Get the bot associated with this role if any.

Returns:

Type Description
Optional[Member]

Member object if any

Source code in naff/models/discord/role.py
def get_bot(self) -> Optional["Member"]:
    """
    Get the bot associated with this role if any.

    Returns:
        Member object if any

    """
    if self._bot_id is None:
        return None
    return self._client.cache.get_member(self._guild_id, self._bot_id)

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/role.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

property readonly guild: Guild

The guild object this role is from.

property readonly default: bool

Is this the @everyone role.

property readonly bot_managed: bool

Is this role owned/managed by a bot.

property readonly mention: str

Returns a string that would mention the role.

property readonly integration: bool

Is this role owned/managed by an integration.

property readonly members: list

List of members with this role

property readonly icon: Union[naff.models.discord.asset.Asset, naff.models.discord.emoji.PartialEmoji]

The icon of this role

Note

You have to use this method instead of the _icon attribute, because the first does account for unicode emojis

property readonly is_assignable: bool

Can this role be assigned or removed by this bot?

Note

This does not account for permissions, only the role hierarchy

async method delete(self, reason)

Delete this role.

Parameters:

Name Type Description Default
reason str

An optional reason for this deletion

None
Source code in naff/models/discord/role.py
async def delete(self, reason: str = None) -> None:
    """
    Delete this role.

    Args:
        reason: An optional reason for this deletion

    """
    await self._client.http.delete_guild_role(self._guild_id, self.id, reason)

async method edit(self, name, permissions, color, hoist, mentionable)

Edit this role, all arguments are optional.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

name of the role

Missing
permissions Union[str, naff.client.const.Missing]

New permissions to use

Missing
color Union[int, naff.models.discord.color.Color, naff.client.const.Missing]

The color of the role

Missing
hoist Union[bool, naff.client.const.Missing]

whether the role should be displayed separately in the sidebar

Missing
mentionable Union[bool, naff.client.const.Missing]

whether the role should be mentionable

Missing

Returns:

Type Description
Role

Role with updated information

Source code in naff/models/discord/role.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    permissions: Absent[str] = MISSING,
    color: Absent[Union[int, Color]] = MISSING,
    hoist: Absent[bool] = MISSING,
    mentionable: Absent[bool] = MISSING,
) -> "Role":
    """
    Edit this role, all arguments are optional.

    Args:
        name: name of the role
        permissions: New permissions to use
        color: The color of the role
        hoist: whether the role should be displayed separately in the sidebar
        mentionable: whether the role should be mentionable

    Returns:
        Role with updated information

    """
    if isinstance(color, Color):
        color = color.value

    payload = dict_filter(
        {"name": name, "permissions": permissions, "color": color, "hoist": hoist, "mentionable": mentionable}
    )

    r_data = await self._client.http.modify_guild_role(self._guild_id, self.id, payload)
    r_data["guild_id"] = self._guild_id
    return self.from_dict(r_data, self._client)