diff options
| author | Rapptz <[email protected]> | 2017-08-21 06:16:50 -0400 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2017-08-21 06:16:50 -0400 |
| commit | e5ebea75a985ef6dd02672e2406a847a3985cb86 (patch) | |
| tree | 42153499b58ae0a1b83b5686f59828fa79af0e77 /discord/emoji.py | |
| parent | Game objects are really dumb. (diff) | |
| download | discord.py-e5ebea75a985ef6dd02672e2406a847a3985cb86.tar.xz discord.py-e5ebea75a985ef6dd02672e2406a847a3985cb86.zip | |
Lazily fetch Emoji.roles and Emoji.guild to prevent memory leaks.
The global emoji cache still managed to somehow cause memory leaks. By
storing IDs directly and lazily evaluating them when needed this
essentially removes all strong references to Guild objects which would
cause an explosion in memory usage.
Diffstat (limited to 'discord/emoji.py')
| -rw-r--r-- | discord/emoji.py | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/discord/emoji.py b/discord/emoji.py index 05f02ecb..6faf8dbf 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -124,16 +124,13 @@ class Emoji(Hashable): If colons are required to use this emoji in the client (:PJSalt: vs PJSalt). managed: bool If this emoji is managed by a Twitch integration. - guild: :class:`Guild` - The guild the emoji belongs to. - roles: List[:class:`Role`] - A list of :class:`Role` that is allowed to use this emoji. If roles is empty, - the emoji is unrestricted. + guild_id: int + The guild ID the emoji belongs to. """ - __slots__ = ('require_colons', 'managed', 'id', 'name', 'roles', 'guild', '_state') + __slots__ = ('require_colons', 'managed', 'id', 'name', '_roles', 'guild_id', '_state') def __init__(self, *, guild, state, data): - self.guild = guild + self.guild_id = guild.id self._state = state self._from_data(data) @@ -142,10 +139,7 @@ class Emoji(Hashable): self.managed = emoji['managed'] self.id = int(emoji['id']) self.name = emoji['name'] - self.roles = emoji.get('roles', []) - if self.roles: - roles = set(self.roles) - self.roles = [role for role in self.guild.roles if role.id in roles] + self._roles = set(emoji.get('roles', [])) def _iterator(self): for attr in self.__slots__: @@ -173,6 +167,22 @@ class Emoji(Hashable): """Returns a URL version of the emoji.""" return "https://cdn.discordapp.com/emojis/{0.id}.png".format(self) + @property + def roles(self): + """List[:class:`Role`]: A list of roles that is allowed to use this emoji. + + If roles is empty, the emoji is unrestricted. + """ + guild = self.guild + if guild is None: + return [] + + return [role for role in guild.roles if role.id in self._roles] + + @property + def guild(self): + """:class:`Guild`: The guild this emoji belongs to.""" + return self._state._get_guild(self.guild_id) @asyncio.coroutine def delete(self, *, reason=None): |