Skip to content

Commit a784f82

Browse files
Cleanup after unloading extension. (#3226)
* Cleanup after unloading extension, resolve #3223. * Remove leftover modules loaded from `plugins` path when purging. --------- Co-authored-by: Taku <[email protected]>
1 parent 43fbc31 commit a784f82

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s
1212
- `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. ([PR #3195](https://github.com/kyb3r/modmail/pull/3195))
1313
- Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242))
1414
- Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239))
15+
- Cleanup imports after removing/unloading a plugin. ([PR #3226](https://github.com/modmail-dev/Modmail/pull/3226))
1516

1617
### Added
1718
- `?log key <key>` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196))

cogs/plugins.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,17 @@ async def load_plugin(self, plugin):
264264
logger.error("Plugin load failure: %s", plugin.ext_string, exc_info=True)
265265
raise InvalidPluginError("Cannot load extension, plugin invalid.") from exc
266266

267+
async def unload_plugin(self, plugin: Plugin) -> None:
268+
try:
269+
await self.bot.unload_extension(plugin.ext_string)
270+
except commands.ExtensionError as exc:
271+
raise exc
272+
273+
ext_parent = ".".join(plugin.ext_string.split(".")[:-1])
274+
for module in list(sys.modules.keys()):
275+
if module == ext_parent or module.startswith(ext_parent + "."):
276+
del sys.modules[module]
277+
267278
async def parse_user_input(self, ctx, plugin_name, check_version=False):
268279

269280
if not self.bot.config["enable_plugins"]:
@@ -378,7 +389,7 @@ async def plugins_add(self, ctx, *, plugin_name: str):
378389
logger.warning("Unable to download plugin %s.", plugin, exc_info=True)
379390

380391
embed = discord.Embed(
381-
description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}",
392+
description=f"Failed to download plugin, check logs for error.\n{type(e).__name__}: {e}",
382393
color=self.bot.error_color,
383394
)
384395

@@ -397,7 +408,7 @@ async def plugins_add(self, ctx, *, plugin_name: str):
397408
logger.warning("Unable to load plugin %s.", plugin, exc_info=True)
398409

399410
embed = discord.Embed(
400-
description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}",
411+
description=f"Failed to load plugin, check logs for error.\n{type(e).__name__}: {e}",
401412
color=self.bot.error_color,
402413
)
403414

@@ -438,7 +449,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str):
438449

439450
if self.bot.config.get("enable_plugins"):
440451
try:
441-
await self.bot.unload_extension(plugin.ext_string)
452+
await self.unload_plugin(plugin)
442453
self.loaded_plugins.remove(plugin)
443454
except (commands.ExtensionNotLoaded, KeyError):
444455
logger.warning("Plugin was never loaded.")
@@ -480,9 +491,10 @@ async def update_plugin(self, ctx, plugin_name):
480491
await self.download_plugin(plugin, force=True)
481492
if self.bot.config.get("enable_plugins"):
482493
try:
483-
await self.bot.unload_extension(plugin.ext_string)
494+
await self.unload_plugin(plugin)
484495
except commands.ExtensionError:
485496
logger.warning("Plugin unload fail.", exc_info=True)
497+
486498
try:
487499
await self.load_plugin(plugin)
488500
except Exception:
@@ -529,17 +541,20 @@ async def plugins_reset(self, ctx):
529541
for ext in list(self.bot.extensions):
530542
if not ext.startswith("plugins."):
531543
continue
544+
logger.error("Unloading plugin: %s.", ext)
532545
try:
533-
logger.error("Unloading plugin: %s.", ext)
534-
await self.bot.unload_extension(ext)
535-
except Exception:
536-
logger.error("Failed to unload plugin: %s.", ext)
537-
else:
538-
if not self.loaded_plugins:
539-
continue
540546
plugin = next((p for p in self.loaded_plugins if p.ext_string == ext), None)
541547
if plugin:
548+
await self.unload_plugin(plugin)
542549
self.loaded_plugins.remove(plugin)
550+
else:
551+
await self.bot.unload_extension(ext)
552+
except Exception:
553+
logger.error("Failed to unload plugin: %s.", ext)
554+
555+
for module in list(sys.modules.keys()):
556+
if module.startswith("plugins."):
557+
del sys.modules[module]
543558

544559
self.bot.config["plugins"].clear()
545560
await self.bot.config.update()

0 commit comments

Comments
 (0)