Modernize code to use f-strings

This also removes the encoding on the top, since Python 3 does it by
default. It also changes some methods to use `yield from`.
This commit is contained in:
Rapptz 2021-04-04 04:40:19 -04:00
parent 9fc2ab9c99
commit 9d39b135f4
67 changed files with 262 additions and 378 deletions

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
Discord API Wrapper Discord API Wrapper
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -42,9 +40,9 @@ def show_version():
if version_info.releaselevel != 'final': if version_info.releaselevel != 'final':
pkg = pkg_resources.get_distribution('discord.py') pkg = pkg_resources.get_distribution('discord.py')
if pkg: if pkg:
entries.append(' - discord.py pkg_resources: v{0}'.format(pkg.version)) entries.append(f' - discord.py pkg_resources: v{pkg.version}')
entries.append('- aiohttp v{0.__version__}'.format(aiohttp)) entries.append(f'- aiohttp v{aiohttp.__version__}')
uname = platform.uname() uname = platform.uname()
entries.append('- system info: {0.system} {0.release} {0.version}'.format(uname)) entries.append('- system info: {0.system} {0.release} {0.version}'.format(uname))
print('\n'.join(entries)) print('\n'.join(entries))
@ -200,7 +198,7 @@ def newbot(parser, args):
try: try:
new_directory.mkdir(exist_ok=True, parents=True) new_directory.mkdir(exist_ok=True, parents=True)
except OSError as exc: except OSError as exc:
parser.error('could not create our bot directory ({})'.format(exc)) parser.error(f'could not create our bot directory ({exc})')
cogs = new_directory / 'cogs' cogs = new_directory / 'cogs'
@ -209,27 +207,27 @@ def newbot(parser, args):
init = cogs / '__init__.py' init = cogs / '__init__.py'
init.touch() init.touch()
except OSError as exc: except OSError as exc:
print('warning: could not create cogs directory ({})'.format(exc)) print(f'warning: could not create cogs directory ({exc})')
try: try:
with open(str(new_directory / 'config.py'), 'w', encoding='utf-8') as fp: with open(str(new_directory / 'config.py'), 'w', encoding='utf-8') as fp:
fp.write('token = "place your token here"\ncogs = []\n') fp.write('token = "place your token here"\ncogs = []\n')
except OSError as exc: except OSError as exc:
parser.error('could not create config file ({})'.format(exc)) parser.error(f'could not create config file ({exc})')
try: try:
with open(str(new_directory / 'bot.py'), 'w', encoding='utf-8') as fp: with open(str(new_directory / 'bot.py'), 'w', encoding='utf-8') as fp:
base = 'Bot' if not args.sharded else 'AutoShardedBot' base = 'Bot' if not args.sharded else 'AutoShardedBot'
fp.write(bot_template.format(base=base, prefix=args.prefix)) fp.write(bot_template.format(base=base, prefix=args.prefix))
except OSError as exc: except OSError as exc:
parser.error('could not create bot file ({})'.format(exc)) parser.error(f'could not create bot file ({exc})')
if not args.no_git: if not args.no_git:
try: try:
with open(str(new_directory / '.gitignore'), 'w', encoding='utf-8') as fp: with open(str(new_directory / '.gitignore'), 'w', encoding='utf-8') as fp:
fp.write(gitignore_template) fp.write(gitignore_template)
except OSError as exc: except OSError as exc:
print('warning: could not create .gitignore file ({})'.format(exc)) print(f'warning: could not create .gitignore file ({exc})')
print('successfully made bot at', new_directory) print('successfully made bot at', new_directory)
@ -238,7 +236,7 @@ def newcog(parser, args):
try: try:
cog_dir.mkdir(exist_ok=True) cog_dir.mkdir(exist_ok=True)
except OSError as exc: except OSError as exc:
print('warning: could not create cogs directory ({})'.format(exc)) print(f'warning: could not create cogs directory ({exc})')
directory = cog_dir / to_path(parser, args.name) directory = cog_dir / to_path(parser, args.name)
directory = directory.with_suffix('.py') directory = directory.with_suffix('.py')
@ -257,12 +255,12 @@ def newcog(parser, args):
name = name.title() name = name.title()
if args.display_name: if args.display_name:
attrs += ', name="{}"'.format(args.display_name) attrs += f', name="{args.display_name}"'
if args.hide_commands: if args.hide_commands:
attrs += ', command_attrs=dict(hidden=True)' attrs += ', command_attrs=dict(hidden=True)'
fp.write(cog_template.format(name=name, extra=extra, attrs=attrs)) fp.write(cog_template.format(name=name, extra=extra, attrs=attrs))
except OSError as exc: except OSError as exc:
parser.error('could not create cog file ({})'.format(exc)) parser.error(f'could not create cog file ({exc})')
else: else:
print('successfully made cog at', directory) print('successfully made cog at', directory)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -196,16 +194,16 @@ class Activity(BaseActivity):
def __repr__(self): def __repr__(self):
attrs = ( attrs = (
'type', ('type', self.type),
'name', ('name', self.name),
'url', ('url', self.url),
'details', ('details', self.details),
'application_id', ('application_id', self.application_id),
'session_id', ('session_id', self.session_id),
'emoji', ('emoji', self.emoji),
) )
mapped = ' '.join('%s=%r' % (attr, getattr(self, attr)) for attr in attrs) inner = ' '.join('%s=%r' % t for t in attrs)
return '<Activity %s>' % mapped return f'<Activity {inner}>'
def to_dict(self): def to_dict(self):
ret = {} ret = {}
@ -250,7 +248,7 @@ class Activity(BaseActivity):
except KeyError: except KeyError:
return None return None
else: else:
return Asset.BASE + '/app-assets/{0}/{1}.png'.format(self.application_id, large_image) return Asset.BASE + f'/app-assets/{self.application_id}/{large_image}.png'
@property @property
def small_image_url(self): def small_image_url(self):
@ -263,7 +261,7 @@ class Activity(BaseActivity):
except KeyError: except KeyError:
return None return None
else: else:
return Asset.BASE + '/app-assets/{0}/{1}.png'.format(self.application_id, small_image) return Asset.BASE + f'/app-assets/{self.application_id}/{small_image}.png'
@property @property
def large_image_text(self): def large_image_text(self):
"""Optional[:class:`str`]: Returns the large image asset hover text of this activity if applicable.""" """Optional[:class:`str`]: Returns the large image asset hover text of this activity if applicable."""
@ -362,7 +360,7 @@ class Game(BaseActivity):
return str(self.name) return str(self.name)
def __repr__(self): def __repr__(self):
return '<Game name={0.name!r}>'.format(self) return f'<Game name={self.name!r}>'
def to_dict(self): def to_dict(self):
timestamps = {} timestamps = {}
@ -455,7 +453,7 @@ class Streaming(BaseActivity):
return str(self.name) return str(self.name)
def __repr__(self): def __repr__(self):
return '<Streaming name={0.name!r}>'.format(self) return f'<Streaming name={self.name!r}>'
@property @property
def twitch_name(self): def twitch_name(self):
@ -700,7 +698,7 @@ class CustomActivity(BaseActivity):
elif isinstance(emoji, PartialEmoji): elif isinstance(emoji, PartialEmoji):
self.emoji = emoji self.emoji = emoji
else: else:
raise TypeError('Expected str, PartialEmoji, or None, received {0!r} instead.'.format(type(emoji))) raise TypeError(f'Expected str, PartialEmoji, or None, received {type(emoji)!r} instead.')
@property @property
def type(self): def type(self):
@ -739,7 +737,7 @@ class CustomActivity(BaseActivity):
def __str__(self): def __str__(self):
if self.emoji: if self.emoji:
if self.name: if self.name:
return '%s %s' % (self.emoji, self.name) return f'{self.emoji} {self.name}'
return str(self.emoji) return str(self.emoji)
else: else:
return str(self.name) return str(self.name)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -74,11 +72,11 @@ class Asset:
if not utils.valid_icon_size(size): if not utils.valid_icon_size(size):
raise InvalidArgument("size must be a power of 2 between 16 and 4096") raise InvalidArgument("size must be a power of 2 between 16 and 4096")
if format is not None and format not in VALID_AVATAR_FORMATS: if format is not None and format not in VALID_AVATAR_FORMATS:
raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS)) raise InvalidArgument(f"format must be None or one of {VALID_AVATAR_FORMATS}")
if format == "gif" and not user.is_avatar_animated(): if format == "gif" and not user.is_avatar_animated():
raise InvalidArgument("non animated avatars do not support gif format") raise InvalidArgument("non animated avatars do not support gif format")
if static_format not in VALID_STATIC_FORMATS: if static_format not in VALID_STATIC_FORMATS:
raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS)) raise InvalidArgument(f"static_format must be one of {VALID_STATIC_FORMATS}")
if user.avatar is None: if user.avatar is None:
return user.default_avatar_url return user.default_avatar_url
@ -96,7 +94,7 @@ class Asset:
if not utils.valid_icon_size(size): if not utils.valid_icon_size(size):
raise InvalidArgument("size must be a power of 2 between 16 and 4096") raise InvalidArgument("size must be a power of 2 between 16 and 4096")
if format not in VALID_STATIC_FORMATS: if format not in VALID_STATIC_FORMATS:
raise InvalidArgument("format must be None or one of {}".format(VALID_STATIC_FORMATS)) raise InvalidArgument(f"format must be None or one of {VALID_STATIC_FORMATS}")
url = '/{0}-icons/{1.id}/{1.icon}.{2}?size={3}'.format(path, object, format, size) url = '/{0}-icons/{1.id}/{1.icon}.{2}?size={3}'.format(path, object, format, size)
return cls(state, url) return cls(state, url)
@ -109,7 +107,7 @@ class Asset:
if not utils.valid_icon_size(size): if not utils.valid_icon_size(size):
raise InvalidArgument("size must be a power of 2 between 16 and 4096") raise InvalidArgument("size must be a power of 2 between 16 and 4096")
if format not in VALID_STATIC_FORMATS: if format not in VALID_STATIC_FORMATS:
raise InvalidArgument("format must be None or one of {}".format(VALID_STATIC_FORMATS)) raise InvalidArgument(f"format must be None or one of {VALID_STATIC_FORMATS}")
url = '/app-assets/{0.id}/store/{0.cover_image}.{1}?size={2}'.format(obj, format, size) url = '/app-assets/{0.id}/store/{0.cover_image}.{1}?size={2}'.format(obj, format, size)
return cls(state, url) return cls(state, url)
@ -119,7 +117,7 @@ class Asset:
if not utils.valid_icon_size(size): if not utils.valid_icon_size(size):
raise InvalidArgument("size must be a power of 2 between 16 and 4096") raise InvalidArgument("size must be a power of 2 between 16 and 4096")
if format not in VALID_STATIC_FORMATS: if format not in VALID_STATIC_FORMATS:
raise InvalidArgument("format must be one of {}".format(VALID_STATIC_FORMATS)) raise InvalidArgument(f"format must be one of {VALID_STATIC_FORMATS}")
if hash is None: if hash is None:
return cls(state) return cls(state)
@ -132,11 +130,11 @@ class Asset:
if not utils.valid_icon_size(size): if not utils.valid_icon_size(size):
raise InvalidArgument("size must be a power of 2 between 16 and 4096") raise InvalidArgument("size must be a power of 2 between 16 and 4096")
if format is not None and format not in VALID_AVATAR_FORMATS: if format is not None and format not in VALID_AVATAR_FORMATS:
raise InvalidArgument("format must be one of {}".format(VALID_AVATAR_FORMATS)) raise InvalidArgument(f"format must be one of {VALID_AVATAR_FORMATS}")
if format == "gif" and not guild.is_icon_animated(): if format == "gif" and not guild.is_icon_animated():
raise InvalidArgument("non animated guild icons do not support gif format") raise InvalidArgument("non animated guild icons do not support gif format")
if static_format not in VALID_STATIC_FORMATS: if static_format not in VALID_STATIC_FORMATS:
raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS)) raise InvalidArgument(f"static_format must be one of {VALID_STATIC_FORMATS}")
if guild.icon is None: if guild.icon is None:
return cls(state) return cls(state)
@ -156,15 +154,15 @@ class Asset:
@classmethod @classmethod
def _from_emoji(cls, state, emoji, *, format=None, static_format='png'): def _from_emoji(cls, state, emoji, *, format=None, static_format='png'):
if format is not None and format not in VALID_AVATAR_FORMATS: if format is not None and format not in VALID_AVATAR_FORMATS:
raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS)) raise InvalidArgument(f"format must be None or one of {VALID_AVATAR_FORMATS}")
if format == "gif" and not emoji.animated: if format == "gif" and not emoji.animated:
raise InvalidArgument("non animated emoji's do not support gif format") raise InvalidArgument("non animated emoji's do not support gif format")
if static_format not in VALID_STATIC_FORMATS: if static_format not in VALID_STATIC_FORMATS:
raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS)) raise InvalidArgument(f"static_format must be one of {VALID_STATIC_FORMATS}")
if format is None: if format is None:
format = 'gif' if emoji.animated else static_format format = 'gif' if emoji.animated else static_format
return cls(state, '/emojis/{0.id}.{1}'.format(emoji, format)) return cls(state, f'/emojis/{emoji.id}.{format}')
def __str__(self): def __str__(self):
return self.BASE + self._url if self._url is not None else '' return self.BASE + self._url if self._url is not None else ''
@ -178,7 +176,7 @@ class Asset:
return self._url is not None return self._url is not None
def __repr__(self): def __repr__(self):
return '<Asset url={0._url!r}>'.format(self) return f'<Asset url={self._url!r}>'
def __eq__(self, other): def __eq__(self, other):
return isinstance(other, Asset) and self._url == other._url return isinstance(other, Asset) and self._url == other._url

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -94,7 +92,7 @@ class AuditLogDiff:
def __repr__(self): def __repr__(self):
values = ' '.join('%s=%r' % item for item in self.__dict__.items()) values = ' '.join('%s=%r' % item for item in self.__dict__.items())
return '<AuditLogDiff %s>' % values return f'<AuditLogDiff {values}>'
class AuditLogChanges: class AuditLogChanges:
TRANSFORMERS = { TRANSFORMERS = {
@ -166,7 +164,7 @@ class AuditLogChanges:
self.before.color = self.before.colour self.before.color = self.before.colour
def __repr__(self): def __repr__(self):
return '<AuditLogChanges before=%r after=%r>' % (self.before, self.after) return f'<AuditLogChanges before={self.before!r} after={self.after!r}>'
def _handle_role(self, first, second, entry, elem): def _handle_role(self, first, second, entry, elem):
if not hasattr(first, 'roles'): if not hasattr(first, 'roles'):

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -115,7 +113,8 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
('news', self.is_news()), ('news', self.is_news()),
('category_id', self.category_id) ('category_id', self.category_id)
] ]
return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) joined = ' '.join('%s=%r' % t for t in attrs)
return f'<{self.__class__.__name__} {joined}>'
def _update(self, guild, data): def _update(self, guild, data):
self.guild = guild self.guild = guild
@ -668,7 +667,8 @@ class VoiceChannel(VocalGuildChannel):
('user_limit', self.user_limit), ('user_limit', self.user_limit),
('category_id', self.category_id) ('category_id', self.category_id)
] ]
return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) joined = ' '.join('%s=%r' % t for t in attrs)
return f'<{self.__class__.__name__} {joined}>'
@property @property
def type(self): def type(self):
@ -791,7 +791,8 @@ class StageChannel(VocalGuildChannel):
('user_limit', self.user_limit), ('user_limit', self.user_limit),
('category_id', self.category_id) ('category_id', self.category_id)
] ]
return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) joined = ' '.join('%s=%r' % t for t in attrs)
return f'<{self.__class__.__name__} {joined}>'
def _update(self, guild, data): def _update(self, guild, data):
super()._update(guild, data) super()._update(guild, data)
@ -1219,7 +1220,7 @@ class DMChannel(discord.abc.Messageable, Hashable):
return self return self
def __str__(self): def __str__(self):
return 'Direct Message with %s' % self.recipient return f'Direct Message with {self.recipient}'
def __repr__(self): def __repr__(self):
return '<DMChannel id={0.id} recipient={0.recipient!r}>'.format(self) return '<DMChannel id={0.id} recipient={0.recipient!r}>'.format(self)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -403,7 +401,7 @@ class Client:
overridden to have a different implementation. overridden to have a different implementation.
Check :func:`~discord.on_error` for more details. Check :func:`~discord.on_error` for more details.
""" """
print('Ignoring exception in {}'.format(event_method), file=sys.stderr) print(f'Ignoring exception in {event_method}', file=sys.stderr)
traceback.print_exc() traceback.print_exc()
@utils.deprecated('Guild.chunk') @utils.deprecated('Guild.chunk')
@ -660,7 +658,7 @@ class Client:
reconnect = kwargs.pop('reconnect', True) reconnect = kwargs.pop('reconnect', True)
if kwargs: if kwargs:
raise TypeError("unexpected keyword argument(s) %s" % list(kwargs.keys())) raise TypeError(f"unexpected keyword argument(s) {list(kwargs.keys())}")
await self.login(*args, bot=bot) await self.login(*args, bot=bot)
await self.connect(reconnect=reconnect) await self.connect(reconnect=reconnect)
@ -760,7 +758,7 @@ class Client:
if value is None or isinstance(value, AllowedMentions): if value is None or isinstance(value, AllowedMentions):
self._connection.allowed_mentions = value self._connection.allowed_mentions = value
else: else:
raise TypeError('allowed_mentions must be AllowedMentions not {0.__class__!r}'.format(value)) raise TypeError(f'allowed_mentions must be AllowedMentions not {value.__class__!r}')
@property @property
def intents(self): def intents(self):
@ -859,8 +857,7 @@ class Client:
""" """
for guild in self.guilds: for guild in self.guilds:
for channel in guild.channels: yield from guild.channels
yield channel
def get_all_members(self): def get_all_members(self):
"""Returns a generator with every :class:`.Member` the client can see. """Returns a generator with every :class:`.Member` the client can see.
@ -877,8 +874,7 @@ class Client:
A member the client can see. A member the client can see.
""" """
for guild in self.guilds: for guild in self.guilds:
for member in guild.members: yield from guild.members
yield member
# listeners/waiters # listeners/waiters

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -61,7 +59,7 @@ class Colour:
def __init__(self, value): def __init__(self, value):
if not isinstance(value, int): if not isinstance(value, int):
raise TypeError('Expected int parameter, received %s instead.' % value.__class__.__name__) raise TypeError(f'Expected int parameter, received {value.__class__.__name__} instead.')
self.value = value self.value = value
@ -75,10 +73,10 @@ class Colour:
return not self.__eq__(other) return not self.__eq__(other)
def __str__(self): def __str__(self):
return '#{:0>6x}'.format(self.value) return f'#{self.value:0>6x}'
def __repr__(self): def __repr__(self):
return '<Colour value=%s>' % self.value return f'<Colour value={self.value}>'
def __hash__(self): def __hash__(self):
return hash(self.value) return hash(self.value)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -49,7 +47,8 @@ class EmbedProxy:
return len(self.__dict__) return len(self.__dict__)
def __repr__(self): def __repr__(self):
return 'EmbedProxy(%s)' % ', '.join(('%s=%r' % (k, v) for k, v in self.__dict__.items() if not k.startswith('_'))) inner = ', '.join((f'{k}={v!r}' for k, v in self.__dict__.items() if not k.startswith('_')))
return f'EmbedProxy({inner})'
def __getattr__(self, attr): def __getattr__(self, attr):
return EmptyEmbed return EmptyEmbed
@ -225,7 +224,7 @@ class Embed:
elif isinstance(value, int): elif isinstance(value, int):
self._colour = Colour(value=value) self._colour = Colour(value=value)
else: else:
raise TypeError('Expected discord.Colour, int, or Embed.Empty but received %s instead.' % value.__class__.__name__) raise TypeError(f'Expected discord.Colour, int, or Embed.Empty but received {value.__class__.__name__} instead.')
color = colour color = colour
@ -238,7 +237,7 @@ class Embed:
if isinstance(value, (datetime.datetime, _EmptyEmbed)): if isinstance(value, (datetime.datetime, _EmptyEmbed)):
self._timestamp = value self._timestamp = value
else: else:
raise TypeError("Expected datetime.datetime or Embed.Empty received %s instead" % value.__class__.__name__) raise TypeError(f"Expected datetime.datetime or Embed.Empty received {value.__class__.__name__} instead")
@property @property
def footer(self): def footer(self):

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -57,8 +55,8 @@ __all__ = (
def _create_value_cls(name): def _create_value_cls(name):
cls = namedtuple('_EnumValue_' + name, 'name value') cls = namedtuple('_EnumValue_' + name, 'name value')
cls.__repr__ = lambda self: '<%s.%s: %r>' % (name, self.name, self.value) cls.__repr__ = lambda self: f'<{name}.{self.name}: {self.value!r}>'
cls.__str__ = lambda self: '%s.%s' % (name, self.name) cls.__str__ = lambda self: f'{name}.{self.name}'
return cls return cls
def _is_descriptor(obj): def _is_descriptor(obj):
@ -112,7 +110,7 @@ class EnumMeta(type):
return len(cls._enum_member_names_) return len(cls._enum_member_names_)
def __repr__(cls): def __repr__(cls):
return '<enum %r>' % cls.__name__ return f'<enum {cls.__name__}>'
@property @property
def __members__(cls): def __members__(cls):
@ -122,7 +120,7 @@ class EnumMeta(type):
try: try:
return cls._enum_value_map_[value] return cls._enum_value_map_[value]
except (KeyError, TypeError): except (KeyError, TypeError):
raise ValueError("%r is not a valid %s" % (value, cls.__name__)) raise ValueError(f"{value!r} is not a valid {cls.__name__}")
def __getitem__(cls, key): def __getitem__(cls, key):
return cls._enum_member_map_[key] return cls._enum_member_map_[key]

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -48,7 +46,7 @@ class GatewayNotFound(DiscordException):
for the :class:`Client` websocket is not found.""" for the :class:`Client` websocket is not found."""
def __init__(self): def __init__(self):
message = 'The gateway to connect to discord was not found.' message = 'The gateway to connect to discord was not found.'
super(GatewayNotFound, self).__init__(message) super().__init__(message)
def flatten_error_dict(d, key=''): def flatten_error_dict(d, key=''):
items = [] items = []
@ -174,7 +172,7 @@ class ConnectionClosed(ClientException):
# aiohttp doesn't seem to consistently provide close reason # aiohttp doesn't seem to consistently provide close reason
self.reason = '' self.reason = ''
self.shard_id = shard_id self.shard_id = shard_id
super().__init__('Shard ID %s WebSocket closed with %s' % (self.shard_id, self.code)) super().__init__(f'Shard ID {self.shard_id} WebSocket closed with {self.code}')
class PrivilegedIntentsRequired(ClientException): class PrivilegedIntentsRequired(ClientException):
"""Exception that's thrown when the gateway is requesting privileged intents """Exception that's thrown when the gateway is requesting privileged intents

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
discord.ext.commands discord.ext.commands
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -46,7 +44,7 @@ def when_mentioned(bot, msg):
These are meant to be passed into the :attr:`.Bot.command_prefix` attribute. These are meant to be passed into the :attr:`.Bot.command_prefix` attribute.
""" """
return [bot.user.mention + ' ', '<@!%s> ' % bot.user.id] return [f'<@{bot.user.id}> ', f'<@!{bot.user.id}> ']
def when_mentioned_or(*prefixes): def when_mentioned_or(*prefixes):
"""A callable that implements when mentioned or other prefixes provided. """A callable that implements when mentioned or other prefixes provided.
@ -114,7 +112,7 @@ class BotBase(GroupMixin):
raise TypeError('Both owner_id and owner_ids are set.') raise TypeError('Both owner_id and owner_ids are set.')
if self.owner_ids and not isinstance(self.owner_ids, collections.abc.Collection): if self.owner_ids and not isinstance(self.owner_ids, collections.abc.Collection):
raise TypeError('owner_ids must be a collection not {0.__class__!r}'.format(self.owner_ids)) raise TypeError(f'owner_ids must be a collection not {self.owner_ids.__class__!r}')
if options.pop('self_bot', False): if options.pop('self_bot', False):
self._skip_check = lambda x, y: x != y self._skip_check = lambda x, y: x != y
@ -169,7 +167,7 @@ class BotBase(GroupMixin):
if cog and Cog._get_overridden_method(cog.cog_command_error) is not None: if cog and Cog._get_overridden_method(cog.cog_command_error) is not None:
return return
print('Ignoring exception in command {}:'.format(context.command), file=sys.stderr) print(f'Ignoring exception in command {context.command}:', file=sys.stderr)
traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr) traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr)
# global check registration # global check registration
@ -944,7 +942,7 @@ class BotBase(GroupMixin):
else: else:
self.dispatch('command_completion', ctx) self.dispatch('command_completion', ctx)
elif ctx.invoked_with: elif ctx.invoked_with:
exc = errors.CommandNotFound('Command "{}" is not found'.format(ctx.invoked_with)) exc = errors.CommandNotFound(f'Command "{ctx.invoked_with}" is not found')
self.dispatch('command_error', ctx, exc) self.dispatch('command_error', ctx, exc)
async def process_commands(self, message): async def process_commands(self, message):

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -120,7 +118,7 @@ class CogMeta(type):
value = value.__func__ value = value.__func__
if isinstance(value, _BaseCommand): if isinstance(value, _BaseCommand):
if is_static_method: if is_static_method:
raise TypeError('Command in method {0}.{1!r} must not be staticmethod.'.format(base, elem)) raise TypeError(f'Command in method {base}.{elem!r} must not be staticmethod.')
if elem.startswith(('cog_', 'bot_')): if elem.startswith(('cog_', 'bot_')):
raise TypeError(no_bot_cog.format(base, elem)) raise TypeError(no_bot_cog.format(base, elem))
commands[elem] = value commands[elem] = value
@ -275,7 +273,7 @@ class Cog(metaclass=CogMeta):
""" """
if name is not None and not isinstance(name, str): if name is not None and not isinstance(name, str):
raise TypeError('Cog.listener expected str but received {0.__class__.__name__!r} instead.'.format(name)) raise TypeError(f'Cog.listener expected str but received {name.__class__.__name__!r} instead.')
def decorator(func): def decorator(func):
actual = func actual = func

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -777,7 +775,7 @@ class clean_content(Converter):
if self.fix_channel_mentions and ctx.guild: if self.fix_channel_mentions and ctx.guild:
def resolve_channel(id, *, _get=ctx.guild.get_channel): def resolve_channel(id, *, _get=ctx.guild.get_channel):
ch = _get(id) ch = _get(id)
return ('<#%s>' % id), ('#' + ch.name if ch else '#deleted-channel') return (f'<#{id}>'), ('#' + ch.name if ch else '#deleted-channel')
transformations.update(resolve_channel(channel) for channel in message.raw_channel_mentions) transformations.update(resolve_channel(channel) for channel in message.raw_channel_mentions)
@ -792,12 +790,12 @@ class clean_content(Converter):
transformations.update( transformations.update(
('<@%s>' % member_id, resolve_member(member_id)) (f'<@{member_id}>', resolve_member(member_id))
for member_id in message.raw_mentions for member_id in message.raw_mentions
) )
transformations.update( transformations.update(
('<@!%s>' % member_id, resolve_member(member_id)) (f'<@!{member_id}>', resolve_member(member_id))
for member_id in message.raw_mentions for member_id in message.raw_mentions
) )
@ -807,7 +805,7 @@ class clean_content(Converter):
return '@' + r.name if r else '@deleted-role' return '@' + r.name if r else '@deleted-role'
transformations.update( transformations.update(
('<@&%s>' % role_id, resolve_role(role_id)) (f'<@&{role_id}>', resolve_role(role_id))
for role_id in message.raw_role_mentions for role_id in message.raw_role_mentions
) )
@ -842,10 +840,10 @@ class _Greedy:
raise TypeError('Greedy[...] expects a type or a Converter instance.') raise TypeError('Greedy[...] expects a type or a Converter instance.')
if converter is str or converter is type(None) or converter is _Greedy: if converter is str or converter is type(None) or converter is _Greedy:
raise TypeError('Greedy[%s] is invalid.' % converter.__name__) raise TypeError(f'Greedy[{converter.__name__}] is invalid.')
if getattr(converter, '__origin__', None) is typing.Union and type(None) in converter.__args__: if getattr(converter, '__origin__', None) is typing.Union and type(None) in converter.__args__:
raise TypeError('Greedy[%r] is invalid.' % converter) raise TypeError(f'Greedy[{converter!r}] is invalid.')
return self.__class__(converter=converter) return self.__class__(converter=converter)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -255,7 +253,7 @@ class MaxConcurrency:
raise ValueError('max_concurrency \'number\' cannot be less than 1') raise ValueError('max_concurrency \'number\' cannot be less than 1')
if not isinstance(per, BucketType): if not isinstance(per, BucketType):
raise TypeError('max_concurrency \'per\' must be of type BucketType not %r' % type(per)) raise TypeError(f'max_concurrency \'per\' must be of type BucketType not {type(per)!r}')
def copy(self): def copy(self):
return self.__class__(self.number, per=self.per, wait=self.wait) return self.__class__(self.number, per=self.per, wait=self.wait)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -473,7 +471,7 @@ class Command(_BaseCommand):
except AttributeError: except AttributeError:
name = converter.__class__.__name__ name = converter.__class__.__name__
raise BadArgument('Converting to "{}" failed for parameter "{}".'.format(name, param.name)) from exc raise BadArgument(f'Converting to "{name}" failed for parameter "{param.name}".') from exc
async def do_conversion(self, ctx, converter, argument, param): async def do_conversion(self, ctx, converter, argument, param):
try: try:
@ -775,7 +773,7 @@ class Command(_BaseCommand):
ctx.command = self ctx.command = self
if not await self.can_run(ctx): if not await self.can_run(ctx):
raise CheckFailure('The check functions for command {0.qualified_name} failed.'.format(self)) raise CheckFailure(f'The check functions for command {self.qualified_name} failed.')
if self._max_concurrency is not None: if self._max_concurrency is not None:
await self._max_concurrency.acquire(ctx) await self._max_concurrency.acquire(ctx)
@ -1014,23 +1012,23 @@ class Command(_BaseCommand):
# do [name] since [name=None] or [name=] are not exactly useful for the user. # do [name] since [name=None] or [name=] are not exactly useful for the user.
should_print = param.default if isinstance(param.default, str) else param.default is not None should_print = param.default if isinstance(param.default, str) else param.default is not None
if should_print: if should_print:
result.append('[%s=%s]' % (name, param.default) if not greedy else result.append(f'[{name}={param.default}]' if not greedy else
'[%s=%s]...' % (name, param.default)) f'[{name}={param.default}]...')
continue continue
else: else:
result.append('[%s]' % name) result.append(f'[{name}]')
elif param.kind == param.VAR_POSITIONAL: elif param.kind == param.VAR_POSITIONAL:
if self.require_var_positional: if self.require_var_positional:
result.append('<%s...>' % name) result.append(f'<{name}...>')
else: else:
result.append('[%s...]' % name) result.append(f'[{name}...]')
elif greedy: elif greedy:
result.append('[%s]...' % name) result.append(f'[{name}]...')
elif self._is_typing_optional(param.annotation): elif self._is_typing_optional(param.annotation):
result.append('[%s]' % name) result.append(f'[{name}]')
else: else:
result.append('<%s>' % name) result.append(f'<{name}>')
return ' '.join(result) return ' '.join(result)
@ -1062,14 +1060,14 @@ class Command(_BaseCommand):
""" """
if not self.enabled: if not self.enabled:
raise DisabledCommand('{0.name} command is disabled'.format(self)) raise DisabledCommand(f'{self.name} command is disabled')
original = ctx.command original = ctx.command
ctx.command = self ctx.command = self
try: try:
if not await ctx.bot.can_run(ctx): if not await ctx.bot.can_run(ctx):
raise CheckFailure('The global check functions for command {0.qualified_name} failed.'.format(self)) raise CheckFailure(f'The global check functions for command {self.qualified_name} failed.')
cog = self.cog cog = self.cog
if cog is not None: if cog is not None:
@ -1588,7 +1586,7 @@ def check_any(*checks):
try: try:
pred = wrapped.predicate pred = wrapped.predicate
except AttributeError: except AttributeError:
raise TypeError('%r must be wrapped by commands.check decorator' % wrapped) from None raise TypeError(f'{wrapped!r} must be wrapped by commands.check decorator') from None
else: else:
unwrapped.append(pred) unwrapped.append(pred)
@ -1776,7 +1774,7 @@ def has_permissions(**perms):
invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) invalid = set(perms) - set(discord.Permissions.VALID_FLAGS)
if invalid: if invalid:
raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) raise TypeError(f"Invalid permission(s): {', '.join(invalid)}")
def predicate(ctx): def predicate(ctx):
ch = ctx.channel ch = ctx.channel
@ -1801,7 +1799,7 @@ def bot_has_permissions(**perms):
invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) invalid = set(perms) - set(discord.Permissions.VALID_FLAGS)
if invalid: if invalid:
raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) raise TypeError(f"Invalid permission(s): {', '.join(invalid)}")
def predicate(ctx): def predicate(ctx):
guild = ctx.guild guild = ctx.guild
@ -1829,7 +1827,7 @@ def has_guild_permissions(**perms):
invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) invalid = set(perms) - set(discord.Permissions.VALID_FLAGS)
if invalid: if invalid:
raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) raise TypeError(f"Invalid permission(s): {', '.join(invalid)}")
def predicate(ctx): def predicate(ctx):
if not ctx.guild: if not ctx.guild:
@ -1854,7 +1852,7 @@ def bot_has_guild_permissions(**perms):
invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) invalid = set(perms) - set(discord.Permissions.VALID_FLAGS)
if invalid: if invalid:
raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) raise TypeError(f"Invalid permission(s): {', '.join(invalid)}")
def predicate(ctx): def predicate(ctx):
if not ctx.guild: if not ctx.guild:

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -143,7 +141,7 @@ class MissingRequiredArgument(UserInputError):
""" """
def __init__(self, param): def __init__(self, param):
self.param = param self.param = param
super().__init__('{0.name} is a required argument that is missing.'.format(param)) super().__init__(f'{param.name} is a required argument that is missing.')
class TooManyArguments(UserInputError): class TooManyArguments(UserInputError):
"""Exception raised when the command was passed too many arguments and its """Exception raised when the command was passed too many arguments and its
@ -229,7 +227,7 @@ class MemberNotFound(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('Member "{}" not found.'.format(argument)) super().__init__(f'Member "{argument}" not found.')
class GuildNotFound(BadArgument): class GuildNotFound(BadArgument):
"""Exception raised when the guild provided was not found in the bot's cache. """Exception raised when the guild provided was not found in the bot's cache.
@ -245,7 +243,7 @@ class GuildNotFound(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('Guild "{}" not found.'.format(argument)) super().__init__(f'Guild "{argument}" not found.')
class UserNotFound(BadArgument): class UserNotFound(BadArgument):
"""Exception raised when the user provided was not found in the bot's """Exception raised when the user provided was not found in the bot's
@ -262,7 +260,7 @@ class UserNotFound(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('User "{}" not found.'.format(argument)) super().__init__(f'User "{argument}" not found.')
class MessageNotFound(BadArgument): class MessageNotFound(BadArgument):
"""Exception raised when the message provided was not found in the channel. """Exception raised when the message provided was not found in the channel.
@ -278,7 +276,7 @@ class MessageNotFound(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('Message "{}" not found.'.format(argument)) super().__init__(f'Message "{argument}" not found.')
class ChannelNotReadable(BadArgument): class ChannelNotReadable(BadArgument):
"""Exception raised when the bot does not have permission to read messages """Exception raised when the bot does not have permission to read messages
@ -295,7 +293,7 @@ class ChannelNotReadable(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__("Can't read messages in {}.".format(argument.mention)) super().__init__(f"Can't read messages in {argument.mention}.")
class ChannelNotFound(BadArgument): class ChannelNotFound(BadArgument):
"""Exception raised when the bot can not find the channel. """Exception raised when the bot can not find the channel.
@ -311,7 +309,7 @@ class ChannelNotFound(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('Channel "{}" not found.'.format(argument)) super().__init__(f'Channel "{argument}" not found.')
class BadColourArgument(BadArgument): class BadColourArgument(BadArgument):
"""Exception raised when the colour is not valid. """Exception raised when the colour is not valid.
@ -327,7 +325,7 @@ class BadColourArgument(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('Colour "{}" is invalid.'.format(argument)) super().__init__(f'Colour "{argument}" is invalid.')
BadColorArgument = BadColourArgument BadColorArgument = BadColourArgument
@ -345,7 +343,7 @@ class RoleNotFound(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('Role "{}" not found.'.format(argument)) super().__init__(f'Role "{argument}" not found.')
class BadInviteArgument(BadArgument): class BadInviteArgument(BadArgument):
"""Exception raised when the invite is invalid or expired. """Exception raised when the invite is invalid or expired.
@ -371,7 +369,7 @@ class EmojiNotFound(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('Emoji "{}" not found.'.format(argument)) super().__init__(f'Emoji "{argument}" not found.')
class PartialEmojiConversionFailure(BadArgument): class PartialEmojiConversionFailure(BadArgument):
"""Exception raised when the emoji provided does not match the correct """Exception raised when the emoji provided does not match the correct
@ -388,7 +386,7 @@ class PartialEmojiConversionFailure(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('Couldn\'t convert "{}" to PartialEmoji.'.format(argument)) super().__init__(f'Couldn\'t convert "{argument}" to PartialEmoji.')
class BadBoolArgument(BadArgument): class BadBoolArgument(BadArgument):
"""Exception raised when a boolean argument was not convertable. """Exception raised when a boolean argument was not convertable.
@ -404,7 +402,7 @@ class BadBoolArgument(BadArgument):
""" """
def __init__(self, argument): def __init__(self, argument):
self.argument = argument self.argument = argument
super().__init__('{} is not a recognised boolean option'.format(argument)) super().__init__(f'{argument} is not a recognised boolean option')
class DisabledCommand(CommandError): class DisabledCommand(CommandError):
"""Exception raised when the command being invoked is disabled. """Exception raised when the command being invoked is disabled.
@ -444,7 +442,7 @@ class CommandOnCooldown(CommandError):
def __init__(self, cooldown, retry_after): def __init__(self, cooldown, retry_after):
self.cooldown = cooldown self.cooldown = cooldown
self.retry_after = retry_after self.retry_after = retry_after
super().__init__('You are on cooldown. Try again in {:.2f}s'.format(retry_after)) super().__init__(f'You are on cooldown. Try again in {retry_after:.2f}s')
class MaxConcurrencyReached(CommandError): class MaxConcurrencyReached(CommandError):
"""Exception raised when the command being invoked has reached its maximum concurrency. """Exception raised when the command being invoked has reached its maximum concurrency.
@ -466,7 +464,7 @@ class MaxConcurrencyReached(CommandError):
suffix = 'per %s' % name if per.name != 'default' else 'globally' suffix = 'per %s' % name if per.name != 'default' else 'globally'
plural = '%s times %s' if number > 1 else '%s time %s' plural = '%s times %s' if number > 1 else '%s time %s'
fmt = plural % (number, suffix) fmt = plural % (number, suffix)
super().__init__('Too many people using this command. It can only be used {} concurrently.'.format(fmt)) super().__init__(f'Too many people using this command. It can only be used {fmt} concurrently.')
class MissingRole(CheckFailure): class MissingRole(CheckFailure):
"""Exception raised when the command invoker lacks a role to run a command. """Exception raised when the command invoker lacks a role to run a command.
@ -483,7 +481,7 @@ class MissingRole(CheckFailure):
""" """
def __init__(self, missing_role): def __init__(self, missing_role):
self.missing_role = missing_role self.missing_role = missing_role
message = 'Role {0!r} is required to run this command.'.format(missing_role) message = f'Role {missing_role!r} is required to run this command.'
super().__init__(message) super().__init__(message)
class BotMissingRole(CheckFailure): class BotMissingRole(CheckFailure):
@ -501,7 +499,7 @@ class BotMissingRole(CheckFailure):
""" """
def __init__(self, missing_role): def __init__(self, missing_role):
self.missing_role = missing_role self.missing_role = missing_role
message = 'Bot requires the role {0!r} to run this command'.format(missing_role) message = f'Bot requires the role {missing_role!r} to run this command'
super().__init__(message) super().__init__(message)
class MissingAnyRole(CheckFailure): class MissingAnyRole(CheckFailure):
@ -521,14 +519,14 @@ class MissingAnyRole(CheckFailure):
def __init__(self, missing_roles): def __init__(self, missing_roles):
self.missing_roles = missing_roles self.missing_roles = missing_roles
missing = ["'{}'".format(role) for role in missing_roles] missing = [f"'{role}'" for role in missing_roles]
if len(missing) > 2: if len(missing) > 2:
fmt = '{}, or {}'.format(", ".join(missing[:-1]), missing[-1]) fmt = '{}, or {}'.format(", ".join(missing[:-1]), missing[-1])
else: else:
fmt = ' or '.join(missing) fmt = ' or '.join(missing)
message = "You are missing at least one of the required roles: {}".format(fmt) message = f"You are missing at least one of the required roles: {fmt}"
super().__init__(message) super().__init__(message)
@ -550,14 +548,14 @@ class BotMissingAnyRole(CheckFailure):
def __init__(self, missing_roles): def __init__(self, missing_roles):
self.missing_roles = missing_roles self.missing_roles = missing_roles
missing = ["'{}'".format(role) for role in missing_roles] missing = [f"'{role}'" for role in missing_roles]
if len(missing) > 2: if len(missing) > 2:
fmt = '{}, or {}'.format(", ".join(missing[:-1]), missing[-1]) fmt = '{}, or {}'.format(", ".join(missing[:-1]), missing[-1])
else: else:
fmt = ' or '.join(missing) fmt = ' or '.join(missing)
message = "Bot is missing at least one of the required roles: {}".format(fmt) message = f"Bot is missing at least one of the required roles: {fmt}"
super().__init__(message) super().__init__(message)
class NSFWChannelRequired(CheckFailure): class NSFWChannelRequired(CheckFailure):
@ -574,7 +572,7 @@ class NSFWChannelRequired(CheckFailure):
""" """
def __init__(self, channel): def __init__(self, channel):
self.channel = channel self.channel = channel
super().__init__("Channel '{}' needs to be NSFW for this command to work.".format(channel)) super().__init__(f"Channel '{channel}' needs to be NSFW for this command to work.")
class MissingPermissions(CheckFailure): class MissingPermissions(CheckFailure):
"""Exception raised when the command invoker lacks permissions to run a """Exception raised when the command invoker lacks permissions to run a
@ -596,7 +594,7 @@ class MissingPermissions(CheckFailure):
fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1]) fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1])
else: else:
fmt = ' and '.join(missing) fmt = ' and '.join(missing)
message = 'You are missing {} permission(s) to run this command.'.format(fmt) message = f'You are missing {fmt} permission(s) to run this command.'
super().__init__(message, *args) super().__init__(message, *args)
class BotMissingPermissions(CheckFailure): class BotMissingPermissions(CheckFailure):
@ -619,7 +617,7 @@ class BotMissingPermissions(CheckFailure):
fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1]) fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1])
else: else:
fmt = ' and '.join(missing) fmt = ' and '.join(missing)
message = 'Bot requires {} permission(s) to run this command.'.format(fmt) message = f'Bot requires {fmt} permission(s) to run this command.'
super().__init__(message, *args) super().__init__(message, *args)
class BadUnionArgument(UserInputError): class BadUnionArgument(UserInputError):
@ -654,7 +652,7 @@ class BadUnionArgument(UserInputError):
else: else:
fmt = ' or '.join(to_string) fmt = ' or '.join(to_string)
super().__init__('Could not convert "{0.name}" into {1}.'.format(param, fmt)) super().__init__(f'Could not convert "{param.name}" into {fmt}.')
class ArgumentParsingError(UserInputError): class ArgumentParsingError(UserInputError):
"""An exception raised when the parser fails to parse a user's input. """An exception raised when the parser fails to parse a user's input.
@ -678,7 +676,7 @@ class UnexpectedQuoteError(ArgumentParsingError):
""" """
def __init__(self, quote): def __init__(self, quote):
self.quote = quote self.quote = quote
super().__init__('Unexpected quote mark, {0!r}, in non-quoted string'.format(quote)) super().__init__(f'Unexpected quote mark, {quote!r}, in non-quoted string')
class InvalidEndOfQuotedStringError(ArgumentParsingError): class InvalidEndOfQuotedStringError(ArgumentParsingError):
"""An exception raised when a space is expected after the closing quote in a string """An exception raised when a space is expected after the closing quote in a string
@ -693,7 +691,7 @@ class InvalidEndOfQuotedStringError(ArgumentParsingError):
""" """
def __init__(self, char): def __init__(self, char):
self.char = char self.char = char
super().__init__('Expected space after closing quotation but received {0!r}'.format(char)) super().__init__(f'Expected space after closing quotation but received {char!r}')
class ExpectedClosingQuoteError(ArgumentParsingError): class ExpectedClosingQuoteError(ArgumentParsingError):
"""An exception raised when a quote character is expected but not found. """An exception raised when a quote character is expected but not found.
@ -708,7 +706,7 @@ class ExpectedClosingQuoteError(ArgumentParsingError):
def __init__(self, close_quote): def __init__(self, close_quote):
self.close_quote = close_quote self.close_quote = close_quote
super().__init__('Expected closing {}.'.format(close_quote)) super().__init__(f'Expected closing {close_quote}.')
class ExtensionError(DiscordException): class ExtensionError(DiscordException):
"""Base exception for extension related errors. """Base exception for extension related errors.
@ -722,7 +720,7 @@ class ExtensionError(DiscordException):
""" """
def __init__(self, message=None, *args, name): def __init__(self, message=None, *args, name):
self.name = name self.name = name
message = message or 'Extension {!r} had an error.'.format(name) message = message or f'Extension {name!r} had an error.'
# clean-up @everyone and @here mentions # clean-up @everyone and @here mentions
m = message.replace('@everyone', '@\u200beveryone').replace('@here', '@\u200bhere') m = message.replace('@everyone', '@\u200beveryone').replace('@here', '@\u200bhere')
super().__init__(m, *args) super().__init__(m, *args)
@ -733,7 +731,7 @@ class ExtensionAlreadyLoaded(ExtensionError):
This inherits from :exc:`ExtensionError` This inherits from :exc:`ExtensionError`
""" """
def __init__(self, name): def __init__(self, name):
super().__init__('Extension {!r} is already loaded.'.format(name), name=name) super().__init__(f'Extension {name!r} is already loaded.', name=name)
class ExtensionNotLoaded(ExtensionError): class ExtensionNotLoaded(ExtensionError):
"""An exception raised when an extension was not loaded. """An exception raised when an extension was not loaded.
@ -741,7 +739,7 @@ class ExtensionNotLoaded(ExtensionError):
This inherits from :exc:`ExtensionError` This inherits from :exc:`ExtensionError`
""" """
def __init__(self, name): def __init__(self, name):
super().__init__('Extension {!r} has not been loaded.'.format(name), name=name) super().__init__(f'Extension {name!r} has not been loaded.', name=name)
class NoEntryPointError(ExtensionError): class NoEntryPointError(ExtensionError):
"""An exception raised when an extension does not have a ``setup`` entry point function. """An exception raised when an extension does not have a ``setup`` entry point function.
@ -749,7 +747,7 @@ class NoEntryPointError(ExtensionError):
This inherits from :exc:`ExtensionError` This inherits from :exc:`ExtensionError`
""" """
def __init__(self, name): def __init__(self, name):
super().__init__("Extension {!r} has no 'setup' function.".format(name), name=name) super().__init__(f"Extension {name!r} has no 'setup' function.", name=name)
class ExtensionFailed(ExtensionError): class ExtensionFailed(ExtensionError):
"""An exception raised when an extension failed to load during execution of the module or ``setup`` entry point. """An exception raised when an extension failed to load during execution of the module or ``setup`` entry point.
@ -808,4 +806,4 @@ class CommandRegistrationError(ClientException):
self.name = name self.name = name
self.alias_conflict = alias_conflict self.alias_conflict = alias_conflict
type_ = 'alias' if alias_conflict else 'command' type_ = 'alias' if alias_conflict else 'command'
super().__init__('The {} {} is already an existing command or alias.'.format(type_, name)) super().__init__(f'The {type_} {name} is already an existing command or alias.')

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -132,7 +130,7 @@ class Paginator:
""" """
max_page_size = self.max_size - self._prefix_len - self._suffix_len - 2 * self._linesep_len max_page_size = self.max_size - self._prefix_len - self._suffix_len - 2 * self._linesep_len
if len(line) > max_page_size: if len(line) > max_page_size:
raise RuntimeError('Line exceeds maximum page size %s' % (max_page_size)) raise RuntimeError(f'Line exceeds maximum page size {max_page_size}')
if self._count + len(line) + self._linesep_len > self.max_size - self._suffix_len: if self._count + len(line) + self._linesep_len > self.max_size - self._suffix_len:
self.close_page() self.close_page()
@ -386,8 +384,9 @@ class HelpCommand:
# consider this to be an *incredibly* strange use case. I'd rather go # consider this to be an *incredibly* strange use case. I'd rather go
# for this common use case rather than waste performance for the # for this common use case rather than waste performance for the
# odd one. # odd one.
pattern = re.compile(r"<@!?%s>" % user.id) pattern = re.compile(fr"<@!?{user.id}>")
return pattern.sub("@%s" % user.display_name.replace('\\', r'\\'), self.context.prefix) display_name = user.display_name.replace('\\', r'\\')
return pattern.sub('@' + display_name, self.context.prefix)
@property @property
def invoked_with(self): def invoked_with(self):
@ -436,14 +435,14 @@ class HelpCommand:
if len(command.aliases) > 0: if len(command.aliases) > 0:
aliases = '|'.join(command.aliases) aliases = '|'.join(command.aliases)
fmt = '[%s|%s]' % (command.name, aliases) fmt = f'[{command.name}|{aliases}]'
if parent_sig: if parent_sig:
fmt = parent_sig + ' ' + fmt fmt = parent_sig + ' ' + fmt
alias = fmt alias = fmt
else: else:
alias = command.name if not parent_sig else parent_sig + ' ' + command.name alias = command.name if not parent_sig else parent_sig + ' ' + command.name
return '%s%s %s' % (self.clean_prefix, alias, command.signature) return f'{self.clean_prefix}{alias} {command.signature}'
def remove_mentions(self, string): def remove_mentions(self, string):
"""Removes mentions from the string to prevent abuse. """Removes mentions from the string to prevent abuse.
@ -506,7 +505,7 @@ class HelpCommand:
:class:`str` :class:`str`
The string to use when a command has not been found. The string to use when a command has not been found.
""" """
return 'No command called "{}" found.'.format(string) return f'No command called "{string}" found.'
def subcommand_not_found(self, command, string): def subcommand_not_found(self, command, string):
"""|maybecoro| """|maybecoro|
@ -535,8 +534,8 @@ class HelpCommand:
The string to use when the command did not have the subcommand requested. The string to use when the command did not have the subcommand requested.
""" """
if isinstance(command, Group) and len(command.all_commands) > 0: if isinstance(command, Group) and len(command.all_commands) > 0:
return 'Command "{0.qualified_name}" has no subcommand named {1}'.format(command, string) return f'Command "{command.qualified_name}" has no subcommand named {string}'
return 'Command "{0.qualified_name}" has no subcommands.'.format(command) return f'Command "{command.qualified_name}" has no subcommands.'
async def filter_commands(self, commands, *, sort=False, key=None): async def filter_commands(self, commands, *, sort=False, key=None):
"""|coro| """|coro|
@ -941,8 +940,8 @@ class DefaultHelpCommand(HelpCommand):
def get_ending_note(self): def get_ending_note(self):
""":class:`str`: Returns help command's ending note. This is mainly useful to override for i18n purposes.""" """:class:`str`: Returns help command's ending note. This is mainly useful to override for i18n purposes."""
command_name = self.invoked_with command_name = self.invoked_with
return "Type {0}{1} command for more info on a command.\n" \ return f"Type {self.clean_prefix}{command_name} command for more info on a command.\n" \
"You can also type {0}{1} category for more info on a category.".format(self.clean_prefix, command_name) f"You can also type {self.clean_prefix}{command_name} category for more info on a category."
def add_indented_commands(self, commands, *, heading, max_size=None): def add_indented_commands(self, commands, *, heading, max_size=None):
"""Indents a list of commands after the specified heading. """Indents a list of commands after the specified heading.
@ -977,7 +976,7 @@ class DefaultHelpCommand(HelpCommand):
for command in commands: for command in commands:
name = command.name name = command.name
width = max_size - (get_width(name) - len(name)) width = max_size - (get_width(name) - len(name))
entry = '{0}{1:<{width}} {2}'.format(self.indent * ' ', name, command.short_doc, width=width) entry = f'{self.indent * " "}{name:<{width}} {command.short_doc}'
self.paginator.add_line(self.shorten_text(entry)) self.paginator.add_line(self.shorten_text(entry))
async def send_pages(self): async def send_pages(self):
@ -1030,7 +1029,7 @@ class DefaultHelpCommand(HelpCommand):
# <description> portion # <description> portion
self.paginator.add_line(bot.description, empty=True) self.paginator.add_line(bot.description, empty=True)
no_category = '\u200b{0.no_category}:'.format(self) no_category = f'\u200b{self.no_category}:'
def get_category(command, *, no_category=no_category): def get_category(command, *, no_category=no_category):
cog = command.cog cog = command.cog
return cog.qualified_name + ':' if cog is not None else no_category return cog.qualified_name + ':' if cog is not None else no_category
@ -1154,7 +1153,7 @@ class MinimalHelpCommand(HelpCommand):
"You can also use `{0}{1} [category]` for more info on a category.".format(self.clean_prefix, command_name) "You can also use `{0}{1} [category]` for more info on a category.".format(self.clean_prefix, command_name)
def get_command_signature(self, command): def get_command_signature(self, command):
return '%s%s %s' % (self.clean_prefix, command.qualified_name, command.signature) return f'{self.clean_prefix}{command.qualified_name} {command.signature}'
def get_ending_note(self): def get_ending_note(self):
"""Return the help command's ending note. This is mainly useful to override for i18n purposes. """Return the help command's ending note. This is mainly useful to override for i18n purposes.
@ -1186,7 +1185,7 @@ class MinimalHelpCommand(HelpCommand):
if commands: if commands:
# U+2002 Middle Dot # U+2002 Middle Dot
joined = '\u2002'.join(c.name for c in commands) joined = '\u2002'.join(c.name for c in commands)
self.paginator.add_line('__**%s**__' % heading) self.paginator.add_line(f'__**{heading}**__')
self.paginator.add_line(joined) self.paginator.add_line(joined)
def add_subcommand_formatting(self, command): def add_subcommand_formatting(self, command):
@ -1220,7 +1219,7 @@ class MinimalHelpCommand(HelpCommand):
aliases: Sequence[:class:`str`] aliases: Sequence[:class:`str`]
A list of aliases to format. A list of aliases to format.
""" """
self.paginator.add_line('**%s** %s' % (self.aliases_heading, ', '.join(aliases)), empty=True) self.paginator.add_line(f'**{self.aliases_heading}** {", ".join(aliases)}', empty=True)
def add_command_formatting(self, command): def add_command_formatting(self, command):
"""A utility function to format commands and groups. """A utility function to format commands and groups.
@ -1273,7 +1272,7 @@ class MinimalHelpCommand(HelpCommand):
if note: if note:
self.paginator.add_line(note, empty=True) self.paginator.add_line(note, empty=True)
no_category = '\u200b{0.no_category}'.format(self) no_category = f'\u200b{self.no_category}'
def get_category(command, *, no_category=no_category): def get_category(command, *, no_category=no_category):
cog = command.cog cog = command.cog
return cog.qualified_name if cog is not None else no_category return cog.qualified_name if cog is not None else no_category
@ -1306,7 +1305,7 @@ class MinimalHelpCommand(HelpCommand):
filtered = await self.filter_commands(cog.get_commands(), sort=self.sort_commands) filtered = await self.filter_commands(cog.get_commands(), sort=self.sort_commands)
if filtered: if filtered:
self.paginator.add_line('**%s %s**' % (cog.qualified_name, self.commands_heading)) self.paginator.add_line(f'**{cog.qualified_name} {self.commands_heading}**')
for command in filtered: for command in filtered:
self.add_subcommand_formatting(command) self.add_subcommand_formatting(command)
@ -1326,7 +1325,7 @@ class MinimalHelpCommand(HelpCommand):
if note: if note:
self.paginator.add_line(note, empty=True) self.paginator.add_line(note, empty=True)
self.paginator.add_line('**%s**' % self.commands_heading) self.paginator.add_line(f'**{self.commands_heading}**')
for command in filtered: for command in filtered:
self.add_subcommand_formatting(command) self.add_subcommand_formatting(command)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -289,9 +287,9 @@ class Loop:
for exc in exceptions: for exc in exceptions:
if not inspect.isclass(exc): if not inspect.isclass(exc):
raise TypeError('{0!r} must be a class.'.format(exc)) raise TypeError(f'{exc!r} must be a class.')
if not issubclass(exc, BaseException): if not issubclass(exc, BaseException):
raise TypeError('{0!r} must inherit from BaseException.'.format(exc)) raise TypeError(f'{exc!r} must inherit from BaseException.')
self._valid_exception = (*self._valid_exception, *exceptions) self._valid_exception = (*self._valid_exception, *exceptions)
@ -345,7 +343,7 @@ class Loop:
async def _error(self, *args): async def _error(self, *args):
exception = args[-1] exception = args[-1]
print('Unhandled exception in internal background task {0.__name__!r}.'.format(self.coro), file=sys.stderr) print(f'Unhandled exception in internal background task {self.coro.__name__!r}.', file=sys.stderr)
traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr) traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr)
def before_loop(self, coro): def before_loop(self, coro):

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -65,7 +63,7 @@ class File:
if isinstance(fp, io.IOBase): if isinstance(fp, io.IOBase):
if not (fp.seekable() and fp.readable()): if not (fp.seekable() and fp.readable()):
raise ValueError('File buffer {!r} must be seekable and readable'.format(fp)) raise ValueError(f'File buffer {fp!r} must be seekable and readable')
self.fp = fp self.fp = fp
self._original_pos = fp.tell() self._original_pos = fp.tell()
self._owner = False self._owner = False

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -48,7 +46,7 @@ class flag_value:
instance._set_flag(self.flag, value) instance._set_flag(self.flag, value)
def __repr__(self): def __repr__(self):
return '<flag_value flag={.flag!r}>'.format(self) return f'<flag_value flag={self.flag!r}>'
class alias_flag_value(flag_value): class alias_flag_value(flag_value):
pass pass
@ -78,7 +76,7 @@ class BaseFlags:
self.value = self.DEFAULT_VALUE self.value = self.DEFAULT_VALUE
for key, value in kwargs.items(): for key, value in kwargs.items():
if key not in self.VALID_FLAGS: if key not in self.VALID_FLAGS:
raise TypeError('%r is not a valid flag name.' % key) raise TypeError(f'{key!r} is not a valid flag name.')
setattr(self, key, value) setattr(self, key, value)
@classmethod @classmethod
@ -97,7 +95,7 @@ class BaseFlags:
return hash(self.value) return hash(self.value)
def __repr__(self): def __repr__(self):
return '<%s value=%s>' % (self.__class__.__name__, self.value) return f'<{self.__class__.__name__} value={self.value}>'
def __iter__(self): def __iter__(self):
for name, value in self.__class__.__dict__.items(): for name, value in self.__class__.__dict__.items():
@ -116,7 +114,7 @@ class BaseFlags:
elif toggle is False: elif toggle is False:
self.value &= ~o self.value &= ~o
else: else:
raise TypeError('Value to set for %s must be a bool.' % self.__class__.__name__) raise TypeError(f'Value to set for {self.__class__.__name__} must be a bool.')
@fill_with_flags(inverted=True) @fill_with_flags(inverted=True)
class SystemChannelFlags(BaseFlags): class SystemChannelFlags(BaseFlags):
@ -399,7 +397,7 @@ class Intents(BaseFlags):
self.value = self.DEFAULT_VALUE self.value = self.DEFAULT_VALUE
for key, value in kwargs.items(): for key, value in kwargs.items():
if key not in self.VALID_FLAGS: if key not in self.VALID_FLAGS:
raise TypeError('%r is not a valid flag name.' % key) raise TypeError(f'{key!r} is not a valid flag name.')
setattr(self, key, value) setattr(self, key, value)
@classmethod @classmethod
@ -832,7 +830,7 @@ class MemberCacheFlags(BaseFlags):
self.value = (1 << bits) - 1 self.value = (1 << bits) - 1
for key, value in kwargs.items(): for key, value in kwargs.items():
if key not in self.VALID_FLAGS: if key not in self.VALID_FLAGS:
raise TypeError('%r is not a valid flag name.' % key) raise TypeError(f'{key!r} is not a valid flag name.')
setattr(self, key, value) setattr(self, key, value)
@classmethod @classmethod

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -162,8 +160,8 @@ class KeepAliveHandler(threading.Thread):
except KeyError: except KeyError:
msg = self.block_msg msg = self.block_msg
else: else:
stack = traceback.format_stack(frame) stack = ''.join(traceback.format_stack(frame))
msg = '%s\nLoop thread traceback (most recent call last):\n%s' % (self.block_msg, ''.join(stack)) msg = f'{self.block_msg}\nLoop thread traceback (most recent call last):\n{stack}'
log.warning(msg, self.shard_id, total) log.warning(msg, self.shard_id, total)
except Exception: except Exception:

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -209,11 +207,14 @@ class Guild(Hashable):
def __repr__(self): def __repr__(self):
attrs = ( attrs = (
'id', 'name', 'shard_id', 'chunked' ('id', self.id),
('name', self.name),
('shard_id', self.shard_id),
('chunked', self.chunked),
('member_count', getattr(self, '_member_count', None)),
) )
resolved = ['%s=%r' % (attr, getattr(self, attr)) for attr in attrs] inner = ' '.join('%s=%r' % t for t in attrs)
resolved.append('member_count=%r' % getattr(self, '_member_count', None)) return f'<Guild {inner}>'
return '<Guild %s>' % ' '.join(resolved)
def _update_voice_state(self, data, channel_id): def _update_voice_state(self, data, channel_id):
user_id = int(data['user_id']) user_id = int(data['user_id'])
@ -1507,7 +1508,7 @@ class Guild(Hashable):
""" """
if not isinstance(days, int): if not isinstance(days, int):
raise InvalidArgument('Expected int for ``days``, received {0.__class__.__name__} instead.'.format(days)) raise InvalidArgument(f'Expected int for ``days``, received {days.__class__.__name__} instead.')
if roles: if roles:
roles = [str(role.id) for role in roles] roles = [str(role.id) for role in roles]
@ -1593,7 +1594,7 @@ class Guild(Hashable):
""" """
if not isinstance(days, int): if not isinstance(days, int):
raise InvalidArgument('Expected int for ``days``, received {0.__class__.__name__} instead.'.format(days)) raise InvalidArgument(f'Expected int for ``days``, received {days.__class__.__name__} instead.')
if roles: if roles:
roles = [str(role.id) for role in roles] roles = [str(role.id) for role in roles]
@ -1896,7 +1897,7 @@ class Guild(Hashable):
valid_keys = ('name', 'permissions', 'color', 'hoist', 'mentionable') valid_keys = ('name', 'permissions', 'color', 'hoist', 'mentionable')
for key in fields: for key in fields:
if key not in valid_keys: if key not in valid_keys:
raise InvalidArgument('%r is not a valid field.' % key) raise InvalidArgument(f'{key!r} is not a valid field.')
data = await self._state.http.create_role(self.id, reason=reason, **fields) data = await self._state.http.create_role(self.id, reason=reason, **fields)
role = Role(guild=self, data=data, state=self._state) role = Role(guild=self, data=data, state=self._state)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -404,7 +402,7 @@ class HTTPClient:
else: else:
for index, file in enumerate(files): for index, file in enumerate(files):
form.append({ form.append({
'name': 'file%s' % index, 'name': f'file{index}',
'value': file.fp, 'value': file.fp,
'filename': file.filename, 'filename': file.filename,
'content_type': 'application/octet-stream' 'content_type': 'application/octet-stream'

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -113,7 +111,8 @@ class VoiceState:
('requested_to_speak_at', self.requested_to_speak_at), ('requested_to_speak_at', self.requested_to_speak_at),
('channel', self.channel) ('channel', self.channel)
] ]
return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) inner = ' '.join('%s=%r' % t for t in attrs)
return f'<{self.__class__.__name__} {inner}>'
def flatten_user(cls): def flatten_user(cls):
for attr, value in itertools.chain(BaseUser.__dict__.items(), User.__dict__.items()): for attr, value in itertools.chain(BaseUser.__dict__.items(), User.__dict__.items()):
@ -129,7 +128,7 @@ def flatten_user(cls):
# slotted members are implemented as member_descriptors in Type.__dict__ # slotted members are implemented as member_descriptors in Type.__dict__
if not hasattr(value, '__annotations__'): if not hasattr(value, '__annotations__'):
getter = attrgetter('_user.' + attr) getter = attrgetter('_user.' + attr)
setattr(cls, attr, property(getter, doc='Equivalent to :attr:`User.%s`' % attr)) setattr(cls, attr, property(getter, doc=f'Equivalent to :attr:`User.{attr}`'))
else: else:
# Technically, this can also use attrgetter # Technically, this can also use attrgetter
# However I'm not sure how I feel about "functions" returning properties # However I'm not sure how I feel about "functions" returning properties
@ -222,8 +221,8 @@ class Member(discord.abc.Messageable, _BaseUser):
return str(self._user) return str(self._user)
def __repr__(self): def __repr__(self):
return '<Member id={1.id} name={1.name!r} discriminator={1.discriminator!r}' \ return f'<Member id={self._user.id} name={self._user.name!r} discriminator={self._user.discriminator!r}' \
' bot={1.bot} nick={0.nick!r} guild={0.guild!r}>'.format(self, self._user) f' bot={self._user.bot} nick={self.nick!r} guild={self.guild!r}>'
def __eq__(self, other): def __eq__(self, other):
return isinstance(other, _BaseUser) and other.id == self.id return isinstance(other, _BaseUser) and other.id == self.id
@ -422,8 +421,8 @@ class Member(discord.abc.Messageable, _BaseUser):
def mention(self): def mention(self):
""":class:`str`: Returns a string that allows you to mention the member.""" """:class:`str`: Returns a string that allows you to mention the member."""
if self.nick: if self.nick:
return '<@!%s>' % self.id return f'<@!{self._user.id}>'
return '<@%s>' % self.id return f'<@{self._user.id}>'
@property @property
def display_name(self): def display_name(self):

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -58,7 +56,7 @@ def convert_emoji_reaction(emoji):
emoji = emoji.emoji emoji = emoji.emoji
if isinstance(emoji, Emoji): if isinstance(emoji, Emoji):
return '%s:%s' % (emoji.name, emoji.id) return f'{emoji.name}:{emoji.id}'
if isinstance(emoji, PartialEmoji): if isinstance(emoji, PartialEmoji):
return emoji._as_reaction() return emoji._as_reaction()
if isinstance(emoji, str): if isinstance(emoji, str):
@ -66,7 +64,7 @@ def convert_emoji_reaction(emoji):
# No existing emojis have <> in them, so this should be okay. # No existing emojis have <> in them, so this should be okay.
return emoji.strip('<>') return emoji.strip('<>')
raise InvalidArgument('emoji argument must be str, Emoji, or Reaction not {.__class__.__name__}.'.format(emoji)) raise InvalidArgument(f'emoji argument must be str, Emoji, or Reaction not {emoji.__class__.__name__}.')
class Attachment(Hashable): class Attachment(Hashable):
"""Represents an attachment from Discord. """Represents an attachment from Discord.
@ -585,7 +583,7 @@ class Message(Hashable):
for handler in ('author', 'member', 'mentions', 'mention_roles', 'call', 'flags'): for handler in ('author', 'member', 'mentions', 'mention_roles', 'call', 'flags'):
try: try:
getattr(self, '_handle_%s' % handler)(data[handler]) getattr(self, f'_handle_{handler}')(data[handler])
except KeyError: except KeyError:
continue continue
@ -833,18 +831,18 @@ class Message(Hashable):
""" """
transformations = { transformations = {
re.escape('<#%s>' % channel.id): '#' + channel.name re.escape(f'<#{channel.id}>'): '#' + channel.name
for channel in self.channel_mentions for channel in self.channel_mentions
} }
mention_transforms = { mention_transforms = {
re.escape('<@%s>' % member.id): '@' + member.display_name re.escape(f'<@{member.id}>'): '@' + member.display_name
for member in self.mentions for member in self.mentions
} }
# add the <@!user_id> cases as well.. # add the <@!user_id> cases as well..
second_mention_transforms = { second_mention_transforms = {
re.escape('<@!%s>' % member.id): '@' + member.display_name re.escape(f'<@!{member.id}>'): '@' + member.display_name
for member in self.mentions for member in self.mentions
} }
@ -853,7 +851,7 @@ class Message(Hashable):
if self.guild is not None: if self.guild is not None:
role_transforms = { role_transforms = {
re.escape('<@&%s>' % role.id): '@' + role.name re.escape(f'<@&{role.id}>'): '@' + role.name
for role in self.role_mentions for role in self.role_mentions
} }
transformations.update(role_transforms) transformations.update(role_transforms)
@ -902,7 +900,7 @@ class Message(Hashable):
return self.content return self.content
if self.type is MessageType.pins_add: if self.type is MessageType.pins_add:
return '{0.name} pinned a message to this channel.'.format(self.author) return f'{self.author.name} pinned a message to this channel.'
if self.type is MessageType.recipient_add: if self.type is MessageType.recipient_add:
return '{0.name} added {1.name} to the group.'.format(self.author, self.mentions[0]) return '{0.name} added {1.name} to the group.'.format(self.author, self.mentions[0])
@ -914,7 +912,7 @@ class Message(Hashable):
return '{0.author.name} changed the channel name: {0.content}'.format(self) return '{0.author.name} changed the channel name: {0.content}'.format(self)
if self.type is MessageType.channel_icon_change: if self.type is MessageType.channel_icon_change:
return '{0.author.name} changed the channel icon.'.format(self) return f'{self.author.name} changed the channel icon.'
if self.type is MessageType.new_member: if self.type is MessageType.new_member:
formats = [ formats = [
@ -946,14 +944,14 @@ class Message(Hashable):
call_ended = self.call.ended_timestamp is not None call_ended = self.call.ended_timestamp is not None
if self.channel.me in self.call.participants: if self.channel.me in self.call.participants:
return '{0.author.name} started a call.'.format(self) return f'{self.author.name} started a call.'
elif call_ended: elif call_ended:
return 'You missed a call from {0.author.name}'.format(self) return f'You missed a call from {self.author.name}'
else: else:
return '{0.author.name} started a call \N{EM DASH} Join the call.'.format(self) return '{0.author.name} started a call \N{EM DASH} Join the call.'.format(self)
if self.type is MessageType.premium_guild_subscription: if self.type is MessageType.premium_guild_subscription:
return '{0.author.name} just boosted the server!'.format(self) return f'{self.author.name} just boosted the server!'
if self.type is MessageType.premium_guild_tier_1: if self.type is MessageType.premium_guild_tier_1:
return '{0.author.name} just boosted the server! {0.guild} has achieved **Level 1!**'.format(self) return '{0.author.name} just boosted the server! {0.guild} has achieved **Level 1!**'.format(self)
@ -1447,7 +1445,7 @@ class PartialMessage(Hashable):
def __init__(self, *, channel, id): def __init__(self, *, channel, id):
if channel.type not in (ChannelType.text, ChannelType.news, ChannelType.private): if channel.type not in (ChannelType.text, ChannelType.news, ChannelType.private):
raise TypeError('Expected TextChannel or DMChannel not %r' % type(channel)) raise TypeError(f'Expected TextChannel or DMChannel not {type(channel)!r}')
self.channel = channel self.channel = channel
self._state = channel._state self._state = channel._state

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -65,12 +63,12 @@ class Object(Hashable):
try: try:
id = int(id) id = int(id)
except ValueError: except ValueError:
raise TypeError('id parameter must be convertable to int not {0.__class__!r}'.format(id)) from None raise TypeError(f'id parameter must be convertable to int not {id.__class__!r}') from None
else: else:
self.id = id self.id = id
def __repr__(self): def __repr__(self):
return '<Object id=%r>' % self.id return f'<Object id={self.id!r}>'
@property @property
def created_at(self): def created_at(self):

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -185,7 +183,7 @@ def _load_default():
_basedir = os.path.dirname(os.path.abspath(__file__)) _basedir = os.path.dirname(os.path.abspath(__file__))
_bitness = struct.calcsize('P') * 8 _bitness = struct.calcsize('P') * 8
_target = 'x64' if _bitness > 32 else 'x86' _target = 'x64' if _bitness > 32 else 'x86'
_filename = os.path.join(_basedir, 'bin', 'libopus-0.{}.dll'.format(_target)) _filename = os.path.join(_basedir, 'bin', f'libopus-0.{_target}.dll')
_lib = libopus_loader(_filename) _lib = libopus_loader(_filename)
else: else:
_lib = libopus_loader(ctypes.util.find_library('opus')) _lib = libopus_loader(ctypes.util.find_library('opus'))
@ -310,14 +308,14 @@ class Encoder(_OpusStruct):
def set_bandwidth(self, req): def set_bandwidth(self, req):
if req not in band_ctl: if req not in band_ctl:
raise KeyError('%r is not a valid bandwidth setting. Try one of: %s' % (req, ','.join(band_ctl))) raise KeyError(f'{req!r} is not a valid bandwidth setting. Try one of: {",".join(band_ctl)}')
k = band_ctl[req] k = band_ctl[req]
_lib.opus_encoder_ctl(self._state, CTL_SET_BANDWIDTH, k) _lib.opus_encoder_ctl(self._state, CTL_SET_BANDWIDTH, k)
def set_signal_type(self, req): def set_signal_type(self, req):
if req not in signal_ctl: if req not in signal_ctl:
raise KeyError('%r is not a valid signal setting. Try one of: %s' % (req, ','.join(signal_ctl))) raise KeyError(f'{req!r} is not a valid bandwidth setting. Try one of: {",".join(signal_ctl)}')
k = signal_ctl[req] k = signal_ctl[req]
_lib.opus_encoder_ctl(self._state, CTL_SET_SIGNAL, k) _lib.opus_encoder_ctl(self._state, CTL_SET_SIGNAL, k)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -103,8 +101,8 @@ class PartialEmoji(_EmojiTag):
if self.id is None: if self.id is None:
return self.name return self.name
if self.animated: if self.animated:
return '<a:%s:%s>' % (self.name, self.id) return f'<a:{self.name}:{self.id}>'
return '<:%s:%s>' % (self.name, self.id) return f'<:{self.name}:{self.id}>'
def __repr__(self): def __repr__(self):
return '<{0.__class__.__name__} animated={0.animated} name={0.name!r} id={0.id}>'.format(self) return '<{0.__class__.__name__} animated={0.animated} name={0.name!r} id={0.id}>'.format(self)
@ -134,7 +132,7 @@ class PartialEmoji(_EmojiTag):
def _as_reaction(self): def _as_reaction(self):
if self.id is None: if self.id is None:
return self.name return self.name
return '%s:%s' % (self.name, self.id) return f'{self.name}:{self.id}'
@property @property
def created_at(self): def created_at(self):

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -96,12 +94,12 @@ class Permissions(BaseFlags):
def __init__(self, permissions=0, **kwargs): def __init__(self, permissions=0, **kwargs):
if not isinstance(permissions, int): if not isinstance(permissions, int):
raise TypeError('Expected int parameter, received %s instead.' % permissions.__class__.__name__) raise TypeError(f'Expected int parameter, received {permissions.__class__.__name__} instead.')
self.value = permissions self.value = permissions
for key, value in kwargs.items(): for key, value in kwargs.items():
if key not in self.VALID_FLAGS: if key not in self.VALID_FLAGS:
raise TypeError('%r is not a valid permission name.' % key) raise TypeError(f'{key!r} is not a valid permission name.')
setattr(self, key, value) setattr(self, key, value)
def is_subset(self, other): def is_subset(self, other):
@ -109,14 +107,14 @@ class Permissions(BaseFlags):
if isinstance(other, Permissions): if isinstance(other, Permissions):
return (self.value & other.value) == self.value return (self.value & other.value) == self.value
else: else:
raise TypeError("cannot compare {} with {}".format(self.__class__.__name__, other.__class__.__name__)) raise TypeError(f"cannot compare {self.__class__.__name__} with {other.__class__.__name__}")
def is_superset(self, other): def is_superset(self, other):
"""Returns ``True`` if self has the same or more permissions as other.""" """Returns ``True`` if self has the same or more permissions as other."""
if isinstance(other, Permissions): if isinstance(other, Permissions):
return (self.value | other.value) == self.value return (self.value | other.value) == self.value
else: else:
raise TypeError("cannot compare {} with {}".format(self.__class__.__name__, other.__class__.__name__)) raise TypeError(f"cannot compare {self.__class__.__name__} with {other.__class__.__name__}")
def is_strict_subset(self, other): def is_strict_subset(self, other):
"""Returns ``True`` if the permissions on other are a strict subset of those on self.""" """Returns ``True`` if the permissions on other are a strict subset of those on self."""
@ -539,7 +537,7 @@ class PermissionOverwrite:
for key, value in kwargs.items(): for key, value in kwargs.items():
if key not in self.VALID_NAMES: if key not in self.VALID_NAMES:
raise ValueError('no permission called {0}.'.format(key)) raise ValueError(f'no permission called {key}.')
setattr(self, key, value) setattr(self, key, value)
@ -548,7 +546,7 @@ class PermissionOverwrite:
def _set(self, key, value): def _set(self, key, value):
if value not in (True, None, False): if value not in (True, None, False):
raise TypeError('Expected bool or NoneType, received {0.__class__.__name__}'.format(value)) raise TypeError(f'Expected bool or NoneType, received {value.__class__.__name__}')
if value is None: if value is None:
self._values.pop(key, None) self._values.pop(key, None)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -313,7 +311,7 @@ class FFmpegOpusAudio(FFmpegAudio):
'-c:a', codec, '-c:a', codec,
'-ar', '48000', '-ar', '48000',
'-ac', '2', '-ac', '2',
'-b:a', '%sk' % bitrate, '-b:a', f'{bitrate}k',
'-loglevel', 'warning')) '-loglevel', 'warning'))
if isinstance(options, str): if isinstance(options, str):
@ -421,7 +419,7 @@ class FFmpegOpusAudio(FFmpegAudio):
if isinstance(method, str): if isinstance(method, str):
probefunc = getattr(cls, '_probe_codec_' + method, None) probefunc = getattr(cls, '_probe_codec_' + method, None)
if probefunc is None: if probefunc is None:
raise AttributeError("Invalid probe method '%s'" % method) raise AttributeError(f"Invalid probe method {method!r}")
if probefunc is cls._probe_codec_native: if probefunc is cls._probe_codec_native:
fallback = cls._probe_codec_fallback fallback = cls._probe_codec_fallback
@ -431,7 +429,7 @@ class FFmpegOpusAudio(FFmpegAudio):
fallback = cls._probe_codec_fallback fallback = cls._probe_codec_fallback
else: else:
raise TypeError("Expected str or callable for parameter 'probe', " \ raise TypeError("Expected str or callable for parameter 'probe', " \
"not '{0.__class__.__name__}'" .format(method)) f"not '{method.__class__.__name__}'")
codec = bitrate = None codec = bitrate = None
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
@ -519,7 +517,7 @@ class PCMVolumeTransformer(AudioSource):
def __init__(self, original, volume=1.0): def __init__(self, original, volume=1.0):
if not isinstance(original, AudioSource): if not isinstance(original, AudioSource):
raise TypeError('expected AudioSource not {0.__class__.__name__}.'.format(original)) raise TypeError(f'expected AudioSource not {original.__class__.__name__}.')
if original.is_opus(): if original.is_opus():
raise ClientException('AudioSource must not be Opus encoded.') raise ClientException('AudioSource must not be Opus encoded.')
@ -619,7 +617,7 @@ class AudioPlayer(threading.Thread):
exc.__context__ = error exc.__context__ = error
traceback.print_exception(type(exc), exc, exc.__traceback__) traceback.print_exception(type(exc), exc, exc.__traceback__)
elif error: elif error:
msg = 'Exception in voice thread {}'.format(self.name) msg = f'Exception in voice thread {self.name}'
log.exception(msg, exc_info=error) log.exception(msg, exc_info=error)
print(msg, file=sys.stderr) print(msg, file=sys.stderr)
traceback.print_exception(type(error), error, error.__traceback__) traceback.print_exception(type(error), error, error.__traceback__)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -26,8 +24,8 @@ DEALINGS IN THE SOFTWARE.
class _RawReprMixin: class _RawReprMixin:
def __repr__(self): def __repr__(self):
value = ' '.join('%s=%r' % (attr, getattr(self, attr)) for attr in self.__slots__) value = ' '.join(f'{attr}={getattr(self, attr)!r}' for attr in self.__slots__)
return '<%s %s>' % (self.__class__.__name__, value) return f'<{self.__class__.__name__} {value}>'
class RawMessageDeleteEvent(_RawReprMixin): class RawMessageDeleteEvent(_RawReprMixin):
"""Represents the event payload for a :func:`on_raw_message_delete` event. """Represents the event payload for a :func:`on_raw_message_delete` event.

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -248,7 +246,7 @@ class Role(Hashable):
@property @property
def mention(self): def mention(self):
""":class:`str`: Returns a string that allows you to mention a role.""" """:class:`str`: Returns a string that allows you to mention a role."""
return '<@&%s>' % self.id return f'<@&{self.id}>'
@property @property
def members(self): def members(self):

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -149,7 +147,7 @@ class ConnectionState:
intents = options.get('intents', None) intents = options.get('intents', None)
if intents is not None: if intents is not None:
if not isinstance(intents, Intents): if not isinstance(intents, Intents):
raise TypeError('intents parameter must be Intent not %r' % type(intents)) raise TypeError(f'intents parameter must be Intent not {type(intents)!r}')
else: else:
intents = Intents.default() intents = Intents.default()
@ -175,7 +173,7 @@ class ConnectionState:
cache_flags = MemberCacheFlags.from_intents(intents) cache_flags = MemberCacheFlags.from_intents(intents)
else: else:
if not isinstance(cache_flags, MemberCacheFlags): if not isinstance(cache_flags, MemberCacheFlags):
raise TypeError('member_cache_flags parameter must be MemberCacheFlags not %r' % type(cache_flags)) raise TypeError(f'member_cache_flags parameter must be MemberCacheFlags not {type(cache_flags)!r}')
cache_flags._verify_intents(intents) cache_flags._verify_intents(intents)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -76,7 +74,7 @@ class _PartialTemplateState:
return [] return []
def __getattr__(self, attr): def __getattr__(self, attr):
raise AttributeError('PartialTemplateState does not support {0!r}.'.format(attr)) raise AttributeError(f'PartialTemplateState does not support {attr!r}.')
class Template: class Template:
"""Represents a Discord template. """Represents a Discord template.

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -199,7 +197,7 @@ class BaseUser(_BaseUser):
@property @property
def default_avatar_url(self): def default_avatar_url(self):
""":class:`Asset`: Returns a URL for a user's default avatar.""" """:class:`Asset`: Returns a URL for a user's default avatar."""
return Asset(self._state, '/embed/avatars/{}.png'.format(self.default_avatar.value)) return Asset(self._state, f'/embed/avatars/{self.default_avatar.value}.png')
@property @property
def colour(self): def colour(self):
@ -222,7 +220,7 @@ class BaseUser(_BaseUser):
@property @property
def mention(self): def mention(self):
""":class:`str`: Returns a string that allows you to mention the given user.""" """:class:`str`: Returns a string that allows you to mention the given user."""
return '<@{0.id}>'.format(self) return f'<@{self.id}>'
def permissions_in(self, channel): def permissions_in(self, channel):
"""An alias for :meth:`abc.GuildChannel.permissions_for`. """An alias for :meth:`abc.GuildChannel.permissions_for`.

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -158,7 +156,7 @@ def oauth_url(client_id, permissions=None, guild=None, redirect_uri=None, scopes
:class:`str` :class:`str`
The OAuth2 URL for inviting the bot into guilds. The OAuth2 URL for inviting the bot into guilds.
""" """
url = 'https://discord.com/oauth2/authorize?client_id={}'.format(client_id) url = f'https://discord.com/oauth2/authorize?client_id={client_id}'
url = url + '&scope=' + '+'.join(scopes or ('bot',)) url = url + '&scope=' + '+'.join(scopes or ('bot',))
if permissions is not None: if permissions is not None:
url = url + '&permissions=' + str(permissions.value) url = url + '&permissions=' + str(permissions.value)
@ -489,11 +487,11 @@ _MARKDOWN_ESCAPE_SUBREGEX = '|'.join(r'\{0}(?=([\s\S]*((?<!\{0})\{0})))'.format(
_MARKDOWN_ESCAPE_COMMON = r'^>(?:>>)?\s|\[.+\]\(.+\)' _MARKDOWN_ESCAPE_COMMON = r'^>(?:>>)?\s|\[.+\]\(.+\)'
_MARKDOWN_ESCAPE_REGEX = re.compile(r'(?P<markdown>%s|%s)' % (_MARKDOWN_ESCAPE_SUBREGEX, _MARKDOWN_ESCAPE_COMMON), re.MULTILINE) _MARKDOWN_ESCAPE_REGEX = re.compile(fr'(?P<markdown>{_MARKDOWN_ESCAPE_SUBREGEX}|{_MARKDOWN_ESCAPE_COMMON})', re.MULTILINE)
_URL_REGEX = r'(?P<url><[^: >]+:\/[^ >]+>|(?:https?|steam):\/\/[^\s<]+[^<.,:;\"\'\]\s])' _URL_REGEX = r'(?P<url><[^: >]+:\/[^ >]+>|(?:https?|steam):\/\/[^\s<]+[^<.,:;\"\'\]\s])'
_MARKDOWN_STOCK_REGEX = r'(?P<markdown>[_\\~|\*`]|%s)' % _MARKDOWN_ESCAPE_COMMON _MARKDOWN_STOCK_REGEX = fr'(?P<markdown>[_\\~|\*`]|{_MARKDOWN_ESCAPE_COMMON})'
def remove_markdown(text, *, ignore_links=True): def remove_markdown(text, *, ignore_links=True):
"""A helper function that removes markdown characters. """A helper function that removes markdown characters.
@ -525,7 +523,7 @@ def remove_markdown(text, *, ignore_links=True):
regex = _MARKDOWN_STOCK_REGEX regex = _MARKDOWN_STOCK_REGEX
if ignore_links: if ignore_links:
regex = '(?:%s|%s)' % (_URL_REGEX, regex) regex = f'(?:{_URL_REGEX}|{regex})'
return re.sub(regex, replacement, text, 0, re.MULTILINE) return re.sub(regex, replacement, text, 0, re.MULTILINE)
def escape_markdown(text, *, as_needed=False, ignore_links=True): def escape_markdown(text, *, as_needed=False, ignore_links=True):
@ -563,7 +561,7 @@ def escape_markdown(text, *, as_needed=False, ignore_links=True):
regex = _MARKDOWN_STOCK_REGEX regex = _MARKDOWN_STOCK_REGEX
if ignore_links: if ignore_links:
regex = '(?:%s|%s)' % (_URL_REGEX, regex) regex = f'(?:{_URL_REGEX}|{regex})'
return re.sub(regex, replacement, text, 0, re.MULTILINE) return re.sub(regex, replacement, text, 0, re.MULTILINE)
else: else:
text = re.sub(r'\\', r'\\\\', text) text = re.sub(r'\\', r'\\\\', text)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -558,7 +556,7 @@ class VoiceClient(VoiceProtocol):
raise ClientException('Already playing audio.') raise ClientException('Already playing audio.')
if not isinstance(source, AudioSource): if not isinstance(source, AudioSource):
raise TypeError('source must an AudioSource not {0.__class__.__name__}'.format(source)) raise TypeError(f'source must an AudioSource not {source.__class__.__name__}')
if not self.encoder and not source.is_opus(): if not self.encoder and not source.is_opus():
self.encoder = opus.Encoder() self.encoder = opus.Encoder()
@ -601,7 +599,7 @@ class VoiceClient(VoiceProtocol):
@source.setter @source.setter
def source(self, value): def source(self, value):
if not isinstance(value, AudioSource): if not isinstance(value, AudioSource):
raise TypeError('expected AudioSource not {0.__class__.__name__}.'.format(value)) raise TypeError(f'expected AudioSource not {value.__class__.__name__}.')
if self._player is None: if self._player is None:
raise ValueError('Not playing anything.') raise ValueError('Not playing anything.')

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -65,7 +63,7 @@ class WebhookAdapter:
def _prepare(self, webhook): def _prepare(self, webhook):
self._webhook_id = webhook.id self._webhook_id = webhook.id
self._webhook_token = webhook.token self._webhook_token = webhook.token
self._request_url = '{0.BASE}/webhooks/{1}/{2}'.format(self, webhook.id, webhook.token) self._request_url = f'{self.BASE}/webhooks/{webhook.id}/{webhook.token}'
self.webhook = webhook self.webhook = webhook
def is_async(self): def is_async(self):
@ -100,10 +98,10 @@ class WebhookAdapter:
return self.request('PATCH', self._request_url, payload=payload, reason=reason) return self.request('PATCH', self._request_url, payload=payload, reason=reason)
def edit_webhook_message(self, message_id, payload): def edit_webhook_message(self, message_id, payload):
return self.request('PATCH', '{}/messages/{}'.format(self._request_url, message_id), payload=payload) return self.request('PATCH', f'{self._request_url}/messages/{message_id}', payload=payload)
def delete_webhook_message(self, message_id): def delete_webhook_message(self, message_id):
return self.request('DELETE', '{}/messages/{}'.format(self._request_url, message_id)) return self.request('DELETE', f'{self._request_url}/messages/{message_id}')
def handle_execution_response(self, data, *, wait): def handle_execution_response(self, data, *, wait):
"""Transforms the webhook execution response into something """Transforms the webhook execution response into something
@ -158,7 +156,7 @@ class WebhookAdapter:
multipart = None multipart = None
files_to_pass = None files_to_pass = None
url = '%s?wait=%d' % (self._request_url, wait) url = f'{self._request_url}?wait={int(wait)}'
maybe_coro = None maybe_coro = None
try: try:
maybe_coro = self.request('POST', url, multipart=multipart, payload=data, files=files_to_pass) maybe_coro = self.request('POST', url, multipart=multipart, payload=data, files=files_to_pass)
@ -422,7 +420,7 @@ class _PartialWebhookState:
if self.parent is not None: if self.parent is not None:
return getattr(self.parent, attr) return getattr(self.parent, attr)
raise AttributeError('PartialWebhookState does not support {0!r}.'.format(attr)) raise AttributeError(f'PartialWebhookState does not support {attr!r}.')
class WebhookMessage(Message): class WebhookMessage(Message):
"""Represents a message sent from your webhook. """Represents a message sent from your webhook.
@ -623,12 +621,12 @@ class Webhook(Hashable):
self.user = User(state=state, data=user) self.user = User(state=state, data=user)
def __repr__(self): def __repr__(self):
return '<Webhook id=%r>' % self.id return f'<Webhook id={self.id!r}>'
@property @property
def url(self): def url(self):
""":class:`str` : Returns the webhook's url.""" """:class:`str` : Returns the webhook's url."""
return 'https://discord.com/api/webhooks/{}/{}'.format(self.id, self.token) return f'https://discord.com/api/webhooks/{self.id}/{self.token}'
@classmethod @classmethod
def partial(cls, id, token, *, adapter): def partial(cls, id, token, *, adapter):
@ -697,7 +695,7 @@ class Webhook(Hashable):
@classmethod @classmethod
def _as_follower(cls, data, *, channel, user): def _as_follower(cls, data, *, channel, user):
name = "{} #{}".format(channel.guild, channel) name = f"{channel.guild} #{channel}"
feed = { feed = {
'id': data['webhook_id'], 'id': data['webhook_id'],
'type': 2, 'type': 2,

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
""" """
The MIT License (MIT) The MIT License (MIT)
@ -77,7 +75,7 @@ class WidgetChannel:
@property @property
def mention(self): def mention(self):
""":class:`str`: The string that allows you to mention the channel.""" """:class:`str`: The string that allows you to mention the channel."""
return '<#%s>' % self.id return f'<#{self.id}>'
@property @property
def created_at(self): def created_at(self):
@ -236,7 +234,7 @@ class Widget:
@property @property
def json_url(self): def json_url(self):
""":class:`str`: The JSON URL of the widget.""" """:class:`str`: The JSON URL of the widget."""
return "https://discord.com/api/guilds/{0.id}/widget.json".format(self) return f"https://discord.com/api/guilds/{self.id}/widget.json"
@property @property
def invite_url(self): def invite_url(self):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# discord.py documentation build configuration file, created by # discord.py documentation build configuration file, created by
# sphinx-quickstart on Fri Aug 21 05:43:30 2015. # sphinx-quickstart on Fri Aug 21 05:43:30 2015.
@ -76,8 +75,8 @@ source_suffix = '.rst'
master_doc = 'index' master_doc = 'index'
# General information about the project. # General information about the project.
project = u'discord.py' project = 'discord.py'
copyright = u'2015-present, Rapptz' copyright = '2015-present, Rapptz'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
@ -160,7 +159,7 @@ resource_links = {
'discord': 'https://discord.gg/r3sSKJJ', 'discord': 'https://discord.gg/r3sSKJJ',
'issues': 'https://github.com/Rapptz/discord.py/issues', 'issues': 'https://github.com/Rapptz/discord.py/issues',
'discussions': 'https://github.com/Rapptz/discord.py/discussions', 'discussions': 'https://github.com/Rapptz/discord.py/discussions',
'examples': 'https://github.com/Rapptz/discord.py/tree/%s/examples' % branch, 'examples': f'https://github.com/Rapptz/discord.py/tree/{branch}/examples',
} }
# Theme options are theme-specific and customize the look and feel of a theme # Theme options are theme-specific and customize the look and feel of a theme
@ -283,8 +282,8 @@ latex_elements = {
# (source start file, target name, title, # (source start file, target name, title,
# author, documentclass [howto, manual, or own class]). # author, documentclass [howto, manual, or own class]).
latex_documents = [ latex_documents = [
('index', 'discord.py.tex', u'discord.py Documentation', ('index', 'discord.py.tex', 'discord.py Documentation',
u'Rapptz', 'manual'), 'Rapptz', 'manual'),
] ]
# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of
@ -313,8 +312,8 @@ latex_documents = [
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
('index', 'discord.py', u'discord.py Documentation', ('index', 'discord.py', 'discord.py Documentation',
[u'Rapptz'], 1) ['Rapptz'], 1)
] ]
# If true, show URL addresses after external links. # If true, show URL addresses after external links.
@ -327,8 +326,8 @@ man_pages = [
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
('index', 'discord.py', u'discord.py Documentation', ('index', 'discord.py', 'discord.py Documentation',
u'Rapptz', 'discord.py', 'One line description of project.', 'Rapptz', 'discord.py', 'One line description of project.',
'Miscellaneous'), 'Miscellaneous'),
] ]

View File

@ -61,7 +61,7 @@ async def cool(ctx):
In reality this just checks if a subcommand is being invoked. In reality this just checks if a subcommand is being invoked.
""" """
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
await ctx.send('No, {0.subcommand_passed} is not cool'.format(ctx)) await ctx.send(f'No, {ctx.subcommand_passed} is not cool')
@cool.command(name='bot') @cool.command(name='bot')
async def _bot(ctx): async def _bot(ctx):

View File

@ -70,9 +70,9 @@ class Music(commands.Cog):
"""Plays a file from the local filesystem""" """Plays a file from the local filesystem"""
source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(query)) source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(query))
ctx.voice_client.play(source, after=lambda e: print('Player error: %s' % e) if e else None) ctx.voice_client.play(source, after=lambda e: print(f'Player error: {e}') if e else None)
await ctx.send('Now playing: {}'.format(query)) await ctx.send(f'Now playing: {query}')
@commands.command() @commands.command()
async def yt(self, ctx, *, url): async def yt(self, ctx, *, url):
@ -80,9 +80,9 @@ class Music(commands.Cog):
async with ctx.typing(): async with ctx.typing():
player = await YTDLSource.from_url(url, loop=self.bot.loop) player = await YTDLSource.from_url(url, loop=self.bot.loop)
ctx.voice_client.play(player, after=lambda e: print('Player error: %s' % e) if e else None) ctx.voice_client.play(player, after=lambda e: print(f'Player error: {e}') if e else None)
await ctx.send('Now playing: {}'.format(player.title)) await ctx.send(f'Now playing: {player.title}')
@commands.command() @commands.command()
async def stream(self, ctx, *, url): async def stream(self, ctx, *, url):
@ -90,9 +90,9 @@ class Music(commands.Cog):
async with ctx.typing(): async with ctx.typing():
player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True) player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True)
ctx.voice_client.play(player, after=lambda e: print('Player error: %s' % e) if e else None) ctx.voice_client.play(player, after=lambda e: print(f'Player error: {e}') if e else None)
await ctx.send('Now playing: {}'.format(player.title)) await ctx.send(f'Now playing: {player.title}')
@commands.command() @commands.command()
async def volume(self, ctx, volume: int): async def volume(self, ctx, volume: int):
@ -102,7 +102,7 @@ class Music(commands.Cog):
return await ctx.send("Not connected to a voice channel.") return await ctx.send("Not connected to a voice channel.")
ctx.voice_client.source.volume = volume / 100 ctx.voice_client.source.volume = volume / 100
await ctx.send("Changed volume to {}%".format(volume)) await ctx.send(f"Changed volume to {volume}%")
@commands.command() @commands.command()
async def stop(self, ctx): async def stop(self, ctx):

View File

@ -29,7 +29,7 @@ async def userinfo(ctx: commands.Context, user: discord.User):
user_id = user.id user_id = user.id
username = user.name username = user.name
avatar = user.avatar_url avatar = user.avatar_url
await ctx.send('User found: {} -- {}\n{}'.format(user_id, username, avatar)) await ctx.send(f'User found: {user_id} -- {username}\n{avatar}')
@userinfo.error @userinfo.error
async def userinfo_error(ctx: commands.Context, error: commands.CommandError): async def userinfo_error(ctx: commands.Context, error: commands.CommandError):
@ -70,7 +70,7 @@ class ChannelOrMemberConverter(commands.Converter):
# If the value could not be converted we can raise an error # If the value could not be converted we can raise an error
# so our error handlers can deal with it in one place. # so our error handlers can deal with it in one place.
# The error has to be CommandError derived, so BadArgument works fine here. # The error has to be CommandError derived, so BadArgument works fine here.
raise commands.BadArgument('No Member or TextChannel could be converted from "{}"'.format(argument)) raise commands.BadArgument(f'No Member or TextChannel could be converted from "{argument}"')
@ -81,7 +81,7 @@ async def notify(ctx: commands.Context, target: ChannelOrMemberConverter):
# the `argument` parameter of the `ChannelOrMemberConverter.convert` method and # the `argument` parameter of the `ChannelOrMemberConverter.convert` method and
# the conversion will go through the process defined there. # the conversion will go through the process defined there.
await target.send('Hello, {}!'.format(target.name)) await target.send(f'Hello, {target.name}!')
@bot.command() @bot.command()
async def ignore(ctx: commands.Context, target: typing.Union[discord.Member, discord.TextChannel]): async def ignore(ctx: commands.Context, target: typing.Union[discord.Member, discord.TextChannel]):
@ -95,9 +95,9 @@ async def ignore(ctx: commands.Context, target: typing.Union[discord.Member, dis
# To check the resulting type, `isinstance` is used # To check the resulting type, `isinstance` is used
if isinstance(target, discord.Member): if isinstance(target, discord.Member):
await ctx.send('Member found: {}, adding them to the ignore list.'.format(target.mention)) await ctx.send(f'Member found: {target.mention}, adding them to the ignore list.')
elif isinstance(target, discord.TextChannel): # this could be an `else` but for completeness' sake. elif isinstance(target, discord.TextChannel): # this could be an `else` but for completeness' sake.
await ctx.send('Channel found: {}, adding it to the ignore list.'.format(target.mention)) await ctx.send(f'Channel found: {target.mention}, adding it to the ignore list.')
# Built-in type converters. # Built-in type converters.
@bot.command() @bot.command()

View File

@ -25,12 +25,12 @@ class MyClient(discord.Client):
try: try:
guess = await self.wait_for('message', check=is_correct, timeout=5.0) guess = await self.wait_for('message', check=is_correct, timeout=5.0)
except asyncio.TimeoutError: except asyncio.TimeoutError:
return await message.channel.send('Sorry, you took too long it was {}.'.format(answer)) return await message.channel.send(f'Sorry, you took too long it was {answer}.')
if int(guess.content) == answer: if int(guess.content) == answer:
await message.channel.send('You are right!') await message.channel.send('You are right!')
else: else:
await message.channel.send('Oops. It is actually {}.'.format(answer)) await message.channel.send(f'Oops. It is actually {answer}.')
client = MyClient() client = MyClient()
client.run('token') client.run('token')

View File

@ -12,7 +12,7 @@ class MyClient(discord.Client):
async def on_member_join(self, member): async def on_member_join(self, member):
guild = member.guild guild = member.guild
if guild.system_channel is not None: if guild.system_channel is not None:
to_send = 'Welcome {0.mention} to {1.name}!'.format(member, guild) to_send = f'Welcome {member.mention} to {guild.name}!'
await guild.system_channel.send(to_send) await guild.system_channel.send(to_send)