Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/release'
Browse files Browse the repository at this point in the history
  • Loading branch information
Overhang.IO committed Jan 10, 2025
2 parents e3444b7 + cb1d5de commit 60e7e91
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog.d/20250109_184104_regis_plugin_unload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- [Bugfix] Properly reload a plugin module on enable/disable/enable. This is an edge case that should not have affected anyone. (by @regisb)
30 changes: 29 additions & 1 deletion tutor/plugins/v1.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import importlib.util
import os
from glob import glob
import sys

import importlib_metadata

from tutor import hooks
from tutor.types import Config

from .base import PLUGINS_ROOT

Expand Down Expand Up @@ -71,8 +73,34 @@ def discover_package(entrypoint: importlib_metadata.EntryPoint) -> None:
dist_version = entrypoint.dist.version if entrypoint.dist else "Unknown"
hooks.Filters.PLUGINS_INFO.add_item((name, dist_version))

# Import module on enable
@hooks.Actions.PLUGIN_LOADED.add()
def load(plugin_name: str) -> None:
"""
Import module on enable.
"""
if name == plugin_name:
importlib.import_module(entrypoint.value)

# Remove module from cache on disable
@hooks.Actions.PLUGIN_UNLOADED.add()
def unload(plugin_name: str, _root: str, _config: Config) -> None:
"""
Remove plugin module from import cache on disable.
This is necessary in one particular use case: when a plugin is enabled,
disabled, and enabled again -- all within the same call to Tutor. In such a
case, the following happens:
1. plugin enabled: the plugin module is imported. It is automatically added by
Python to the import cache.
2. plugin disabled: action and filter callbacks are removed, but the module
remains in the import cache.
3. plugin enabled again: the plugin module is imported. But because it's in the
import cache, the module instructions are not executed again.
This is not supposed to happen when we run Tutor normally from the CLI. But when
running a long-lived process, such as a web app, where a plugin might be enabled
and disabled multiple times, this becomes an issue.
"""
if name == plugin_name and entrypoint.value in sys.modules:
sys.modules.pop(entrypoint.value)

0 comments on commit 60e7e91

Please sign in to comment.