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

Code before:
    def __str__(self) -> str:
        return str(self.name)

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

    def to_dict(self) -> Dict[str, Any]:
        timestamps: Dict[str, Any] = {}
        if self._start:
            timestamps['start'] = self._start

        if self._end:
            timestamps['end'] = self._end

        return {
            'type': ActivityType.playing.value,
            'name': str(self.name),
            'timestamps': timestamps,
            'platform': str(self.platform) if self.platform else None,
            'assets': self.assets,
        }

    def __eq__(self, other: object) -> bool:
        return (isinstance(other, Game)
                and other.name == self.name
                and other.platform == self.platform)

    def __ne__(self, other: object) -> bool:
        return not self.__eq__(other)

    def __hash__(self) -> int:
        return hash((self.name, self.platform))


class Streaming(BaseActivity):
    """A slimmed down version of :class:`Activity` that represents a Discord streaming status.

    This is typically displayed via **Streaming** on the official Discord client.

    .. container:: operations

        .. describe:: x == y

            Checks if two streams are equal.

        .. describe:: x != y

            Checks if two streams are not equal.

        .. describe:: hash(x)


Review comment (suggestion):
I don't think `platform` should be part of the `__eq__` or `__hash__` though I guess it's up to debate.

Code after:
        """Optional[:class:`datetime.datetime`]: When the user started playing this game in UTC, if applicable."""
        if self._start:
            return datetime.datetime.fromtimestamp(self._start / 1000, tz=datetime.timezone.utc)
        return None

    @property
    def end(self) -> Optional[datetime.datetime]:
        """Optional[:class:`datetime.datetime`]: When the user will stop playing this game in UTC, if applicable."""
        if self._end:
            return datetime.datetime.fromtimestamp(self._end / 1000, tz=datetime.timezone.utc)
        return None

    def __str__(self) -> str:
        return str(self.name)

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

    def to_dict(self) -> Dict[str, Any]:
        timestamps: Dict[str, Any] = {}
        if self._start:
            timestamps['start'] = self._start

        if self._end:
            timestamps['end'] = self._end

        return {
            'type': ActivityType.playing.value,
            'name': str(self.name),
            'timestamps': timestamps,
            'platform': str(self.platform) if self.platform else None,
            'assets': self.assets,
        }

    def __eq__(self, other: object) -> bool:
        return isinstance(other, Game) and other.name == self.name

    def __ne__(self, other: object) -> bool:
        return not self.__eq__(other)

    def __hash__(self) -> int:
        return hash(self.name)


class Streaming(BaseActivity):
    """A slimmed down version of :class:`Activity` that represents a Discord streaming status.

    This is typically displayed via **Streaming** on the official Discord client.

    .. container:: operations