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

Code before:
    def icon(self) -> Optional[Asset]:
        """Optional[:class:`Asset`]: The application's icon, if any."""
        if self._icon:
            return Asset._from_app_icon(state=self._state, object_id=self.id, icon_hash=self._icon, asset_type='icon')
        return None

    @property
    def cover(self) -> Optional[Asset]:
        """Optional[:class:`Asset`]: The application's cover image, if any."""
        if self._cover_image:
            return Asset._from_app_icon(
                state=self._state, object_id=self.id, icon_hash=self._cover_image, asset_type='cover_image'
            )
        return None


class MessageCall:
    """Represents a message's call data in a private channel from a :class:`~discord.Message`.

    .. versionadded:: 2.5

    Attributes
    -----------
    ended_timestamp: Optional[:class:`datetime.datetime`]
        The timestamp the call has ended.
    participants: List[Optional[:class:`User`]]
        A list of users that participated in the call.
    """

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

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

    def __init__(self, *, state: ConnectionState, message: Message, data: MessageCallPayload):
        self._message: Message = message
        self.ended_timestamp: Optional[datetime.datetime] = utils.parse_time(data.get('ended_timestamp'))
        self.participants: List[Optional[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:
                self.participants.append(state.get_user(user_id))

    @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

Review comment (suggestion):
`List[Optional[X]]` should never be done in the library, so properly filter these. [This is how it was done in the previous implementation](https://github.com/Rapptz/discord.py/blob/1863a1c6636f53592519320a173ec9573c090c0b/discord/message.py#L184-L194).

Code after:
        self._cover_image: Optional[str] = data.get('cover_image')

    def __repr__(self) -> str:
        return f'<MessageApplication id={self.id} name={self.name!r}>'

    @property
    def icon(self) -> Optional[Asset]:
        """Optional[:class:`Asset`]: The application's icon, if any."""
        if self._icon:
            return Asset._from_app_icon(state=self._state, object_id=self.id, icon_hash=self._icon, asset_type='icon')
        return None

    @property
    def cover(self) -> Optional[Asset]:
        """Optional[:class:`Asset`]: The application's cover image, if any."""
        if self._cover_image:
            return Asset._from_app_icon(
                state=self._state, object_id=self.id, icon_hash=self._cover_image, asset_type='cover_image'
            )
        return None


class CallMessage:
    """Represents a message's call data in a private channel from a :class:`~discord.Message`.

    .. versionadded:: 2.5

    Attributes
    -----------
    ended_timestamp: Optional[:class:`datetime.datetime`]
        The timestamp the call has ended.
    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)