この記事は移転しました。約2秒後に新記事へ移動します。移動しない場合はココをクリックしてください。
はじめに
制作しているDiscord Botの改修作業を行っている途中で、loop周りのエラーにぶち当たりました。解決に少々時間を要したので、メモを残しておきます。
開発環境
- discord.py 2.1.0
- python3 3.8.10
起きたこと
Discord Botを実行すると以下のエラー文が出るようになった。
Traceback (most recent call last): File "main.py", line 50, in <module> loop.start() File "/home/oimo/.local/lib/python3.8/site-packages/discord/ext/tasks/__init__.py", line 398, in start self._task = asyncio.create_task(self._loop(*args, **kwargs)) File "/usr/lib/python3.8/asyncio/tasks.py", line 381, in create_task loop = events.get_running_loop() RuntimeError: no running event loop sys:1: RuntimeWarning: coroutine 'Loop._loop' was never awaited
解決策
- loopの起動を
on_ready
の中に仕込む
import discord from discord.ext import tasks # この中にloop.startを仕込む @client.event async def on_ready(): loop.start() @tasks.loop(seconds=60) async def loop(): now = datetime.now(timezone('Asia/Tokyo')).strftime('%H:%M') if now.hour == 19 and now.minute == 30: channel = client.get_channel(CHANNEL_ID) await channel.send('ゴミ出しに行こうね!')
一体なんだったのか
Discord.py 2.0.0/python 3.1以上の環境で、「discord.ext.tasks」を使用しているときに起きるようです。
もともと「discord.ext.tasks」を使うと、asyncio
という並行処理のコードを書くためのライブラリを使用せずとも、ループを実行させられるらしい。しかし、Discord.py側のアップデートか何なのかbotの起動前に、ただ単にループ処理実行を書くだけでは上手く起動しないようになっています。
そこで、上記のようにon_readyにループ実行を入れてあげれば動くらしい。
# うまく動作しないパターン @client.event async def on_ready(): @tasks.loop(seconds=60) async def loop(): now = datetime.now(timezone('Asia/Tokyo')).strftime('%H:%M') if now.hour == 19 and now.minute == 30: channel = client.get_channel(CHANNEL_ID) await channel.send('ゴミ出しに行こうね!') loop.start()
まとめ
timezone周りを修正したかっただけなのに、これが出てきてえらい大変困りました。