Browse Source

Fix typing in Audit Logs

pull/7494/head
Josh 3 years ago
committed by GitHub
parent
commit
437d451d4e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 102
      discord/audit_logs.py

102
discord/audit_logs.py

@ -53,7 +53,11 @@ if TYPE_CHECKING:
AuditLogChange as AuditLogChangePayload, AuditLogChange as AuditLogChangePayload,
AuditLogEntry as AuditLogEntryPayload, AuditLogEntry as AuditLogEntryPayload,
) )
from .types.channel import PermissionOverwrite as PermissionOverwritePayload from .types.channel import (
PartialChannel as PartialChannelPayload,
PermissionOverwrite as PermissionOverwritePayload,
)
from .types.invite import Invite as InvitePayload
from .types.role import Role as RolePayload from .types.role import Role as RolePayload
from .types.snowflake import Snowflake from .types.snowflake import Snowflake
from .user import User from .user import User
@ -131,13 +135,13 @@ def _transform_icon(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset
if entry.action is enums.AuditLogAction.guild_update: if entry.action is enums.AuditLogAction.guild_update:
return Asset._from_guild_icon(entry._state, entry.guild.id, data) return Asset._from_guild_icon(entry._state, entry.guild.id, data)
else: else:
return Asset._from_icon(entry._state, entry._target_id, data, path='role') return Asset._from_icon(entry._state, entry._target_id, data, path='role') # type: ignore - target_id won't be None in this case
def _transform_avatar(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]: def _transform_avatar(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]:
if data is None: if data is None:
return None return None
return Asset._from_avatar(entry._state, entry._target_id, data) # type: ignore return Asset._from_avatar(entry._state, entry._target_id, data) # type: ignore - target_id won't be None in this case
def _guild_hash_transformer(path: str) -> Callable[[AuditLogEntry, Optional[str]], Optional[Asset]]: def _guild_hash_transformer(path: str) -> Callable[[AuditLogEntry, Optional[str]], Optional[Asset]]:
@ -237,10 +241,10 @@ class AuditLogChanges:
# special cases for role add/remove # special cases for role add/remove
if attr == '$add': if attr == '$add':
self._handle_role(self.before, self.after, entry, elem['new_value']) # type: ignore self._handle_role(self.before, self.after, entry, elem['new_value']) # type: ignore - new_value is a list of roles in this case
continue continue
elif attr == '$remove': elif attr == '$remove':
self._handle_role(self.after, self.before, entry, elem['new_value']) # type: ignore self._handle_role(self.after, self.before, entry, elem['new_value']) # type: ignore - new_value is a list of roles in this case
continue continue
try: try:
@ -289,7 +293,7 @@ class AuditLogChanges:
setattr(first, 'roles', []) setattr(first, 'roles', [])
data = [] data = []
g: Guild = entry.guild # type: ignore g: Guild = entry.guild
for e in elem: for e in elem:
role_id = int(e['id']) role_id = int(e['id'])
@ -297,33 +301,39 @@ class AuditLogChanges:
if role is None: if role is None:
role = Object(id=role_id) role = Object(id=role_id)
role.name = e['name'] # type: ignore role.name = e['name'] # type: ignore - Object doesn't usually have name
data.append(role) data.append(role)
setattr(second, 'roles', data) setattr(second, 'roles', data)
class _AuditLogProxyMemberPrune: class _AuditLogProxy:
def __init__(self, **kwargs: Any) -> None:
for k, v in kwargs.items():
setattr(self, k, v)
class _AuditLogProxyMemberPrune(_AuditLogProxy):
delete_member_days: int delete_member_days: int
members_removed: int members_removed: int
class _AuditLogProxyMemberMoveOrMessageDelete: class _AuditLogProxyMemberMoveOrMessageDelete(_AuditLogProxy):
channel: abc.GuildChannel channel: abc.GuildChannel
count: int count: int
class _AuditLogProxyMemberDisconnect: class _AuditLogProxyMemberDisconnect(_AuditLogProxy):
count: int count: int
class _AuditLogProxyPinAction: class _AuditLogProxyPinAction(_AuditLogProxy):
channel: abc.GuildChannel channel: abc.GuildChannel
message_id: int message_id: int
class _AuditLogProxyStageInstanceAction: class _AuditLogProxyStageInstanceAction(_AuditLogProxy):
channel: abc.GuildChannel channel: abc.GuildChannel
@ -382,51 +392,48 @@ class AuditLogEntry(Hashable):
# this key is technically not usually present # this key is technically not usually present
self.reason = data.get('reason') self.reason = data.get('reason')
self.extra = data.get('options') extra = data.get('options')
if isinstance(self.action, enums.AuditLogAction) and self.extra: if isinstance(self.action, enums.AuditLogAction) and extra:
if self.action is enums.AuditLogAction.member_prune: if self.action is enums.AuditLogAction.member_prune:
# member prune has two keys with useful information # member prune has two keys with useful information
self.extra: _AuditLogProxyMemberPrune = type( self.extra = _AuditLogProxyMemberPrune(
'_AuditLogProxy', (), {k: int(v) for k, v in self.extra.items()} delete_member_days=int(extra['delete_member_days']),
)() members_removed=int(extra['members_removed']),
)
elif self.action is enums.AuditLogAction.member_move or self.action is enums.AuditLogAction.message_delete: elif self.action is enums.AuditLogAction.member_move or self.action is enums.AuditLogAction.message_delete:
channel_id = int(self.extra['channel_id']) channel_id = int(extra['channel_id'])
elems = { self.extra = _AuditLogProxyMemberMoveOrMessageDelete(
'count': int(self.extra['count']), count=int(extra['count']),
'channel': self.guild.get_channel(channel_id) or Object(id=channel_id), channel=self.guild.get_channel(channel_id) or Object(id=channel_id),
} )
self.extra: _AuditLogProxyMemberMoveOrMessageDelete = type('_AuditLogProxy', (), elems)()
elif self.action is enums.AuditLogAction.member_disconnect: elif self.action is enums.AuditLogAction.member_disconnect:
# The member disconnect action has a dict with some information # The member disconnect action has a dict with some information
elems = { self.extra = _AuditLogProxyMemberDisconnect(count=int(extra['count']))
'count': int(self.extra['count']),
}
self.extra: _AuditLogProxyMemberDisconnect = type('_AuditLogProxy', (), elems)()
elif self.action.name.endswith('pin'): elif self.action.name.endswith('pin'):
# the pin actions have a dict with some information # the pin actions have a dict with some information
channel_id = int(self.extra['channel_id']) channel_id = int(extra['channel_id'])
elems = { self.extra = _AuditLogProxyPinAction(
'channel': self.guild.get_channel(channel_id) or Object(id=channel_id), channel=self.guild.get_channel(channel_id) or Object(id=channel_id),
'message_id': int(self.extra['message_id']), message_id=int(extra['message_id']),
} )
self.extra: _AuditLogProxyPinAction = type('_AuditLogProxy', (), elems)()
elif self.action.name.startswith('overwrite_'): elif self.action.name.startswith('overwrite_'):
# the overwrite_ actions have a dict with some information # the overwrite_ actions have a dict with some information
instance_id = int(self.extra['id']) instance_id = int(extra['id'])
the_type = self.extra.get('type') the_type = extra.get('type')
if the_type == '1': if the_type == '1':
self.extra = self._get_member(instance_id) self.extra = self._get_member(instance_id)
elif the_type == '0': elif the_type == '0':
role = self.guild.get_role(instance_id) role = self.guild.get_role(instance_id)
if role is None: if role is None:
role = Object(id=instance_id) role = Object(id=instance_id)
role.name = self.extra.get('role_name') # type: ignore role.name = self.extra.get('role_name') # type: ignore - Object doesn't usually have name
self.extra: Role = role self.extra = role
elif self.action.name.startswith('stage_instance'): elif self.action.name.startswith('stage_instance'):
channel_id = int(self.extra['channel_id']) channel_id = int(extra['channel_id'])
elems = {'channel': self.guild.get_channel(channel_id) or Object(id=channel_id)} self.extra = _AuditLogProxyStageInstanceAction(
self.extra: _AuditLogProxyStageInstanceAction = type('_AuditLogProxy', (), elems)() channel=self.guild.get_channel(channel_id) or Object(id=channel_id)
)
# fmt: off # fmt: off
self.extra: Union[ self.extra: Union[
@ -436,7 +443,7 @@ class AuditLogEntry(Hashable):
_AuditLogProxyPinAction, _AuditLogProxyPinAction,
_AuditLogProxyStageInstanceAction, _AuditLogProxyStageInstanceAction,
Member, User, None, Member, User, None,
Role, Role, Object
] ]
# fmt: on # fmt: on
@ -447,7 +454,8 @@ class AuditLogEntry(Hashable):
# into meaningful data when requested # into meaningful data when requested
self._changes = data.get('changes', []) self._changes = data.get('changes', [])
self.user = self._get_member(utils._get_as_snowflake(data, 'user_id')) # type: ignore user_id = utils._get_as_snowflake(data, 'user_id')
self.user = user_id and self._get_member(user_id)
self._target_id = utils._get_as_snowflake(data, 'target_id') self._target_id = utils._get_as_snowflake(data, 'target_id')
def _get_member(self, user_id: int) -> Union[Member, User, None]: def _get_member(self, user_id: int) -> Union[Member, User, None]:
@ -463,6 +471,9 @@ class AuditLogEntry(Hashable):
@utils.cached_property @utils.cached_property
def target(self) -> TargetType: def target(self) -> TargetType:
if self._target_id is None or self.action.target_type is None:
return None
try: try:
converter = getattr(self, '_convert_target_' + self.action.target_type) converter = getattr(self, '_convert_target_' + self.action.target_type)
except AttributeError: except AttributeError:
@ -471,7 +482,7 @@ class AuditLogEntry(Hashable):
return converter(self._target_id) return converter(self._target_id)
@utils.cached_property @utils.cached_property
def category(self) -> enums.AuditLogActionCategory: def category(self) -> Optional[enums.AuditLogActionCategory]:
"""Optional[:class:`AuditLogActionCategory`]: The category of the action, if applicable.""" """Optional[:class:`AuditLogActionCategory`]: The category of the action, if applicable."""
return self.action.category return self.action.category
@ -509,15 +520,16 @@ class AuditLogEntry(Hashable):
# so figure out which change has the full invite data # so figure out which change has the full invite data
changeset = self.before if self.action is enums.AuditLogAction.invite_delete else self.after changeset = self.before if self.action is enums.AuditLogAction.invite_delete else self.after
fake_payload = { fake_payload: InvitePayload = {
'max_age': changeset.max_age, 'max_age': changeset.max_age,
'max_uses': changeset.max_uses, 'max_uses': changeset.max_uses,
'code': changeset.code, 'code': changeset.code,
'temporary': changeset.temporary, 'temporary': changeset.temporary,
'uses': changeset.uses, 'uses': changeset.uses,
'channel': None, # type: ignore - the channel is passed to the Invite constructor directly
} }
obj = Invite(state=self._state, data=fake_payload, guild=self.guild, channel=changeset.channel) # type: ignore obj = Invite(state=self._state, data=fake_payload, guild=self.guild, channel=changeset.channel)
try: try:
obj.inviter = changeset.inviter obj.inviter = changeset.inviter
except AttributeError: except AttributeError:

Loading…
Cancel
Save