Skip to content

Instantly share code, notes, and snippets.

@AXVin
Last active March 8, 2024 16:43
Show Gist options
  • Save AXVin/08ed554a458fc7aee4da162f4c53d086 to your computer and use it in GitHub Desktop.
Save AXVin/08ed554a458fc7aee4da162f4c53d086 to your computer and use it in GitHub Desktop.
Cog for reloading extensions as they are edited
import os
import pathlib
import discord
from discord.ext import commands, tasks
# put your extension names in this list
# if you don't want them to be reloaded
IGNORE_EXTENSIONS = []
def path_from_extension(extension: str) -> pathlib.Path:
return pathlib.Path(extension.replace('.', os.sep)+'.py')
class HotReload(commands.Cog):
"""
Cog for reloading extensions as soon as the file is edited
"""
def __init__(self, bot):
self.bot = bot
self.hot_reload_loop.start()
def cog_unload(self):
self.hot_reload_loop.stop()
@tasks.loop(seconds=3)
async def hot_reload_loop(self):
for extension in list(self.bot.extensions.keys()):
if extension in IGNORE_EXTENSIONS:
continue
path = path_from_extension(extension)
time = os.path.getmtime(path)
try:
if self.last_modified_time[extension] == time:
continue
except KeyError:
self.last_modified_time[extension] = time
try:
# For d.py 2.0, await the next line
self.bot.reload_extension(extension)
except commands.ExtensionError:
print(f"Couldn't reload extension: {extension}")
except commands.ExtensionNotLoaded:
continue
else:
print(f"Reloaded extension: {extension}")
finally:
self.last_modified_time[extension] = time
@hot_reload_loop.before_loop
async def cache_last_modified_time(self):
self.last_modified_time = {}
# Mapping = {extension: timestamp}
for extension in self.bot.extensions.keys():
if extension in IGNORE_EXTENSIONS:
continue
path = path_from_extension(extension)
time = os.path.getmtime(path)
self.last_modified_time[extension] = time
def setup(bot):
cog = HotReload(bot)
bot.add_cog(cog)
# For d.py 2.0, comment the above setup function
# and uncomment the below
# async def setup(bot):
# cog = HotReload(bot)
# await bot.add_cog(cog)
@artemOP
Copy link

artemOP commented Jun 23, 2022

for d.py 2.0 support line 43 and 67 have to be awaited
await self.bot.reload_extension(extension)
await bot.add_cog(HotReload(bot))

@artemOP
Copy link

artemOP commented Sep 10, 2022

NB if you want to use asyncronous cog_load and cog_unload methods you will need to add await self.bot.wait_until_ready() to the start of the before_loop

@AXVin
Copy link
Author

AXVin commented Sep 10, 2022

NB if you want to use asyncronous cog_load and cog_unload methods you will need to add await self.bot.wait_until_ready() to the start of the before_loop

this extension should be the last loaded extension of the bot, so there's no particular need to do that

@Motzumoto
Copy link

Cog watch devs hate this 1 simple trick!!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment