Last active
March 8, 2024 16:43
-
-
Save AXVin/08ed554a458fc7aee4da162f4c53d086 to your computer and use it in GitHub Desktop.
Cog for reloading extensions as they are edited
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
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
NB if you want to use asyncronous
cog_load
andcog_unload
methods you will need to addawait self.bot.wait_until_ready()
to the start of thebefore_loop
this extension should be the last loaded extension of the bot, so there's no particular need to do that
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
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))