Repository: Rapptz/discord.py
File: discord/message.py (Python)

Code before:
    """

    __slots__ = (
        'role_subscription_listing_id',
        'tier_name',
        'total_months_subscribed',
        'is_renewal',
    )

    def __init__(self, data: RoleSubscriptionDataPayload) -> None:
        self.role_subscription_listing_id: int = int(data['role_subscription_listing_id'])
        self.tier_name: str = data['tier_name']
        self.total_months_subscribed: int = data['total_months_subscribed']
        self.is_renewal: bool = data['is_renewal']


class GuildProductPurchase(NamedTuple):
    """Represents a message's guild product that the user has purchased.

    .. versionadded:: 2.5
    """

    listing_id: int
    """The ID of the listing that the user has purchased."""
    product_name: str
    """The name of the product that the user has purchased."""


class PurchaseNotification:
    """Represents a message's purchase notification data.

    This is currently only attached to messages of type :attr:`MessageType.purchase_notification`.

    .. versionadded:: 2.5

    Attributes
    -----------
    guild_product_purchase: Optional[:class:`GuildProductPurchase`]
        The guild product purchase that prompted the message.
    """

    __slots__ = ('_type', 'guild_product_purchase')

    def __init__(self, data: PurchaseNotificationResponsePayload) -> None:
        self._type: int = data['type']

        self.guild_product_purchase: Optional[GuildProductPurchase] = None
        guild_product_purchase = data.get('guild_product_purchase')
        if guild_product_purchase is not None:
            self.guild_product_purchase = GuildProductPurchase(
                listing_id=int(guild_product_purchase['listing_id']),

Review comment (suggestion):
We don't use NamedTuple in the public API if we can help it. Please just turn this into a regular class.

Code after:
    participants: List[:class:`User`]
        A list of users that participated in the call.
    """

    __slots__ = ('_message', 'ended_timestamp', 'participants')

    def __repr__(self) -> str:
        return f'<CallMessage participants={self.participants!r}>'

    def __init__(self, *, state: ConnectionState, message: Message, data: CallMessagePayload):
        self._message: Message = message
        self.ended_timestamp: Optional[datetime.datetime] = utils.parse_time(data.get('ended_timestamp'))
        self.participants: List[User] = []

        for user_id in data['participants']:
            user_id = int(user_id)
            if user_id == self._message.author.id:
                self.participants.append(self._message.author)  # type: ignore # can't be a Member here
            else:
                user = state.get_user(user_id)
                if user is not None:
                    self.participants.append(user)

    @property
    def duration(self) -> datetime.timedelta:
        """:class:`datetime.timedelta`: The duration the call has lasted or is already ongoing."""
        if self.ended_timestamp is None:
            return utils.utcnow() - self._message.created_at
        else:
            return self.ended_timestamp - self._message.created_at

    def is_ended(self) -> bool:
        """:class:`bool`: Whether the call is ended or not."""
        return self.ended_timestamp is not None


class RoleSubscriptionInfo:
    """Represents a message's role subscription information.

    This is currently only attached to messages of type :attr:`MessageType.role_subscription_purchase`.

    .. versionadded:: 2.0

    Attributes
    -----------
    role_subscription_listing_id: :class:`int`
        The ID of the SKU and listing that the user is subscribed to.
    tier_name: :class:`str`
        The name of the tier that the user is subscribed to.
    total_months_subscribed: :class:`int`
        The cumulative number of months that the user has been subscribed for.