Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/github_actions/heinrichreimer/git…
Browse files Browse the repository at this point in the history
…hub-changelog-generator-action-2.4
  • Loading branch information
Czaki authored Sep 8, 2024
2 parents d716e03 + c564891 commit 167b1db
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ jobs:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }}

- uses: softprops/action-gh-release@v1
- uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
generate_release_notes: true
Expand Down
22 changes: 21 additions & 1 deletion src/npe2/_plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
import urllib
import warnings
from collections import Counter
from collections import Counter, defaultdict
from fnmatch import fnmatch
from importlib import metadata
from logging import getLogger
Expand Down Expand Up @@ -38,6 +38,7 @@
if TYPE_CHECKING:
from .manifest.contributions import (
CommandContribution,
MenuCommand,
MenuItem,
ReaderContribution,
SampleDataContribution,
Expand Down Expand Up @@ -235,6 +236,9 @@ def __init__(
self._manifests: Dict[PluginName, PluginManifest] = {}
self.events = PluginManagerEvents(self)
self._npe1_adapters: List[NPE1Adapter] = []
self._command_menu_map: Dict[
str, Dict[str, Dict[str, List[MenuCommand]]]
] = defaultdict(dict)

# up to napari 0.4.15, discovery happened in the init here
# so if we're running on an older version of napari, we need to discover
Expand Down Expand Up @@ -358,14 +362,28 @@ def register(
self._npe1_adapters.append(manifest)
else:
self._contrib.index_contributions(manifest)
self._populate_command_menu_map(manifest)
self.events.plugins_registered.emit({manifest})

def _populate_command_menu_map(self, manifest: PluginManifest):
# map of manifest -> command -> menu_id -> list[items]
self._command_menu_map[manifest.name] = defaultdict(lambda: defaultdict(list))
menu_map = self._command_menu_map[manifest.name] # just for conciseness below
for menu_id, menu_items in manifest.contributions.menus.items() or ():
# command IDs are keys in map
# each value is a dict menu_id: list of MenuCommands
# for the command and menu
for item in menu_items:
if (command_id := getattr(item, "command", None)) is not None:
menu_map[command_id][menu_id].append(item)

def unregister(self, key: PluginName):
"""Unregister plugin named `key`."""
if key not in self._manifests:
raise ValueError(f"No registered plugin named {key!r}") # pragma: no cover
self.deactivate(key)
self._contrib.remove_contributions(key)
self._command_menu_map.pop(key)
self._manifests.pop(key)

def activate(self, key: PluginName) -> PluginContext:
Expand Down Expand Up @@ -448,6 +466,7 @@ def enable(self, plugin_name: PluginName) -> None:
mf = self._manifests.get(plugin_name)
if mf is not None:
self._contrib.index_contributions(mf)
self._populate_command_menu_map(mf)
self.events.enablement_changed({plugin_name}, {})

def disable(self, plugin_name: PluginName) -> None:
Expand All @@ -467,6 +486,7 @@ def disable(self, plugin_name: PluginName) -> None:

self._disabled_plugins.add(plugin_name)
self._contrib.remove_contributions(plugin_name)
self._command_menu_map.pop(plugin_name, None)
self.events.enablement_changed({}, {plugin_name})

def is_disabled(self, plugin_name: str) -> bool:
Expand Down
30 changes: 30 additions & 0 deletions tests/test_plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,33 @@ def dummy_error():
pm.get_context("test").register_disposable(dummy_error)
pm.deactivate("test")
assert caplog.records[0].msg == "Error while disposing test; This is an error"


def test_command_menu_map(uses_sample_plugin, plugin_manager: PluginManager):
"""Test that the command menu map is correctly populated."""
pm = PluginManager.instance()
assert SAMPLE_PLUGIN_NAME in pm._manifests
assert SAMPLE_PLUGIN_NAME in pm._command_menu_map

# contains correct commands
command_menu_map = pm._command_menu_map[SAMPLE_PLUGIN_NAME]
assert "my-plugin.hello_world" in command_menu_map
assert "my-plugin.another_command" in command_menu_map

# commands point to correct menus
assert len(cmd_menu := command_menu_map["my-plugin.hello_world"]) == 1
assert "/napari/layer_context" in cmd_menu
assert len(cmd_menu := command_menu_map["my-plugin.another_command"]) == 1
assert "mysubmenu" in cmd_menu

# enable/disable
pm.disable(SAMPLE_PLUGIN_NAME)
assert SAMPLE_PLUGIN_NAME not in pm._command_menu_map
pm.enable(SAMPLE_PLUGIN_NAME)
assert SAMPLE_PLUGIN_NAME in pm._command_menu_map

# register/unregister
pm.unregister(SAMPLE_PLUGIN_NAME)
assert SAMPLE_PLUGIN_NAME not in pm._command_menu_map
pm.register(SAMPLE_PLUGIN_NAME)
assert SAMPLE_PLUGIN_NAME in pm._command_menu_map

0 comments on commit 167b1db

Please sign in to comment.