Browse Source

Use a specific tag type for member and user comparisons

The previous protocol based tag type caused significant overhead
(in the magnitude of seconds). Removing this should simplify object
creation by removing typing.Generic from the __mro__
pull/7192/head
Rapptz 4 years ago
parent
commit
af8742a911
  1. 8
      discord/member.py
  2. 12
      discord/user.py

8
discord/member.py

@ -35,7 +35,7 @@ import discord.abc
from . import utils from . import utils
from .utils import MISSING from .utils import MISSING
from .user import BaseUser, User from .user import BaseUser, User, _UserTag
from .activity import create_activity, ActivityTypes from .activity import create_activity, ActivityTypes
from .permissions import Permissions from .permissions import Permissions
from .enums import Status, try_enum from .enums import Status, try_enum
@ -194,13 +194,11 @@ def flatten_user(cls):
return cls return cls
_BaseUser = discord.abc.User
M = TypeVar('M', bound='Member') M = TypeVar('M', bound='Member')
@flatten_user @flatten_user
class Member(discord.abc.Messageable, _BaseUser): class Member(discord.abc.Messageable, _UserTag):
"""Represents a Discord member to a :class:`Guild`. """Represents a Discord member to a :class:`Guild`.
This implements a lot of the functionality of :class:`User`. This implements a lot of the functionality of :class:`User`.
@ -301,7 +299,7 @@ class Member(discord.abc.Messageable, _BaseUser):
) )
def __eq__(self, other: Any) -> bool: def __eq__(self, other: Any) -> bool:
return isinstance(other, _BaseUser) and other.id == self.id return isinstance(other, _UserTag) and other.id == self.id
def __ne__(self, other: Any) -> bool: def __ne__(self, other: Any) -> bool:
return not self.__eq__(other) return not self.__eq__(other)

12
discord/user.py

@ -35,10 +35,13 @@ __all__ = (
'ClientUser', 'ClientUser',
) )
_BaseUser = discord.abc.User
class _UserTag:
__slots__ = ()
id: int
class BaseUser(_BaseUser):
class BaseUser(_UserTag):
__slots__ = ('name', 'id', 'discriminator', '_avatar', 'bot', 'system', '_public_flags', '_state') __slots__ = ('name', 'id', 'discriminator', '_avatar', 'bot', 'system', '_public_flags', '_state')
if TYPE_CHECKING: if TYPE_CHECKING:
@ -62,7 +65,7 @@ class BaseUser(_BaseUser):
return f'{self.name}#{self.discriminator}' return f'{self.name}#{self.discriminator}'
def __eq__(self, other): def __eq__(self, other):
return isinstance(other, _BaseUser) and other.id == self.id return isinstance(other, _UserTag) and other.id == self.id
def __ne__(self, other): def __ne__(self, other):
return not self.__eq__(other) return not self.__eq__(other)
@ -118,6 +121,7 @@ class BaseUser(_BaseUser):
return Asset._from_default_avatar(self._state, int(self.discriminator) % len(DefaultAvatar)) return Asset._from_default_avatar(self._state, int(self.discriminator) % len(DefaultAvatar))
else: else:
return Asset._from_avatar(self._state, self.id, self._avatar) return Asset._from_avatar(self._state, self.id, self._avatar)
@property @property
def default_avatar(self): def default_avatar(self):
""":class:`Asset`: Returns the default avatar for a given user. This is calculated by the user's discriminator.""" """:class:`Asset`: Returns the default avatar for a given user. This is calculated by the user's discriminator."""
@ -247,7 +251,7 @@ class ClientUser(BaseUser):
self._flags = data.get('flags', 0) self._flags = data.get('flags', 0)
self.mfa_enabled = data.get('mfa_enabled', False) self.mfa_enabled = data.get('mfa_enabled', False)
async def edit(self, *, username: str = MISSING, avatar: bytes = MISSING) -> None: async def edit(self, *, username: str = MISSING, avatar: bytes = MISSING) -> None:
"""|coro| """|coro|
Edits the current profile of the client. Edits the current profile of the client.

Loading…
Cancel
Save