mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-08-23 11:46:18 +00:00
Fix type errors in all examples
This commit is contained in:
parent
7e2ca02fd1
commit
4f539b710f
@ -68,7 +68,7 @@ if TYPE_CHECKING:
|
||||
|
||||
SelectCallbackDecorator = Callable[[ItemCallbackType['S', BaseSelectT]], BaseSelectT]
|
||||
|
||||
S = TypeVar('S', bound='ActionRow', covariant=True)
|
||||
S = TypeVar('S', bound=Union['ActionRow', 'LayoutView'], covariant=True)
|
||||
V = TypeVar('V', bound='LayoutView', covariant=True)
|
||||
|
||||
__all__ = ('ActionRow',)
|
||||
|
@ -5,7 +5,6 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import logging.handlers
|
||||
import os
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
|
@ -8,6 +8,9 @@ MY_GUILD = discord.Object(id=0) # replace with your guild id
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self, *, intents: discord.Intents):
|
||||
super().__init__(intents=intents)
|
||||
# A CommandTree is a special type that holds all the application command
|
||||
@ -72,10 +75,17 @@ async def send(interaction: discord.Interaction, text_to_send: str):
|
||||
async def joined(interaction: discord.Interaction, member: Optional[discord.Member] = None):
|
||||
"""Says when a member joined."""
|
||||
# If no member is explicitly provided then we use the command user here
|
||||
member = member or interaction.user
|
||||
user = member or interaction.user
|
||||
|
||||
# Tell the type checker that this is a Member
|
||||
assert isinstance(user, discord.Member)
|
||||
|
||||
# The format_dt function formats the date time into a human readable representation in the official client
|
||||
await interaction.response.send_message(f'{member} joined {discord.utils.format_dt(member.joined_at)}')
|
||||
# Joined at can be None in very bizarre cases so just handle that as well
|
||||
if user.joined_at is None:
|
||||
await interaction.response.send_message(f'{user} has no join date.')
|
||||
else:
|
||||
await interaction.response.send_message(f'{user} joined {discord.utils.format_dt(user.joined_at)}')
|
||||
|
||||
|
||||
# A Context Menu command is an app command that can be run on a member or on a message by
|
||||
@ -86,6 +96,11 @@ async def joined(interaction: discord.Interaction, member: Optional[discord.Memb
|
||||
@client.tree.context_menu(name='Show Join Date')
|
||||
async def show_join_date(interaction: discord.Interaction, member: discord.Member):
|
||||
# The format_dt function formats the date time into a human readable representation in the official client
|
||||
# Joined at can be None in very bizarre cases so just handle that as well
|
||||
|
||||
if member.joined_at is None:
|
||||
await interaction.response.send_message(f'{member} has no join date.')
|
||||
else:
|
||||
await interaction.response.send_message(f'{member} joined at {discord.utils.format_dt(member.joined_at)}')
|
||||
|
||||
|
||||
@ -97,9 +112,18 @@ async def report_message(interaction: discord.Interaction, message: discord.Mess
|
||||
f'Thanks for reporting this message by {message.author.mention} to our moderators.', ephemeral=True
|
||||
)
|
||||
|
||||
# Make sure that we're inside a guild
|
||||
if interaction.guild is None:
|
||||
await interaction.response.send_message('This command can only be used in a server.', ephemeral=True)
|
||||
return
|
||||
|
||||
# Handle report by sending it into a log channel
|
||||
log_channel = interaction.guild.get_channel(0) # replace with your channel id
|
||||
|
||||
if log_channel is None or not isinstance(log_channel, discord.abc.Messageable):
|
||||
await interaction.response.send_message('Log channel not found or not messageable.', ephemeral=True)
|
||||
return
|
||||
|
||||
embed = discord.Embed(title='Reported Message')
|
||||
if message.content:
|
||||
embed.description = message.content
|
||||
|
@ -12,6 +12,9 @@ MY_GUILD = discord.Object(id=0) # replace with your guild id
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(intents=discord.Intents.default())
|
||||
self.tree = app_commands.CommandTree(self)
|
||||
|
@ -4,6 +4,9 @@ import discord
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@ -21,8 +24,11 @@ class MyClient(discord.Client):
|
||||
@tasks.loop(seconds=60) # task runs every 60 seconds
|
||||
async def my_background_task(self):
|
||||
channel = self.get_channel(1234567) # channel ID goes here
|
||||
# Tell the type checker that this is a messageable channel
|
||||
assert isinstance(channel, discord.abc.Messageable)
|
||||
|
||||
self.counter += 1
|
||||
await channel.send(self.counter)
|
||||
await channel.send(str(self.counter))
|
||||
|
||||
@my_background_task.before_loop
|
||||
async def before_my_task(self):
|
||||
|
@ -3,6 +3,9 @@ import asyncio
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@ -18,9 +21,13 @@ class MyClient(discord.Client):
|
||||
await self.wait_until_ready()
|
||||
counter = 0
|
||||
channel = self.get_channel(1234567) # channel ID goes here
|
||||
|
||||
# Tell the type checker that this is a messageable channel
|
||||
assert isinstance(channel, discord.abc.Messageable)
|
||||
|
||||
while not self.is_closed():
|
||||
counter += 1
|
||||
await channel.send(counter)
|
||||
await channel.send(str(counter))
|
||||
await asyncio.sleep(60) # task runs every 60 seconds
|
||||
|
||||
|
||||
|
@ -18,6 +18,9 @@ bot = commands.Bot(command_prefix='?', description=description, intents=intents)
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
# Tell the type checker that User is filled up at this point
|
||||
assert bot.user is not None
|
||||
|
||||
print(f'Logged in as {bot.user} (ID: {bot.user.id})')
|
||||
print('------')
|
||||
|
||||
@ -57,7 +60,11 @@ async def repeat(ctx, times: int, content='repeating...'):
|
||||
@bot.command()
|
||||
async def joined(ctx, member: discord.Member):
|
||||
"""Says when a member joined."""
|
||||
await ctx.send(f'{member.name} joined {discord.utils.format_dt(member.joined_at)}')
|
||||
# Joined at can be None in very bizarre cases so just handle that as well
|
||||
if member.joined_at is None:
|
||||
await ctx.send(f'{member} has no join date.')
|
||||
else:
|
||||
await ctx.send(f'{member} joined {discord.utils.format_dt(member.joined_at)}')
|
||||
|
||||
|
||||
@bot.group()
|
||||
|
@ -25,10 +25,6 @@ ytdl_format_options = {
|
||||
'source_address': '0.0.0.0', # bind to ipv4 since ipv6 addresses cause issues sometimes
|
||||
}
|
||||
|
||||
ffmpeg_options = {
|
||||
'options': '-vn',
|
||||
}
|
||||
|
||||
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
|
||||
|
||||
|
||||
@ -51,7 +47,7 @@ class YTDLSource(discord.PCMVolumeTransformer):
|
||||
data = data['entries'][0]
|
||||
|
||||
filename = data['url'] if stream else ytdl.prepare_filename(data)
|
||||
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
|
||||
return cls(discord.FFmpegPCMAudio(filename, options='-vn'), data=data)
|
||||
|
||||
|
||||
class Music(commands.Cog):
|
||||
@ -138,6 +134,9 @@ bot = commands.Bot(
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
# Tell the type checker that User is filled up at this point
|
||||
assert bot.user is not None
|
||||
|
||||
print(f'Logged in as {bot.user} (ID: {bot.user.id})')
|
||||
print('------')
|
||||
|
||||
|
@ -83,8 +83,14 @@ class ChannelOrMemberConverter(commands.Converter):
|
||||
raise commands.BadArgument(f'No Member or TextChannel could be converted from "{argument}"')
|
||||
|
||||
|
||||
# Make it so the converter is friendly to type checkers
|
||||
# The first parameter of typing.Annotated is the type we tell the type checker
|
||||
# The second parameter is what converter the library uses
|
||||
ChannelOrMember = typing.Annotated[typing.Union[discord.Member, discord.TextChannel], ChannelOrMemberConverter]
|
||||
|
||||
|
||||
@bot.command()
|
||||
async def notify(ctx: commands.Context, target: ChannelOrMemberConverter):
|
||||
async def notify(ctx: commands.Context, target: ChannelOrMember):
|
||||
# This command signature utilises the custom converter written above
|
||||
# What will happen during command invocation is that the `target` above will be passed to
|
||||
# the `argument` parameter of the `ChannelOrMemberConverter.convert` method and
|
||||
@ -118,8 +124,8 @@ async def multiply(ctx: commands.Context, number: int, maybe: bool):
|
||||
# See: https://discordpy.readthedocs.io/en/latest/ext/commands/commands.html#bool
|
||||
|
||||
if maybe is True:
|
||||
return await ctx.send(number * 2)
|
||||
await ctx.send(number * 5)
|
||||
return await ctx.send(str(number * 2))
|
||||
await ctx.send(str(number * 5))
|
||||
|
||||
|
||||
bot.run('token')
|
||||
|
@ -4,6 +4,9 @@ import discord
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
async def on_ready(self):
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})')
|
||||
print('------')
|
||||
|
@ -5,6 +5,9 @@ import asyncio
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
async def on_ready(self):
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})')
|
||||
print('------')
|
||||
|
@ -6,6 +6,9 @@ import asyncio
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
async def on_ready(self):
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})')
|
||||
print('------')
|
||||
|
@ -9,6 +9,9 @@ TEST_GUILD = discord.Object(0)
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self) -> None:
|
||||
# Just default intents and a `discord.Client` instance
|
||||
# We don't need a `commands.Bot` instance because we are not
|
||||
|
@ -4,6 +4,9 @@ import discord
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
async def on_ready(self):
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})')
|
||||
print('------')
|
||||
|
@ -4,6 +4,9 @@ import discord
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@ -36,6 +39,9 @@ class MyClient(discord.Client):
|
||||
# Make sure the role still exists and is valid.
|
||||
return
|
||||
|
||||
# Tell the type checker that RawReactionActionEvent.member is not none during REACTION_ADD
|
||||
assert payload.member is not None
|
||||
|
||||
try:
|
||||
# Finally, add the role.
|
||||
await payload.member.add_roles(role)
|
||||
|
@ -4,6 +4,9 @@ import discord
|
||||
|
||||
|
||||
class MyClient(discord.Client):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
async def on_ready(self):
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})')
|
||||
print('------')
|
||||
|
@ -52,6 +52,9 @@ async def text(ctx: commands.Context, name: str, *objects: typing.Union[discord.
|
||||
|
||||
overwrites = create_overwrites(ctx, *objects)
|
||||
|
||||
# Tell the type checker that our Guild is not None
|
||||
assert ctx.guild is not None
|
||||
|
||||
await ctx.guild.create_text_channel(
|
||||
name,
|
||||
overwrites=overwrites,
|
||||
@ -69,6 +72,8 @@ async def voice(ctx: commands.Context, name: str, *objects: typing.Union[discord
|
||||
|
||||
overwrites = create_overwrites(ctx, *objects)
|
||||
|
||||
assert ctx.guild is not None
|
||||
|
||||
await ctx.guild.create_voice_channel(
|
||||
name,
|
||||
overwrites=overwrites,
|
||||
@ -86,6 +91,8 @@ async def emoji(ctx: commands.Context, emoji: discord.PartialEmoji, *roles: disc
|
||||
# fetch the emoji asset and read it as bytes.
|
||||
emoji_bytes = await emoji.read()
|
||||
|
||||
assert ctx.guild is not None
|
||||
|
||||
# the key parameter here is `roles`, which controls
|
||||
# what roles are able to use the emoji.
|
||||
await ctx.guild.create_custom_emoji(
|
||||
|
@ -6,6 +6,8 @@ import discord
|
||||
|
||||
|
||||
class Bot(commands.Bot):
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
@ -6,6 +6,9 @@ import discord
|
||||
|
||||
|
||||
class CounterBot(commands.Bot):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
@ -38,6 +38,9 @@ class DropdownView(discord.ui.View):
|
||||
|
||||
|
||||
class Bot(commands.Bot):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
@ -70,6 +70,9 @@ class DynamicCounter(
|
||||
|
||||
|
||||
class DynamicCounterBot(commands.Bot):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
super().__init__(command_prefix=commands.when_mentioned, intents=intents)
|
||||
|
@ -6,6 +6,9 @@ import discord
|
||||
|
||||
|
||||
class EphemeralCounterBot(commands.Bot):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
@ -6,6 +6,9 @@ import discord
|
||||
|
||||
|
||||
class Bot(commands.Bot):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
@ -7,6 +7,9 @@ from urllib.parse import quote_plus
|
||||
|
||||
|
||||
class GoogleBot(commands.Bot):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
@ -64,6 +64,9 @@ class DynamicButton(discord.ui.DynamicItem[discord.ui.Button], template=r'button
|
||||
|
||||
|
||||
class PersistentViewBot(commands.Bot):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
@ -121,6 +121,9 @@ class TicTacToe(discord.ui.View):
|
||||
|
||||
|
||||
class TicTacToeBot(commands.Bot):
|
||||
# Suppress error on the User attribute being None since it fills up later
|
||||
user: discord.ClientUser
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
Loading…
x
Reference in New Issue
Block a user