From de1c74a399a5286cd707c6ebc3892e168d628ac0 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Wed, 16 Dec 2015 22:03:16 -0500 Subject: [PATCH] Make more things into properties. A lot of the expensive getters were transformed into cached properties instead. A lot of things that were properties were transformed into properties as well. --- discord/message.py | 20 +++++++++----------- discord/role.py | 1 + discord/server.py | 13 +++++++------ discord/state.py | 4 ++-- discord/utils.py | 15 +++++++++++++++ 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/discord/message.py b/discord/message.py index 8601e3cd9..496cd75e8 100644 --- a/discord/message.py +++ b/discord/message.py @@ -131,24 +131,25 @@ class Message(object): self.mentions.append(member) if self.server is not None: - channel_mentions = self.get_raw_channel_mentions() - for mention in channel_mentions: + for mention in self.raw_channel_mentions: channel = utils.find(lambda m: m.id == mention, self.server.channels) if channel is not None: self.channel_mentions.append(channel) - def get_raw_mentions(self): - """Returns an array of user IDs matched with the syntax of - <@user_id> in the message content. + @utils.cached_property + def raw_mentions(self): + """A property that returns an array of user IDs matched with + the syntax of <@user_id> in the message content. This allows you receive the user IDs of mentioned users even in a private message context. """ return re.findall(r'<@(\d+)>', self.content) - def get_raw_channel_mentions(self): - """Returns an array of channel IDs matched with the syntax of - <#channel_id> in the message content. + @utils.cached_property + def raw_channel_mentions(self): + """A property that returns an array of channel IDs matched with + the syntax of <#channel_id> in the message content. This allows you receive the channel IDs of mentioned users even in a private message context. @@ -168,6 +169,3 @@ class Message(object): found = utils.find(lambda m: m.id == self.author.id, self.server.members) if found is not None: self.author = found - - - diff --git a/discord/role.py b/discord/role.py index 93d8e3b50..eb44795a0 100644 --- a/discord/role.py +++ b/discord/role.py @@ -81,6 +81,7 @@ class Role(EqualityComparable): if 'everyone' in kwargs: self._is_everyone = kwargs['everyone'] + @property def is_everyone(self): """Checks if the role is the @everyone role.""" return self._is_everyone diff --git a/discord/server.py b/discord/server.py index bc0a7ba8f..e1093b008 100644 --- a/discord/server.py +++ b/discord/server.py @@ -108,12 +108,11 @@ class Server(EqualityComparable): self.unavailable = guild.get('unavailable', False) self.id = guild['id'] self.roles = [Role(everyone=(self.id == r['id']), **r) for r in guild['roles']] - default_role = self.get_default_role() owner_id = guild['owner_id'] for data in guild.get('members', []): - roles = [default_role] + roles = [self.default_role] for role_id in data['roles']: role = utils.find(lambda r: r.id == role_id, self.roles) if role is not None: @@ -149,13 +148,15 @@ class Server(EqualityComparable): for obj in guild.get('voice_states', []): self._update_voice_state(obj) - def get_default_role(self): + @utils.cached_property + def default_role(self): """Gets the @everyone role that all members have by default.""" - return utils.find(lambda r: r.is_everyone(), self.roles) + return utils.find(lambda r: r.is_everyone, self.roles) - def get_default_channel(self): + @utils.cached_property + def default_channel(self): """Gets the default :class:`Channel` for the server.""" - return utils.find(lambda c: c.is_default_channel(), self.channels) + return utils.find(lambda c: c.is_default, self.channels) @property def icon_url(self): diff --git a/discord/state.py b/discord/state.py index ac9c9454d..ce0878b99 100644 --- a/discord/state.py +++ b/discord/state.py @@ -169,7 +169,7 @@ class ConnectionState: def parse_guild_member_add(self, data): server = self._get_server(data.get('guild_id')) member = Member(server=server, deaf=False, mute=False, **data) - member.roles.append(server.get_default_role()) + member.roles.append(server.default_role) server.members.append(member) self.dispatch('member_join', member) @@ -195,7 +195,7 @@ class ConnectionState: member.name = user['username'] member.discriminator = user['discriminator'] member.avatar = user['avatar'] - member.roles = [server.get_default_role()] + member.roles = [server.default_role] # update the roles for role in server.roles: if role.id in data['roles']: diff --git a/discord/utils.py b/discord/utils.py index 2662b4a1f..9e2302621 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -31,6 +31,21 @@ from base64 import b64encode import asyncio import json + +class cached_property: + def __init__(self, function): + self.function = function + self.__doc__ = getattr(function, '__doc__') + + def __get__(self, instance, owner): + if instance is None: + return self + + value = self.function(instance) + setattr(instance, self.function.__name__, value) + + return value + def parse_time(timestamp): if timestamp: return datetime.datetime(*map(int, re_split(r'[^\d]', timestamp.replace('+00:00', ''))))