[core] plugins: Add a method to reload a NodePlugin

Additionnally, add a new error status to distinguish an error during
the registration of the plugin (`LOADING_ERROR`) and an error when
the module itself is reloaded (through the `reload` function from
importlib).
This commit is contained in:
Candice Bentéjac 2025-05-26 17:41:37 +02:00
parent 3af5acfa91
commit 5bc09c8847

View file

@ -1,7 +1,9 @@
from __future__ import annotations from __future__ import annotations
import importlib
import logging import logging
import os import os
import sys
from enum import Enum from enum import Enum
from inspect import getfile from inspect import getfile
@ -63,7 +65,8 @@ class NodePluginStatus(Enum):
NOT_LOADED = 0 # The node plugin exists but is not loaded and cannot be used (not registered) NOT_LOADED = 0 # The node plugin exists but is not loaded and cannot be used (not registered)
LOADED = 1 # The node plugin is currently loaded and functional (it has been registered) LOADED = 1 # The node plugin is currently loaded and functional (it has been registered)
DESC_ERROR = 2 # The node plugin exists but has an invalid description DESC_ERROR = 2 # The node plugin exists but has an invalid description
ERROR = 3 # The node plugin exists and is valid but could not be successfully loaded LOADING_ERROR = 3 # The node plugin exists and is valid but could not be successfully registered
ERROR = 4 # Error when importing the node plugin from its module
class Plugin(BaseObject): class Plugin(BaseObject):
@ -197,6 +200,23 @@ class NodePlugin(BaseObject):
self._processEnv = None self._processEnv = None
def reload(self):
""" Reload the node plugin and update its status accordingly. """
updated = importlib.reload(sys.modules.get(self.nodeDescriptor.__module__))
descriptor = getattr(updated, self.nodeDescriptor.__name__)
if not descriptor:
self.status = NodePluginStatus.ERROR
return
self.nodeDescriptor = descriptor
self.errors = validateNodeDesc(descriptor)
if self.errors:
self.status = NodePluginStatus.DESC_ERROR
else:
self.status = NodePluginStatus.NOT_LOADED
@property @property
def plugin(self): def plugin(self):
""" """
@ -375,13 +395,14 @@ class NodePluginManager(BaseObject):
nodePlugin: the node plugin to register. nodePlugin: the node plugin to register.
""" """
name = nodePlugin.nodeDescriptor.__name__ name = nodePlugin.nodeDescriptor.__name__
if not self.isRegistered(name) and nodePlugin.status != NodePluginStatus.DESC_ERROR: if not self.isRegistered(name) and nodePlugin.status not in (NodePluginStatus.DESC_ERROR,
NodePluginStatus.ERROR):
try: try:
self._nodePlugins[name] = nodePlugin self._nodePlugins[name] = nodePlugin
nodePlugin.status = NodePluginStatus.LOADED nodePlugin.status = NodePluginStatus.LOADED
except Exception as e: except Exception as e:
logging.error(f"NodePlugin {name} could not be loaded: {e}") logging.error(f"NodePlugin {name} could not be loaded: {e}")
nodePlugin.status = NodePluginStatus.ERROR nodePlugin.status = NodePluginStatus.LOADING_ERROR
def unregisterNode(self, nodePlugin: NodePlugin): def unregisterNode(self, nodePlugin: NodePlugin):
""" """