semantics
This commit is contained in:
@@ -4,7 +4,6 @@ import sys # Added this line
|
||||
from typing import Dict, List, Optional
|
||||
from .plugin_base import PluginBase, PluginConfig
|
||||
from .logger import belief_scope
|
||||
|
||||
# #region PluginLoader [C:3] [TYPE Class] [SEMANTICS plugin, loader, dynamic, import]
|
||||
# @BRIEF Scans a specified directory for Python modules, dynamically loads them, and registers any classes that are valid implementations of the PluginBase interface.
|
||||
# @LAYER: Core
|
||||
@@ -14,8 +13,7 @@ class PluginLoader:
|
||||
Scans a directory for Python modules, loads them, and identifies classes
|
||||
that inherit from PluginBase.
|
||||
"""
|
||||
|
||||
# [DEF:__init__:Function]
|
||||
# #region __init__ [TYPE Function]
|
||||
# @PURPOSE: Initializes the PluginLoader with a directory to scan.
|
||||
# @PRE: plugin_dir is a valid directory path.
|
||||
# @POST: Plugins are loaded and registered.
|
||||
@@ -26,9 +24,8 @@ class PluginLoader:
|
||||
self._plugins: Dict[str, PluginBase] = {}
|
||||
self._plugin_configs: Dict[str, PluginConfig] = {}
|
||||
self._load_plugins()
|
||||
# [/DEF:__init__:Function]
|
||||
|
||||
# [DEF:_load_plugins:Function]
|
||||
# #endregion __init__
|
||||
# #region _load_plugins [TYPE Function]
|
||||
# @PURPOSE: Scans the plugin directory and loads all valid plugins.
|
||||
# @PRE: plugin_dir exists or can be created.
|
||||
# @POST: _load_module is called for each .py file.
|
||||
@@ -39,14 +36,12 @@ class PluginLoader:
|
||||
"""
|
||||
if not os.path.exists(self.plugin_dir):
|
||||
os.makedirs(self.plugin_dir)
|
||||
|
||||
# Add the plugin directory's parent to sys.path to enable relative imports within plugins
|
||||
# This assumes plugin_dir is something like 'backend/src/plugins'
|
||||
# and we want 'backend/src' to be on the path for 'from ..core...' imports
|
||||
plugin_parent_dir = os.path.abspath(os.path.join(self.plugin_dir, os.pardir))
|
||||
if plugin_parent_dir not in sys.path:
|
||||
sys.path.insert(0, plugin_parent_dir)
|
||||
|
||||
for filename in os.listdir(self.plugin_dir):
|
||||
file_path = os.path.join(self.plugin_dir, filename)
|
||||
|
||||
@@ -56,14 +51,12 @@ class PluginLoader:
|
||||
if os.path.exists(init_file):
|
||||
self._load_module(filename, init_file)
|
||||
continue
|
||||
|
||||
# Handle single-file plugins
|
||||
if filename.endswith(".py") and filename != "__init__.py":
|
||||
module_name = filename[:-3]
|
||||
self._load_module(module_name, file_path)
|
||||
# [/DEF:_load_plugins:Function]
|
||||
|
||||
# [DEF:_load_module:Function]
|
||||
# #endregion _load_plugins
|
||||
# #region _load_module [TYPE Function]
|
||||
# @PURPOSE: Loads a single Python module and discovers PluginBase implementations.
|
||||
# @PRE: module_name and file_path are valid.
|
||||
# @POST: Plugin classes are instantiated and registered.
|
||||
@@ -82,14 +75,12 @@ class PluginLoader:
|
||||
if spec is None or spec.loader is None:
|
||||
print(f"Could not load module spec for {package_name}") # Replace with proper logging
|
||||
return
|
||||
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
try:
|
||||
spec.loader.exec_module(module)
|
||||
except Exception as e:
|
||||
print(f"Error loading plugin module {module_name}: {e}") # Replace with proper logging
|
||||
return
|
||||
|
||||
for attribute_name in dir(module):
|
||||
attribute = getattr(module, attribute_name)
|
||||
if (
|
||||
@@ -102,9 +93,8 @@ class PluginLoader:
|
||||
self._register_plugin(plugin_instance)
|
||||
except Exception as e:
|
||||
print(f"Error instantiating plugin {attribute_name} in {module_name}: {e}") # Replace with proper logging
|
||||
# [/DEF:_load_module:Function]
|
||||
|
||||
# [DEF:_register_plugin:Function]
|
||||
# #endregion _load_module
|
||||
# #region _register_plugin [TYPE Function]
|
||||
# @PURPOSE: Registers a PluginBase instance and its configuration.
|
||||
# @PRE: plugin_instance is a valid implementation of PluginBase.
|
||||
# @POST: Plugin is added to _plugins and _plugin_configs.
|
||||
@@ -118,7 +108,6 @@ class PluginLoader:
|
||||
if plugin_id in self._plugins:
|
||||
print(f"Warning: Duplicate plugin ID '{plugin_id}' found. Skipping.") # Replace with proper logging
|
||||
return
|
||||
|
||||
try:
|
||||
schema = plugin_instance.get_schema()
|
||||
# Basic validation to ensure it's a dictionary
|
||||
@@ -143,10 +132,8 @@ class PluginLoader:
|
||||
except Exception as e:
|
||||
from ..core.logger import logger
|
||||
logger.error(f"Error validating plugin '{plugin_instance.name}' (ID: {plugin_id}): {e}")
|
||||
# [/DEF:_register_plugin:Function]
|
||||
|
||||
|
||||
# [DEF:get_plugin:Function]
|
||||
# #endregion _register_plugin
|
||||
# #region get_plugin [TYPE Function]
|
||||
# @PURPOSE: Retrieves a loaded plugin instance by its ID.
|
||||
# @PRE: plugin_id is a string.
|
||||
# @POST: Returns plugin instance or None.
|
||||
@@ -158,9 +145,8 @@ class PluginLoader:
|
||||
Returns a loaded plugin instance by its ID.
|
||||
"""
|
||||
return self._plugins.get(plugin_id)
|
||||
# [/DEF:get_plugin:Function]
|
||||
|
||||
# [DEF:get_all_plugin_configs:Function]
|
||||
# #endregion get_plugin
|
||||
# #region get_all_plugin_configs [TYPE Function]
|
||||
# @PURPOSE: Returns a list of all registered plugin configurations.
|
||||
# @PRE: None.
|
||||
# @POST: Returns list of all PluginConfig objects.
|
||||
@@ -171,9 +157,8 @@ class PluginLoader:
|
||||
Returns a list of all loaded plugin configurations.
|
||||
"""
|
||||
return list(self._plugin_configs.values())
|
||||
# [/DEF:get_all_plugin_configs:Function]
|
||||
|
||||
# [DEF:has_plugin:Function]
|
||||
# #endregion get_all_plugin_configs
|
||||
# #region has_plugin [TYPE Function]
|
||||
# @PURPOSE: Checks if a plugin with the given ID is registered.
|
||||
# @PRE: plugin_id is a string.
|
||||
# @POST: Returns True if plugin exists.
|
||||
@@ -185,6 +170,5 @@ class PluginLoader:
|
||||
Checks if a plugin with the given ID is loaded.
|
||||
"""
|
||||
return plugin_id in self._plugins
|
||||
# [/DEF:has_plugin:Function]
|
||||
|
||||
# #endregion PluginLoader
|
||||
# #endregion has_plugin
|
||||
# #endregion PluginLoader
|
||||
Reference in New Issue
Block a user