V2.0への移行

v1.0と比較して、v2.0は主に開発のしやすさとAPIの対応に関連する破壊的変更があります。変更はコードすべての書き換えを必要とするほどの大規模なものではありませんが、少し書き換えが必要になる変更は多くあります。

Pythonのバージョンの変更

開発を容易にするために、セキュリティ関連の更新を維持するために、また新しい機能を使用するために v2.0はPython 3.7以前をサポートしなくなりました

ユーザーアカウント(セルフボット)のサポートの削除

ユーザートークンを用いてのログインはDiscordの 利用規約 に反しているため、ユーザーのみのエンドポイントに対するサポートはすべて削除されました。

以下の機能は削除されました。

  • Client.login()Client.start()bot パラメータ

  • Client.change_presence()afk パラメータ

  • ClientUser.edit()password, new_password, email, house パラメータ

  • CallMessage モデル

  • GroupCall モデル

  • Profile モデル

  • Relationship モデル

  • 列挙型 RelationshipType

  • 列挙型 HypeSquadHouse

  • 列挙型 PremiumType

  • 列挙型 UserContentFilter

  • 列挙型 FriendFlags

  • 列挙型 Theme

  • on_relationship_add イベント

  • on_relationship_remove イベント

  • on_relationship_update イベント

  • Client.fetch_user_profile メソッド

  • ClientUser.create_group メソッド

  • ClientUser.edit_settings メソッド

  • ClientUser.get_relationship メソッド

  • GroupChannel.add_recipients メソッド

  • GroupChannel.remove_recipients メソッド

  • GroupChannel.edit メソッド

  • Guild.ack メソッド

  • Message.ack メソッド

  • User.block メソッド

  • User.is_blocked メソッド

  • User.is_friend メソッド

  • User.profile メソッド

  • User.remove_friend メソッド

  • User.send_friend_request メソッド

  • User.unblock メソッド

  • ClientUser.blocked 属性

  • ClientUser.email 属性

  • ClientUser.friends 属性

  • ClientUser.premium 属性

  • ClientUser.premium_type 属性

  • ClientUser.relationships 属性

  • Message.call 属性

  • User.mutual_friends 属性

  • User.relationship 属性

asyncio イベントループの変更

Python 3.7で、自動的に非同期のイベントループを作成し破壊する asyncio.run() ヘルパー関数が導入されました。

これをサポートするために、discord.pyの asyncio のイベントループの扱い方が変更されました。

このため、 Client.run() を使用せずに、自分で非同期ループを作成して他の非同期のコードを準備できるようになります。

簡単な例:

client = discord.Client()

async def main():
    # do other async things
    await my_async_function()

    # start the client
    async with client:
        await client.start(TOKEN)

asyncio.run(main())

Client クラスに setup_hook() メソッドが追加されました。このメソッドはログイン後、Discordゲートウェイに接続前に呼び出されます。

これは、非同期コンテキストで様々なボットの機能を準備するために使用することを意図しています。

setup_hook()Client をサブクラス化して定義できます。

簡単な例:

class MyClient(discord.Client):
    async def setup_hook(self):
        print('This is asynchronous!')

client = MyClient()
client.run(TOKEN)

この変更により、 Client のコンストラクタは connectorloop パラメータを受け付けなくなりました。

これらとともに、コマンド拡張機能のエクステンションやコグの読み込みと読み込み解除にも変更がありました。 エクステンションとコグの読み込み・解除の非同期化 を参照してください。

インテントの必須化

以前のバージョンでは、intents キーワード引数は省略可能で、デフォルトで Intents.default() に指定されていました。 ユーザーにインテントを教え、より明示的にするために、このパラメータを必須にしました。

例:

# before
client = discord.Client()

# after
intents = discord.Intents.default()
client = discord.Client(intents=intents)

この変更は、 Clientすべての サブクラスに適用されます。

抽象基底クラスの変更

抽象基底クラスabc.ABCMeta を継承していましたが、 typing.Protocol を継承するようになりました。

これにより、これらのクラスが使用する基幹メタクラスが変更されますが、一般的にこの変更はユーザーに対して完全に透過的であるべきです。

すべてのクラスは runtime-checkable プロトコルであるか明示的に継承されているので、 isinstance()issubclass() の使用には影響を与えません。

以下のクラスは runtime-checkableProtocol に変更されました:

以下のクラスは Protocol のサブクラスに変更されました:

以下のクラスは abc.ABCMeta の代わりにデフォルトのメタクラスを使用するよう変更されました:

datetime オブジェクトはUTC-Awareに

ライブラリ内でのnaiveな datetime.datetime オブジェクトはUTCタイムゾーンを使用したawareなものへ置き換えられました。naiveな datetime オブジェクトを受け取るメソッドは、 timezone-awareなオブジェクトも受け取るようになりました。 datetime のメソッドと同じように動作するよう、このライブラリのメソッドは naiveな datetime オブジェクトがローカルタイムを表すものと仮定するようになりました。(いくつかのメソッドは naiveな datetime を受け入れないことに注意してください。そのような例外は下に記載してあります。)

naiveな datetime が多くのメソッドからローカルタイムを表すものとして扱われるため、従来の動作では使用時にプログラムのエラーを引き起こす可能性が高かったのです。

移行を用意にするため、 utils.utcnow() ヘルパー関数が追加されました。

警告

datetime.datetime.utcnow() を使用するとnaiveな UTC datetime オブジェクトが返されるため、問題が発生します。

簡単な例:

# before
week_ago = datetime.datetime.utcnow() - datetime.timedelta(days=7)
if member.created_at > week_ago:
    print(f'Member account {member} was created less than a week ago!')

# after
# The new helper function can be used here:
week_ago = discord.utils.utcnow() - datetime.timedelta(days=7)
# ...or the equivalent result can be achieved with datetime.datetime.now():
week_ago = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=7)
if member.created_at > week_ago:
    print(f'Member account {member} was created less than a week ago!')

以下はnaiveな datetime から UTC-awareなものへ変更されました:

以下はawareな datetime を受け入れ、渡された datetime がnaiveであればそれをローカルタイムを表すものと仮定するようになりました:

今のところ、このライブラリにはnaiveな datetime.datetime オブジェクトを受け入れない場所は1つしかありません:

  • Member.edit()timed_out_until 引数

    これはユーザーがギルドメンバーに誤ったタイムアウトを適用することを防ぐために行われました。

主なWebhookの変更

Webhookのサポートは、タイピングとレート制限でより良い動作をするように書き換えられています。

その結果、同期的な機能は個別のクラスへと分割されました。

非同期的なWebhookの簡単な例:

# before
async with aiohttp.ClientSession() as session:
    webhook = discord.Webhook.from_url('url-here', adapter=discord.AsyncWebhookAdapter(session))
    await webhook.send('Hello World', username='Foo')

# after
async with aiohttp.ClientSession() as session:
    webhook = discord.Webhook.from_url('url-here', session=session)
    await webhook.send('Hello World', username='Foo')

同期的なWebhookの簡単な例:

# before
webhook = discord.Webhook.partial(123456, 'token-here', adapter=discord.RequestsWebhookAdapter())
webhook.send('Hello World', username='Foo')

# after
webhook = discord.SyncWebhook.partial(123456, 'token-here')
webhook.send('Hello World', username='Foo')

以下の破壊的変更が行われました。

  • WebhookWebhookMessage の同期的な機能が WebhookWebhookMessage に分離されました。

  • WebhookAdapter クラスが削除され、それに基づくインターフェイス( WebhookAdapterRequestsWebhookAdapter )は実装の詳細とみなされるようになりました。これらに依存してはいけません。

  • Webhook.send() / SyncWebhook.send()execute エイリアスが削除されました。

Assetのリデザインと変更

Asset オブジェクトにCDNアセットに関連する全てのメソッドと属性が含まれるようになりました。

これはアセット関連の属性とメソッドを持つ全てのモデルがこの新しいデザインを使用するように変えられたことを意味します。例として、( Asset 型の) Guild.icon がどのように変更されたかを以下に示します:

これに加えて、 EmojiPartialEmojiAsset のようなインターフェイスを共有するようになりました。

  • Emoji.urlstr 型になりました。

  • Emoji.url_as は削除されました。

  • Emoji.url.readEmoji.read() に置き換えられました。

  • Emoji.url.saveEmoji.save() に置き換えられました。

Asset は実際に存在するCDNアセットを常に表すようになりました。 つまり:

  • Assetstr(x) は空の文字列を返せなくなりました。

  • Assetbool(x)False を返せなくなりました。

  • Optionalな Asset を含む属性は None になることがあります。

以下がこの影響を受けました:

スレッドのサポート

スレッドをサポートする新しいAPIゲートウェイバージョンを使用するためにv2.0が更新され、その結果いくつかの破壊的変更が必要になりました。最も注目すべきは、 ギルド内で送信されるメッセージは TextChannel に加えて Thread でも送信できる点です。

テキストチャンネルとスレッドの主な違いは以下の通りです:

  • スレッドには固有の権限はありません。親チャンネルの権限を継承します。

    • これはスレッドにこれらの属性がないことを意味します:

      • changed_roles

      • overwrites

      • permissions_synced

    注釈

    テキストチャンネルにはスレッド専用の権限がいくつかあります:

  • スレッドは固有の年齢制限ステータスを持っていません。親チャンネルを継承します。

    • これは Threadnsfw 属性がないことを意味します。

  • スレッドには固有のトピックがありません。

    • これは Threadtopic 属性がないことを意味します。

  • スレッドはチャンネルリストに固有の位置を持っていません。

    • これは Threadposition 属性がないことを意味します。

  • 2022年1月10日より前に作成されたスレッドの Thread.created_atNone です。

  • Thread.members は List[Member] ではなく、 List[ThreadMember] 型です。

    • ほとんどの場合このデータは提供されず、 Thread.fetch_members() の呼び出しが必要になります。

便宜上、 Thread には親チャンネルに関する情報を返す一連のプロパティとメソッドがあります。

  • Thread.category

  • Thread.category_id

  • Thread.is_news()

  • Thread.is_nsfw()

  • Thread.permissions_for()

    • これは親チャンネルの権限を出力し、メンバーがなにかできるかどうかを判断するときに異なる権限をチェックする必要があるかもしれないことに注意してください。

      次にいくつかの注目すべき例を示します:

      • ギルドメンバーは send_messages 権限を持っている場合にテキストチャンネルでメッセージを送信できます。

        ギルドメンバーは以下の場合に公開スレッドでメッセージを送信できます:
        ギルドメンバーは以下の場合にプライベートスレッドでメッセージを送信できます:
        • 親チャンネルで send_messages_in_threads 権限がある場合。

        • すでにスレッドのメンバーであるか、 親チャンネルで manage_threads 権限を持っている場合。

        • スレッドが locked でない場合。

      • ギルドメンバーは manage_channels 権限を持っている場合テキストチャンネルを編集できます。

        ギルドメンバーは、親チャンネルで manage_threads 権限がある場合スレッドを編集できます。

        注釈

        スレッドの owner は(ロックされていない)スレッドをアーカイブし、 nameauto_archive_durationmanage_threads 権限なしで編集できます。

      • ギルドメンバーは、以下の場合にテキストチャンネル内のメッセージに絵文字でリアクションすることができます:
        • read_message_history 権限を持っているとき。

        • add_reactions 権限を持っているか、またはメッセージにすでにその絵文字のリアクションがついているとき。

        ギルドメンバーは以下の場合に公開スレッドのメッセージに絵文字でリアクションすることができます:
        • read_message_history 権限を親チャンネルで持っているとき。

        • 親チャンネルで add_reactions 権限を持っているか、メッセージにすでにその絵文字のリアクションがついているとき。

        • スレッドが archived でないとき。ギルドメンバーはメッセージにリアクションするためにスレッドを( locked でない場合) アーカイブ解除することができます。

        ギルドメンバーは以下の場合にプライベートスレッドのメッセージにリアクションをつけることができます:
        • read_message_history 権限を親チャンネルで持っているとき。

        • 親チャンネルで add_reactions 権限を持っているか、メッセージにすでにその絵文字のリアクションがついているとき。

        • すでにスレッドのメンバーであるか、 親チャンネルで manage_threads 権限を持っている場合。

        • スレッドが archived でないとき。ギルドメンバーはメッセージにリアクションするためにスレッドを( locked でない場合) アーカイブ解除することができます。

以下のように変更されました:

編集時の置換を廃止

モデル内のデータを直接置き換えて編集していたメソッドのほとんどが、そうしないよう更新されました。代わりに、こうしたメソッドは更新された新しいモデルを返すように変更されました。これは、置換編集とモデル更新のゲートウェイイベントの競合を解消するために行われました。詳細については、 GH-4098 を確認してください。

簡単な例:

# before
await member.edit(nick='new nick')
await member.send(f'Your new nick is {member.nick}')

# after
updated_member = await member.edit(nick='new nick')
await member.send(f'Your new nick is {updated_member.nick}')

以下のように変更されました。

スタンプの変更

Discordがスタンプの動作を変更したため、スタンプのサポートが見直されました。

以下の破壊的変更が行われました。

連携サービスの変更

新しいインテグレーションの種類をサポートするため、インテグレーションのサポートがやり直されました。

以下の破壊的変更が行われました。

プレゼンスのアップデートが個別のイベントに変更

プレゼンスのアップデート (メンバーのステータスとアクティビティの変化) は、 on_presence_update() という別のイベントで扱われるようになりました。 on_member_update() イベントは、今後はメンバーのアップデート (ニックネーム、ロール、ペンディング状態の変化) の場合のみ呼び出されます。

APIからすると、これらは個別のイベントなので、この変更はAPIとライブラリーとの一致度を改善します。プレゼンスのアップデートは多くの場合扱われるイベントの90%を占めているので、分割は、メンバーアップデートのみ必要なリスナーに利益をもたらすはずです。

簡単な例:

# before
@client.event
async def on_member_update(self, before, after):
    if before.nick != after.nick:
        await nick_changed(before, after)
    if before.status != after.status:
        await status_changed(before, after)

# after
@client.event
async def on_member_update(self, before, after):
    if before.nick != after.nick:
        await nick_changed(before, after)

@client.event
async def on_presence_update(self, before, after):
    if before.status != after.status:
        await status_changed(before, after)

カスタム AsyncIterator からの移行

v1.0の非同期イテレータは、AsyncIterator というクラスを使用して実装されました。 v2.0は代わりに、ユーティリティメソッドを追加しない通常の非同期イテレータを提供します

つまり、以下のユーティリティメソッドを使用することはできなくなります。

  • AsyncIterator.next()

    明示的な async for ループの使用が一般的に推奨されます。

    # before
    it = channel.history()
    while True:
        try:
            message = await self.next()
        except discord.NoMoreItems:
            break
        print(f'Found message with ID {message.id}')
    
    # after
    async for message in channel.history():
        print(f'Found message with ID {message.id}')
    

    ループなしにイテレータから次のアイテムを取得する必要がある場合には、 anext() (Python 3.10で追加) か __anext__() を代わりに使用できます。

    # before
    it = channel.history()
    first = await it.next()
    if first.content == 'do not iterate':
        return
    async for message in it:
        ...
    
    # after
    it = channel.history()
    first = await anext(it)  # await it.__anext__() on Python<3.10
    if first.content == 'do not iterate':
        return
    async for message in it:
        ...
    
  • AsyncIterator.get()

    # before
    msg = await channel.history().get(author__name='Dave')
    
    # after
    msg = await discord.utils.get(channel.history(), author__name='Dave')
    
  • AsyncIterator.find()

    def predicate(event):
        return event.reason is not None
    
    # before
    event = await guild.audit_logs().find(predicate)
    
    # after
    event = await discord.utils.find(predicate, guild.audit_logs())
    
  • AsyncIterator.flatten()

    # before
    users = await reaction.users().flatten()
    
    # after
    users = [user async for user in reaction.users()]
    
  • AsyncIterator.chunk()

    # before
    async for leader, *users in reaction.users().chunk(3):
        ...
    
    # after
    async for leader, *users in discord.utils.as_chunks(reaction.users(), 3):
        ...
    
  • AsyncIterator.map()

    # before
    content_of_messages = []
    async for content in channel.history().map(lambda m: m.content):
        content_of_messages.append(content)
    
    # after
    content_of_messages = [message.content async for message in channel.history()]
    
  • AsyncIterator.filter()

    def predicate(message):
        return not message.author.bot
    
    # before
    user_messages = []
    async for message in channel.history().filter(lambda m: not m.author.bot):
        user_messages.append(message)
    
    # after
    user_messages = [message async for message in channel.history() if not m.author.bot]
    

この移行を容易にするために、次の変更が行われました:

以下のメソッドの戻り値の型が asynchronous iterator に変更されました。

変更によって asynchronous iterator に対して anext()__anext__() を呼び出すと StopAsyncIteration が発生するようになったため、 NoMoreItems 例外は削除されました。

特定のリストを遅延評価シーケンスに変更

リストの長さを計算するときのパフォーマンスを向上させるために、特定の属性が list ではなくシーケンスを返すように変更されました。

シーケンスは list と似ていますが読み込み専用です。これをリストに戻すには返されたシーケンスに対し list を呼び出せばよいです。

以下のプロパティは、リストの代わりにシーケンスを返すように変更されました:

list.append のようにシーケンスを変更しない限り、この変更は影響を与えないでしょう。

埋め込みの変更

以前は、埋め込みは属性が空であったり、属性の表示を除去することを示すのに、特別なセンチネルを使用していました。この Embed.Empty センチネルはDiscordの埋め込みの設計が漠然とし変化していた状態にあったときにできました。その後、埋め込みの設計は安定化したため、このセンチネルは過去のものとされてきました。

このため、 Embed.Empty は、 None に置き換えられ削除されました。

さらに、 Embed.__eq__ が実装されたため、埋め込みがハッシュ化できなくなりました。 (例えば、集合型や辞書型キーで使用できなくなりました)

# before
embed = discord.Embed(title='foo')
embed.title = discord.Embed.Empty
embed == embed.copy() # False

# after
embed = discord.Embed(title='foo')
embed.title = None
embed == embed.copy() # True
{embed, embed} # Raises TypeError

InvalidArgument 例外の削除

カスタム例外 InvalidArgument は削除され、これを発生させていた関数やメソッドは、代わりに TypeErrorValueError を発生させるようになりました。

以下のメソッドが変更されました:

ログの変更

ライブラリは Client.run() を使用した場合にデフォルトの logging 構成を提供するようになりました。無効化するには、 log_handler キーワード引数に None を渡してください。ライブラリがデフォルトでログ設定を提供するようになったため、次のメソッドは sys.stderr に出力せず、ロガーを使用するように変更されました。

詳しくは、 ログの設定 を確認してください。

ボイスチャンネル チャット

ボイスチャンネル チャット機能に対応するために、いくつかの変更が行われました:

将来的には、Discordが実装する際に、 StageChannel でも同様の変更が行われるかもしれません。

StoreChannel の削除

DiscordのAPIは、 2022年3月10日 をもって、ストアチャンネルを削除しました。そのため、ライブラリもそれに対するサポートを削除しました。

これにより、以下が削除されます。

  • StoreChannel

  • commands.StoreChannelConverter

  • ChannelType.store

Guild.bans エンドポイントの変更

Discord APIの破壊的変更のため、 Guild.bans() はギルドのすべてのBANのリストを返さなくなり、代わりに非同期イテレータを用いてページ化されるようになりました。

# before

bans = await guild.bans()

# after
async for ban in guild.bans(limit=1000):
    ...

フラグのクラスにカスタムの bool() 実装を追加

ライブラリユーザーがフラグクラスのインスタンスに何らかのフラグが立っているかどうかを確認しやすくするために、 bool を使用するとフラグが最低一個有効の場合に True を返すようにしました。

つまり、 真偽値の文脈 (例えば if obj:) で次のクラスのインスタンスを評価するとき、 True が返されない可能性があります:

関数シグネチャの変更

以下のメソッドの引数は全て位置限定になりました:

以下の引数が位置限定になりました:

以下はキーワード限定になりました:

ライブラリは関数/メソッドの引数のデフォルト値として None を使用することが少なくなりました。

その結果、 これらの引数は None にはならなくなりました:

以下の引数で受け取られる型が変更されました:

属性の型の変更

以下のように変更されました:

削除

以下の非推奨の機能は削除されました。

  • Client.request_offline_members

  • AutoShardedClient.request_offline_members

  • Client.logout

  • Client コンストラクタの fetch_offline_members パラメータ

    • 代わりに chunk_guild_at_startup を使用してください。

  • Permissions.use_slash_commandsPermissionOverwrite.use_slash_commands

以下の機能は削除されました。

  • MemberCacheFlags.online

    • 置換先はありません。現在のAPIバージョンは、このために必要な十分なデータを提供しません。

  • AppInfo.summary

    • この項目を置き換えることはできません。現在の API バージョンではこの項目は提供されません。

  • User.permissions_inMember.permissions_in

  • Client コンストラクタの guild_subscriptions パラメータ

    • 現在の API バージョンはこの機能を提供していません。代わりに intents パラメーターを使用してください。

  • VerificationLevel のエイリアス

  • StageChannel.edit()topic パラメータ

  • Reaction.custom_emoji

  • AuditLogDiff.region

  • Guild.region

  • VoiceRegion

    • これはDiscordより非推奨とされていて、また追加されたペースが速いため多くの場合で反映するのが遅れていました。

  • Client.create_guild()region パラメータ

  • Template.create_guild()region パラメータ

  • Guild.edit()region パラメータ

  • on_private_channel_create イベント

    • Discord APIは、DMにはチャンネル作成イベントを送信しないようになりました。

  • on_private_channel_delete イベント

    • Discord APIは、DMにはチャンネル作成イベントを送信しないようになりました。

  • 文書化されていないプライベートな on_socket_response イベント

    • 代わりに、より新しくドキュメント化された on_socket_event_type() イベントを使用することを検討してください。

  • abc.Messageable.trigger_typing

その他の変更点

以下のように変更されました:

  • Clientenable_debug_events が設定されている場合にのみ on_socket_raw_receive() が呼び出されるようになりました。

  • on_socket_raw_receive()完全な メッセージを受信して解凍した後にのみ呼び出されるようになりました。渡された msg パラメータは 常に str になりました。

  • Clientenable_debug_events が設定されている場合にのみ on_socket_raw_send() が呼び出されるようになりました。

  • 文書化された Guild.fetch_channels() の戻り値の型は Sequence[abc.GuildChannel] に変更されました。

  • utils.resolve_invite()ResolvedInvite クラスを返すようになりました。

  • utils.oauth_url() のスコープが与えられていない場合の初期値が bot から botapplications.commands に変更されました。

  • abc.Messageable.typing() は、通常の(非同期でない)コンテキストマネージャーとしては使用できなくなりました。

  • Intents.emojisIntents.emojis_and_stickers のエイリアスになりました。

    これは、このクラスのインスタンス内の (name, value) ペアをイテレートするコードに影響を与える可能性があります。

    # before
    friendly_names = {
        ...,
        'emojis': 'Emojis Intent',
        ...,
    }
    for name, value in discord.Intents.all():
        print(f'{friendly_names[name]}: {value}')
    
    # after
    friendly_names = {
        ...,
        'emojis_and_stickers': 'Emojis Intent',
        ...,
    }
    for name, value in discord.Intents.all():
        print(f'{friendly_names[name]}: {value}')
    
  • created_atabc.Snowflake の一部ではなくなりました。

    既存のすべてのクラスは、この属性を保持します。ただ、このプロトコルの一部ではなくなりました。これは、DiscordがいくつかのモデルのID(snowflake)を他のモデルで再利用するために行われました。例えば、あるメッセージから Thread が作成された場合、その Thread.id はそのメッセージの ID と同じで、スレッドの作成時刻に関する情報は含まれず、 Thread.created_at に基づいて作成することはできません。

  • Embed の bool 実装では、埋め込みに何らかのデータが設定されていれば True が返されるようになりました。

  • Emoji.edit()roles 引数なしで呼び出したときに、絵文字が全員に利用できるようにならなくなりました。

    • 絵文字を誰でも利用できるようにするには、空のリストを roles に渡してください。

  • 古い Colour.blurpleColour.og_blurple に改名されました。

    • Colour.blurple は別の色を参照するようになりました。

  • メッセージが返信である場合、 Message.typeMessageType.reply に設定されるようになりました。

    • これは、現在のDiscordAPIバージョンでの動作の違いによって引き起こされます。

  • Message.edit()allowed_mentions パラメータで渡されたオブジェクトを Client.allowed_mentions と合わせるようになりました。このパラメータが指定されていない場合は、代わりに Client.allowed_mentions で指定されたデフォルト値が使用されます。

  • Permissions.stage_moderator()Permissions.manage_channels 権限が含まれるようになり、 Permissions.request_to_speak 権限が含まれなくなりました。

  • File.filenameNone になることはなくなりました。以前そうなった場合ではファイル名は 'untitled' になります。

  • Message.application が生のAPIペイロードの dict ではなくなり、 MessageApplication インスタンスを返すようになりました。

VoiceProtocol.connect() のシグネチャ変更

VoiceProtocol.connect() に、 self_deafself_mute キーワード引数が渡されるようになりました。これはクライアントがボイスチャットに参加する際にスピーカーミュートし、またはミュートすべきかを示します。

コマンド拡張の変更

エクステンションとコグの読み込み・解除の非同期化

asyncio の変更 に伴い、エクステンションとコグの読み込みや読み込み解除が非同期処理となりました。

これに対応するために、以下のように変更が行われました:

エクステンションのセットアップの簡単な例:

# before
def setup(bot):
    bot.add_cog(MyCog(bot))

# after
async def setup(bot):
    await bot.add_cog(MyCog(bot))

エクステンションの読み込みの簡単な例:

# before
bot.load_extension('my_extension')

# after using setup_hook
class MyBot(commands.Bot):
    async def setup_hook(self):
        await self.load_extension('my_extension')

# after using async_with
async def main():
    async with bot:
        await bot.load_extension('my_extension')
        await bot.start(TOKEN)

asyncio.run(main())

コンバータの汎用ランタイムプロトコル化

Converterruntime-checkabletyping.Protocol になりました。

その結果、これらのクラスで使用されるベースメタクラスが変更され、 Converter を継承するユーザーが作成したクラスに影響を与える可能性があります。

簡単な例:

# before
class SomeConverterMeta(type):
    ...

class SomeConverter(commands.Converter, metaclass=SomeConverterMeta):
    ...

# after
class SomeConverterMeta(type(commands.Converter)):
    ...

class SomeConverter(commands.Converter, metaclass=SomeConverterMeta):
    ...

さらに、 Convertertyping.Generic になり、ユーザーは(自己判断で)型ヒントをより正確に定義することができます。

関数シグネチャの変更

以下のメソッドの引数は全て位置限定になりました:

以下の引数が位置限定になりました:

以下のパラメータは削除されました。

ライブラリは関数/メソッドの引数のデフォルト値として None を使用することが少なくなりました。

その結果、 これらの引数は None にはならなくなりました:

削除

以下の属性が削除されました:

その他の変更点

タスク拡張機能の変更

  • stop()before_loop() で呼び出すと、最初のイテレーションが実行されなくなりました。

  • ext.tasks.Loop.change_interval() を呼び出すと、次のループの繰り返しの時ではなく、直ちにスリープ時間の間隔が変更されるようになりました。

  • ext.tasks.loop() のパラメーター loopNone を渡せなくなりました。

v1.0への移行

この移行に関する内容は v1.0への移行 に移動されました。