From e74029c880568455e72c2823c88f541bd506a90e Mon Sep 17 00:00:00 2001 From: f321x Date: Mon, 17 Mar 2025 17:29:38 +0100 Subject: [PATCH] move plugin commands to init file of plugin --- electrum/commands.py | 5 ++++- electrum/plugin.py | 16 ++++++---------- electrum/plugins/labels/__init__.py | 19 +++++++++++++++++++ electrum/plugins/labels/commands.py | 20 -------------------- 4 files changed, 29 insertions(+), 31 deletions(-) delete mode 100644 electrum/plugins/labels/commands.py diff --git a/electrum/commands.py b/electrum/commands.py index e7f289a70..c6374c5e1 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -1568,10 +1568,13 @@ def plugin_command(s, plugin_name): in the plugins root.""" def decorator(func): global known_commands + assert len(plugin_name) > 0, "Plugin name must not be empty" func.plugin_name = plugin_name name = plugin_name + '_' + func.__name__ if name in known_commands or hasattr(Commands, name): - raise Exception(f"Plugins should not override other commands: {name}") + # electrum plugins are always loaded before the plugin commands, + # so plugin commands cannot overwrite them + return assert asyncio.iscoroutinefunction(func), f"Plugin commands must be a coroutine: {name}" @command(s) @wraps(func) diff --git a/electrum/plugin.py b/electrum/plugin.py index 7ed7e02cc..a4c0d614a 100644 --- a/electrum/plugin.py +++ b/electrum/plugin.py @@ -104,13 +104,13 @@ class Plugins(DaemonThread): if self.cmd_only and self.config.get('enable_plugin_' + name) is not True: continue base_name = 'electrum.plugins' if not external else 'electrum_external_plugins' - full_name = f'{base_name}.{name}' + ('.commands' if self.cmd_only else '') + full_name = f'{base_name}.{name}' if external: module_path = os.path.join(pkg_path, name) if not self._has_recursive_root_permissions(module_path): self.logger.info(f"Not loading plugin {module_path}: directory has user write permissions") continue - module_path = os.path.join(module_path, 'commands.py' if self.cmd_only else '__init__.py') + module_path = os.path.join(module_path, '__init__.py') if not os.path.exists(module_path): continue spec = importlib.util.spec_from_file_location(full_name, module_path) @@ -122,7 +122,7 @@ class Plugins(DaemonThread): raise Exception(f"Error pre-loading {full_name}: no spec") module = self.exec_module_from_spec(spec, full_name) if self.cmd_only: - assert name not in self.loaded_command_modules, f"duplicate command modules for: {name}" + assert name not in self.loaded_command_modules, f"tried to load commands of {name} twice" self.loaded_command_modules.add(name) continue d = module.__dict__ @@ -235,17 +235,13 @@ class Plugins(DaemonThread): raise Exception(f"duplicate plugins for name={name}") if name in self.external_plugin_metadata: raise Exception(f"duplicate plugins for name={name}") + if self.cmd_only and not self.config.get('enable_plugin_' + name): + continue module_path = f'electrum_external_plugins.{name}' if external else f'electrum.plugins.{name}' spec = zipfile.find_spec(name) module = self.exec_module_from_spec(spec, module_path) if self.cmd_only: - if self.config.get('enable_plugin_' + name) is not True: - continue - spec2 = importlib.util.find_spec(module_path + '.commands') - if spec2 is None: # no commands module in this plugin - continue - self.exec_module_from_spec(spec2, module_path + '.commands') - assert name not in self.loaded_command_modules, f"duplicate command modules for: {name}" + assert name not in self.loaded_command_modules, f"tried to load commands of {name} twice" self.loaded_command_modules.add(name) continue d = module.__dict__ diff --git a/electrum/plugins/labels/__init__.py b/electrum/plugins/labels/__init__.py index a40b30e06..da5e56ac8 100644 --- a/electrum/plugins/labels/__init__.py +++ b/electrum/plugins/labels/__init__.py @@ -1,4 +1,11 @@ from electrum.i18n import _ +from electrum.commands import plugin_command +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .labels import LabelsPlugin + from electrum.commands import Commands + fullname = _('LabelSync') description = ' '.join([ @@ -7,3 +14,15 @@ description = ' '.join([ ]) available_for = ['qt', 'qml', 'cmdline'] +plugin_name = "labels" + +@plugin_command('w', plugin_name) +async def push(self: 'Commands', plugin: 'LabelsPlugin' = None, wallet=None) -> int: + """ push labels to server """ + return await plugin.push_thread(wallet) + + +@plugin_command('w', plugin_name) +async def pull(self: 'Commands', plugin: 'LabelsPlugin' = None, wallet=None, force=False) -> int: + """ pull labels from server """ + return await plugin.pull_thread(wallet, force=force) diff --git a/electrum/plugins/labels/commands.py b/electrum/plugins/labels/commands.py deleted file mode 100644 index 2c540833e..000000000 --- a/electrum/plugins/labels/commands.py +++ /dev/null @@ -1,20 +0,0 @@ -from electrum.commands import plugin_command -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from .labels import LabelsPlugin - from electrum.commands import Commands - -plugin_name = "labels" - - -@plugin_command('w', plugin_name) -async def push(self: 'Commands', plugin: 'LabelsPlugin' = None, wallet=None) -> int: - """ push labels to server """ - return await plugin.push_thread(wallet) - - -@plugin_command('w', plugin_name) -async def pull(self: 'Commands', plugin: 'LabelsPlugin' = None, wallet=None, force=False) -> int: - """ pull labels from server """ - return await plugin.pull_thread(wallet, force=force)