Pycord-Development / pycord

Pycord is a modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python
https://docs.pycord.dev
MIT License
2.7k stars 458 forks source link

Running examples/audio_recording.py with @bot.command but AttributeError occurs -- 'NoneType' object has no attribute 'expandtabs' #2558

Open Johnny850807 opened 3 weeks ago

Johnny850807 commented 3 weeks ago

Summary

Running examples/audio_recording.py with @bot.command but AttributeError occurs -- 'NoneType' object has no attribute 'expandtabs'

Reproduction Steps

Run examples/audio_recording.py

Minimal Reproducible Code

Run examples/audio_recording.py as below:

import os
from enum import Enum

from discord.ext import commands
from dotenv import load_dotenv

import discord

load_dotenv()

bot = discord.Bot(intents=discord.Intents.all())
connections = {}

class Sinks(Enum):
    mp3 = discord.sinks.MP3Sink()
    wav = discord.sinks.WaveSink()
    pcm = discord.sinks.PCMSink()
    ogg = discord.sinks.OGGSink()
    mka = discord.sinks.MKASink()
    mkv = discord.sinks.MKVSink()
    mp4 = discord.sinks.MP4Sink()
    m4a = discord.sinks.M4ASink()

async def finished_callback(sink, channel: discord.TextChannel, *args):
    recorded_users = [f"<@{user_id}>" for user_id, audio in sink.audio_data.items()]
    await sink.vc.disconnect()
    files = [
        discord.File(audio.file, f"{user_id}.{sink.encoding}")
        for user_id, audio in sink.audio_data.items()
    ]
    await channel.send(
        f"Finished! Recorded audio for {', '.join(recorded_users)}.", files=files
    )

@bot.command()
async def start(ctx: discord.ApplicationContext, sink: Sinks):
    """Record your voice!"""
    voice = ctx.author.voice

    if not voice:
        return await ctx.respond("You're not in a vc right now")

    vc = await voice.channel.connect()
    connections.update({ctx.guild.id: vc})

    vc.start_recording(
        sink.value,
        finished_callback,
        ctx.channel,
    )

    await ctx.respond("The recording has started!")

@bot.command()
async def stop(ctx: discord.ApplicationContext):
    """Stop recording."""
    if ctx.guild.id in connections:
        vc = connections[ctx.guild.id]
        vc.stop_recording()
        del connections[ctx.guild.id]
        await ctx.delete()
    else:
        await ctx.respond("Not recording in this guild.")

bot.run(os.getenv('DISCORD_BOT_TOKEN'))

Expected Results

  1. Slash command registered
  2. No error, the bot is running

Actual Results

Traceback (most recent call last):
  File "/Users/johnnypan/Projects/WSA-Utopia-Discord-Bot-AI-Agent/speech/app/services/discord/record_voice.py", line 38, in <module>
    @bot.command()
     ^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/discord/bot.py", line 953, in decorator
    result = command(**kwargs)(func)
             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/discord/commands/core.py", line 2026, in decorator
    return cls(func, **attrs)
           ^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/discord/commands/core.py", line 762, in __init__
    self._validate_parameters()
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/discord/commands/core.py", line 780, in _validate_parameters
    self.options = self._parse_options(params)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/discord/commands/core.py", line 838, in _parse_options
    option = Option(option)
             ^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/discord/commands/options.py", line 202, in __init__
    description = inspect.cleandoc(input_type.__doc__)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/inspect.py", line 869, in cleandoc
    lines = doc.expandtabs().split('\n')
            ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'expandtabs'

Intents

all

System Information

macos py-cord==2.6.0 python 3.11

Checklist

Additional Context

What happened? Please help!

NeloBlivion commented 3 weeks ago

...Sorry, this can be fixed by giving the Sinks class a docstring

class Sinks(Enum):
+   """some description"""
    mp3 = discord.sinks.MP3Sink()
    ...