From 7815b80efa034584e697782e06c438ee9a541dab Mon Sep 17 00:00:00 2001 From: Emanuele Morrone <67059270+Pingdred@users.noreply.github.com> Date: Sat, 26 Aug 2023 19:35:10 +0200 Subject: [PATCH 1/8] Check if the module is imported before trying to remove it --- core/cat/mad_hatter/plugin.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/cat/mad_hatter/plugin.py b/core/cat/mad_hatter/plugin.py index dbe508c0..ba2db517 100644 --- a/core/cat/mad_hatter/plugin.py +++ b/core/cat/mad_hatter/plugin.py @@ -62,9 +62,12 @@ def deactivate(self): # Remove the imported modules for py_file in self.py_files: - py_filename = py_file.replace("/", ".").replace(".py", "") # this is UGLY I know. I'm sorry - log(f"Remove module {py_filename}", "DEBUG") - sys.modules.pop(py_filename) + py_filename = py_file.replace("/", ".").replace(".py", "") + + # If the module is imported it is removed + if py_filename in sys.modules: + log(f"Remove module {py_filename}", "DEBUG") + sys.modules.pop(py_filename) self._hooks = [] self._tools = [] From 823a829823620234a7983fee98b0dac696e720bc Mon Sep 17 00:00:00 2001 From: Emanuele Morrone <67059270+Pingdred@users.noreply.github.com> Date: Sat, 26 Aug 2023 19:37:55 +0200 Subject: [PATCH 2/8] Removed active parameter from Plugin constructor --- core/cat/mad_hatter/mad_hatter.py | 6 +++--- core/cat/mad_hatter/plugin.py | 10 ++-------- core/tests/mad_hatter/test_plugin.py | 10 +++++----- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/core/cat/mad_hatter/mad_hatter.py b/core/cat/mad_hatter/mad_hatter.py index 8ffe4746..170f95d7 100644 --- a/core/cat/mad_hatter/mad_hatter.py +++ b/core/cat/mad_hatter/mad_hatter.py @@ -52,7 +52,7 @@ def install_plugin(self, package_plugin): raise Exception("A plugin should contain a folder, found a file") # create plugin obj - self.load_plugin(plugin_path, active=False) + self.load_plugin(plugin_path) # activate it self.toggle_plugin(plugin_id) @@ -104,12 +104,12 @@ def find_plugins(self): self.sync_hooks_and_tools() - def load_plugin(self, plugin_path, active): + def load_plugin(self, plugin_path): # Instantiate plugin. # If the plugin is inactive, only manifest will be loaded # If active, also settings, tools and hooks try: - plugin = Plugin(plugin_path, active=active) + plugin = Plugin(plugin_path) # if plugin is valid, keep a reference self.plugins[plugin.id] = plugin except Exception as e: diff --git a/core/cat/mad_hatter/plugin.py b/core/cat/mad_hatter/plugin.py index ba2db517..2dfa6f57 100644 --- a/core/cat/mad_hatter/plugin.py +++ b/core/cat/mad_hatter/plugin.py @@ -18,7 +18,7 @@ class Plugin: - def __init__(self, plugin_path: str, active: bool): + def __init__(self, plugin_path: str): # does folder exist? if not os.path.exists(plugin_path) or not os.path.isdir(plugin_path): @@ -45,21 +45,14 @@ def __init__(self, plugin_path: str, active: bool): # but they are created and stored in each plugin instance self._hooks = [] self._tools = [] - self._active = False - # all plugins start active, they can be deactivated/reactivated from endpoint - if active: - self.activate() - def activate(self): # lists of hooks and tools self._hooks, self._tools = self._load_hooks_and_tools() self._active = True def deactivate(self): - self._active = False - # Remove the imported modules for py_file in self.py_files: py_filename = py_file.replace("/", ".").replace(".py", "") @@ -71,6 +64,7 @@ def deactivate(self): self._hooks = [] self._tools = [] + self._active = False # get plugin settings JSON schema def get_settings_schema(self): diff --git a/core/tests/mad_hatter/test_plugin.py b/core/tests/mad_hatter/test_plugin.py index d2b67d45..31c833a5 100644 --- a/core/tests/mad_hatter/test_plugin.py +++ b/core/tests/mad_hatter/test_plugin.py @@ -13,7 +13,7 @@ @pytest.fixture def plugin(): - p = Plugin(mock_plugin_path, active=True) + p = Plugin(mock_plugin_path) yield p @@ -25,7 +25,7 @@ def plugin(): def test_create_plugin_wrong_folder(): with pytest.raises(Exception) as e: - Plugin("/non/existent/folder", active=True) + Plugin("/non/existent/folder") assert f"Cannot create" in str(e.value) @@ -36,14 +36,14 @@ def test_create_plugin_empty_folder(): os.mkdir(path) with pytest.raises(Exception) as e: - Plugin(path, active=True) + Plugin(path) assert f"Cannot create" in str(e.value) def test_create_non_active_plugin(): - plugin = Plugin(mock_plugin_path, active=False) + plugin = Plugin(mock_plugin_path) assert plugin.active == False @@ -97,7 +97,7 @@ def test_create_active_plugin(plugin): def test_activate_plugin(): # create non-active plugin - plugin = Plugin(mock_plugin_path, active=False) + plugin = Plugin(mock_plugin_path) # activate it plugin.activate() From dade61acf98514f3cf58c81cfee9cb53d2e99079 Mon Sep 17 00:00:00 2001 From: Emanuele Morrone <67059270+Pingdred@users.noreply.github.com> Date: Sat, 26 Aug 2023 19:38:44 +0200 Subject: [PATCH 3/8] Removed unused headers --- core/tests/mad_hatter/test_plugin.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/tests/mad_hatter/test_plugin.py b/core/tests/mad_hatter/test_plugin.py index 31c833a5..e79af161 100644 --- a/core/tests/mad_hatter/test_plugin.py +++ b/core/tests/mad_hatter/test_plugin.py @@ -1,11 +1,7 @@ import os -import shutil import pytest -from inspect import isfunction from cat.mad_hatter.mad_hatter import Plugin -from cat.mad_hatter.decorators import CatHook, CatTool - mock_plugin_path = "tests/mocks/mock_plugin/" From e79c69eb6ac0780e3e07174f9065644193548e86 Mon Sep 17 00:00:00 2001 From: Emanuele Morrone <67059270+Pingdred@users.noreply.github.com> Date: Sat, 26 Aug 2023 19:40:34 +0200 Subject: [PATCH 4/8] Manually activate the plugin during discovery if is int the list of active plugins --- core/cat/mad_hatter/mad_hatter.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/cat/mad_hatter/mad_hatter.py b/core/cat/mad_hatter/mad_hatter.py index 170f95d7..51922a85 100644 --- a/core/cat/mad_hatter/mad_hatter.py +++ b/core/cat/mad_hatter/mad_hatter.py @@ -95,12 +95,12 @@ def find_plugins(self): # discover plugins, folder by folder for folder in all_plugin_folders: + self.load_plugin(folder) - # is the plugin active? - folder_base = os.path.basename(os.path.normpath(folder)) - is_active = folder_base in self.active_plugins - - self.load_plugin(folder, is_active) + plugin_id = os.path.basename(os.path.normpath(folder)) + + if plugin_id in self.active_plugins: + self.plugins[plugin_id].activate() self.sync_hooks_and_tools() From abf976fe96a776caf2bf9238a6ed15b3595923ce Mon Sep 17 00:00:00 2001 From: Emanuele Morrone <67059270+Pingdred@users.noreply.github.com> Date: Sat, 26 Aug 2023 19:42:19 +0200 Subject: [PATCH 5/8] Removed unnecessary test, Plugin object is created by default deactivated --- core/tests/mad_hatter/test_plugin.py | 34 ---------------------------- 1 file changed, 34 deletions(-) diff --git a/core/tests/mad_hatter/test_plugin.py b/core/tests/mad_hatter/test_plugin.py index e79af161..66092a27 100644 --- a/core/tests/mad_hatter/test_plugin.py +++ b/core/tests/mad_hatter/test_plugin.py @@ -56,40 +56,6 @@ def test_create_non_active_plugin(): assert plugin.hooks == [] assert plugin.tools == [] - -def test_create_active_plugin(plugin): - - assert plugin.active == True - - assert plugin.path == mock_plugin_path - assert plugin.id == "mock_plugin" - - # manifest - assert type(plugin.manifest) == dict - assert plugin.manifest["id"] == plugin.id - assert plugin.manifest["name"] == "MockPlugin" - assert "Description not found" in plugin.manifest["description"] - - # hooks - assert len(plugin.hooks) == 1 - hook = plugin.hooks[0] - assert isinstance(hook, CatHook) - assert hook.plugin_id == "mock_plugin" - assert hook.name == "before_cat_sends_message" - assert isfunction(hook.function) - assert hook.priority == 2.0 - - # tools - assert len(plugin.tools) == 1 - tool = plugin.tools[0] - assert isinstance(tool, CatTool) - assert tool.plugin_id == "mock_plugin" - assert tool.name == "mock_tool" - assert "mock_tool" in tool.description - assert isfunction(tool.func) - assert tool.return_direct == True - - def test_activate_plugin(): # create non-active plugin From b0d9dec893ce46732591cde1c9f2e7f6513c89aa Mon Sep 17 00:00:00 2001 From: Emanuele Morrone <67059270+Pingdred@users.noreply.github.com> Date: Sat, 26 Aug 2023 19:42:41 +0200 Subject: [PATCH 6/8] Renamed test function --- core/tests/mad_hatter/test_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/tests/mad_hatter/test_plugin.py b/core/tests/mad_hatter/test_plugin.py index 66092a27..98e3815f 100644 --- a/core/tests/mad_hatter/test_plugin.py +++ b/core/tests/mad_hatter/test_plugin.py @@ -37,7 +37,7 @@ def test_create_plugin_empty_folder(): assert f"Cannot create" in str(e.value) -def test_create_non_active_plugin(): +def test_create_plugin(): plugin = Plugin(mock_plugin_path) From 21ce67394a2202443975ea0fd97063667438f285 Mon Sep 17 00:00:00 2001 From: Emanuele Morrone <67059270+Pingdred@users.noreply.github.com> Date: Wed, 30 Aug 2023 16:37:39 +0200 Subject: [PATCH 7/8] Use fixture in `test_create_plugin` and `test_activate_plugin` --- core/tests/mad_hatter/test_plugin.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/core/tests/mad_hatter/test_plugin.py b/core/tests/mad_hatter/test_plugin.py index 98e3815f..d5f8c152 100644 --- a/core/tests/mad_hatter/test_plugin.py +++ b/core/tests/mad_hatter/test_plugin.py @@ -1,7 +1,9 @@ import os import pytest +from inspect import isfunction from cat.mad_hatter.mad_hatter import Plugin +from cat.mad_hatter.decorators import CatHook, CatTool mock_plugin_path = "tests/mocks/mock_plugin/" @@ -37,9 +39,7 @@ def test_create_plugin_empty_folder(): assert f"Cannot create" in str(e.value) -def test_create_plugin(): - - plugin = Plugin(mock_plugin_path) +def test_create_plugin(plugin): assert plugin.active == False @@ -56,10 +56,7 @@ def test_create_plugin(): assert plugin.hooks == [] assert plugin.tools == [] -def test_activate_plugin(): - - # create non-active plugin - plugin = Plugin(mock_plugin_path) +def test_activate_plugin(plugin): # activate it plugin.activate() From c7e7e4b5994c8d9b1f272e3d04b2fa583458cad3 Mon Sep 17 00:00:00 2001 From: Emanuele Morrone <67059270+Pingdred@users.noreply.github.com> Date: Wed, 30 Aug 2023 16:39:47 +0200 Subject: [PATCH 8/8] Added tests on hooks and tools that were previously in test_create_active_plugin in test_activate_plugin --- core/tests/mad_hatter/test_plugin.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/core/tests/mad_hatter/test_plugin.py b/core/tests/mad_hatter/test_plugin.py index d5f8c152..4770c4a1 100644 --- a/core/tests/mad_hatter/test_plugin.py +++ b/core/tests/mad_hatter/test_plugin.py @@ -62,14 +62,31 @@ def test_activate_plugin(plugin): plugin.activate() assert plugin.active == True - - # hooks and tools + + # hooks assert len(plugin.hooks) == 1 + hook = plugin.hooks[0] + assert isinstance(hook, CatHook) + assert hook.plugin_id == "mock_plugin" + assert hook.name == "before_cat_sends_message" + assert isfunction(hook.function) + assert hook.priority == 2.0 + + # tools assert len(plugin.tools) == 1 - + tool = plugin.tools[0] + assert isinstance(tool, CatTool) + assert tool.plugin_id == "mock_plugin" + assert tool.name == "mock_tool" + assert "mock_tool" in tool.description + assert isfunction(tool.func) + assert tool.return_direct == True def test_deactivate_plugin(plugin): + # The plugin is non active by default + plugin.activate() + # deactivate it plugin.deactivate()