Skip to content

Commit 3b95fb2

Browse files
Jerrie-AriesTaaku18
authored andcommitted
Cleanup after unloading extension. (modmail-dev#3226)
* Cleanup after unloading extension, resolve modmail-dev#3223. * Remove leftover modules loaded from `plugins` path when purging. --------- Co-authored-by: Taku <[email protected]> (cherry picked from commit a784f82) Signed-off-by: Khakers <[email protected]>
1 parent 982ae77 commit 3b95fb2

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ however, insignificant breaking changes do not guarantee a major version bump, s
3535
- Persistent notes have been fixed after the previous discord.py update.
3636
- `is_image` now is true only if the image is actually an image.
3737
- Fix contact command reporting user was blocked when they weren't.
38+
- Cleanup imports after removing/unloading a plugin. ([PR #3226](https://github.com/modmail-dev/Modmail/pull/3226))
3839

3940
### Internal
4041
- Add `update_title` and `update_nsfw` methods to `ApiClient` to update thread title and nsfw status in the database.

cogs/plugins.py

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

266+
async def unload_plugin(self, plugin: Plugin) -> None:
267+
try:
268+
await self.bot.unload_extension(plugin.ext_string)
269+
except commands.ExtensionError as exc:
270+
raise exc
271+
272+
ext_parent = ".".join(plugin.ext_string.split(".")[:-1])
273+
for module in list(sys.modules.keys()):
274+
if module == ext_parent or module.startswith(ext_parent + "."):
275+
del sys.modules[module]
276+
266277
async def parse_user_input(self, ctx, plugin_name, check_version=False):
267278
if not self.bot.config["enable_plugins"]:
268279
embed = discord.Embed(
@@ -376,7 +387,7 @@ async def plugins_add(self, ctx, *, plugin_name: str):
376387
logger.warning("Unable to download plugin %s.", plugin, exc_info=True)
377388

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

@@ -394,7 +405,7 @@ async def plugins_add(self, ctx, *, plugin_name: str):
394405
logger.warning("Unable to load plugin %s.", plugin, exc_info=True)
395406

396407
embed = discord.Embed(
397-
description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}",
408+
description=f"Failed to load plugin, check logs for error.\n{type(e).__name__}: {e}",
398409
color=self.bot.error_color,
399410
)
400411

@@ -435,7 +446,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str):
435446

436447
if self.bot.config.get("enable_plugins"):
437448
try:
438-
await self.bot.unload_extension(plugin.ext_string)
449+
await self.unload_plugin(plugin)
439450
self.loaded_plugins.remove(plugin)
440451
except (commands.ExtensionNotLoaded, KeyError):
441452
logger.warning("Plugin was never loaded.")
@@ -477,9 +488,10 @@ async def update_plugin(self, ctx, plugin_name):
477488
await self.download_plugin(plugin, force=True)
478489
if self.bot.config.get("enable_plugins"):
479490
try:
480-
await self.bot.unload_extension(plugin.ext_string)
491+
await self.unload_plugin(plugin)
481492
except commands.ExtensionError:
482493
logger.warning("Plugin unload fail.", exc_info=True)
494+
483495
try:
484496
await self.load_plugin(plugin)
485497
except Exception:
@@ -526,17 +538,20 @@ async def plugins_reset(self, ctx):
526538
for ext in list(self.bot.extensions):
527539
if not ext.startswith("plugins."):
528540
continue
541+
logger.error("Unloading plugin: %s.", ext)
529542
try:
530-
logger.error("Unloading plugin: %s.", ext)
531-
await self.bot.unload_extension(ext)
532-
except Exception:
533-
logger.error("Failed to unload plugin: %s.", ext)
534-
else:
535-
if not self.loaded_plugins:
536-
continue
537543
plugin = next((p for p in self.loaded_plugins if p.ext_string == ext), None)
538544
if plugin:
545+
await self.unload_plugin(plugin)
539546
self.loaded_plugins.remove(plugin)
547+
else:
548+
await self.bot.unload_extension(ext)
549+
except Exception:
550+
logger.error("Failed to unload plugin: %s.", ext)
551+
552+
for module in list(sys.modules.keys()):
553+
if module.startswith("plugins."):
554+
del sys.modules[module]
540555

541556
self.bot.config["plugins"].clear()
542557
await self.bot.config.update()

0 commit comments

Comments
 (0)