From 2bbe0457e550f2b6a1dd14be137554fe4e8c5be7 Mon Sep 17 00:00:00 2001
From: c4pp4
Date: Sun, 25 Oct 2026 12:56:48 +0100
Subject: [PATCH 1/1] Replace the removed imp module

The imp module was removed in Python 3.12. Load the plugins with the
source and sourceless file loaders of importlib instead of
imp.load_source() and imp.load_compiled().

Signed-off-by: c4pp4
---
 Mailnag/common/plugins.py | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/Mailnag/common/plugins.py b/Mailnag/common/plugins.py
index d9bf572..5e78503 100644
--- a/Mailnag/common/plugins.py
+++ b/Mailnag/common/plugins.py
@@ -17,7 +17,9 @@
 #
 
 import os
-import imp
+import sys
+import importlib.machinery
+import importlib.util
 import inspect
 import logging
 from enum import Enum
@@ -29,6 +31,15 @@ PLUGIN_LIB_PATH = os.path.join(LIB_DIR, 'plugins')
 PLUGIN_USER_PATH = os.path.join(cfg_folder, 'plugins')
 PLUGIN_PATHS = [ PLUGIN_LIB_PATH, PLUGIN_USER_PATH ]
 
+# imp.load_source() and imp.load_compiled() were removed in Python 3.12
+def load_module(modname, filename, loader_type):
+	loader = loader_type(modname, filename)
+	spec = importlib.util.spec_from_file_location(modname, filename, loader = loader)
+	mod = importlib.util.module_from_spec(spec)
+	sys.modules[modname] = mod
+	loader.exec_module(mod)
+	return mod
+
 #
 # All known hook types.
 #
@@ -259,9 +270,9 @@ class Plugin:
 				try:
 					if ext.lower() == '.py':
 						if not os.path.exists(os.path.join(path, modname + '.pyc')):
-							mod = imp.load_source(modname, os.path.join(path, f))
+							mod = load_module(modname, os.path.join(path, f), importlib.machinery.SourceFileLoader)
 					elif ext.lower() == '.pyc':
-						mod = imp.load_compiled(modname, os.path.join(path, f))
+						mod = load_module(modname, os.path.join(path, f), importlib.machinery.SourcelessFileLoader)
 				
 					if mod != None:
 						for t in dir(mod):
-- 
2.55.0

