fix: 'load_module()' deprecated in Python 3.12
[babeltrace.git] / src / bindings / python / bt2 / bt2 / py_plugin.py
index 5f620ab794ad20321c219c5eadd4e01c0e6d1b55..50bfe91ab7f44c5e184b88dbb3046a31134346e1 100644 (file)
 # THE SOFTWARE.
 
 from bt2 import utils
-import bt2.component
+from bt2 import component as bt2_component
+import sys
+
+
+# Python plugin path to `_PluginInfo` (cache)
+_plugin_infos = {}
 
 
 def plugin_component_class(component_class):
-    if not issubclass(component_class, bt2.component._UserComponent):
+    if not issubclass(component_class, bt2_component._UserComponent):
         raise TypeError('component class is not a subclass of a user component class')
 
     component_class._bt_plugin_component_class = None
@@ -35,8 +40,6 @@ def plugin_component_class(component_class):
 def register_plugin(
     module_name, name, description=None, author=None, license=None, version=None
 ):
-    import sys
-
     if module_name not in sys.modules:
         raise RuntimeError(
             "cannot find module '{}' in loaded modules".format(module_name)
@@ -102,6 +105,10 @@ class _PluginInfo:
 
 # called by the BT plugin system
 def _try_load_plugin_module(path):
+    if path in _plugin_infos:
+        # do not load module and create plugin info twice for this path
+        return _plugin_infos[path]
+
     import importlib.machinery
     import inspect
     import hashlib
@@ -115,9 +122,19 @@ def _try_load_plugin_module(path):
     h = hashlib.sha256()
     h.update(path.encode())
     module_name = 'bt_plugin_{}'.format(h.hexdigest())
+    assert module_name not in sys.modules
 
     # try loading the module: any raised exception is catched by the caller
-    mod = importlib.machinery.SourceFileLoader(module_name, path).load_module()
+    if sys.version_info < (3, 5):
+        mod = importlib.machinery.SourceFileLoader(module_name, path).load_module()
+    else:
+        import importlib.util
+
+        loader = importlib.machinery.SourceFileLoader(module_name, path)
+        spec = importlib.util.spec_from_file_location(module_name, path, loader=loader)
+        mod = importlib.util.module_from_spec(spec)
+        sys.modules[mod.__name__] = mod
+        loader.exec_module(mod)
 
     # we have the module: look for its plugin info first
     if not hasattr(mod, '_bt_plugin_info'):
@@ -137,4 +154,5 @@ def _try_load_plugin_module(path):
 
     comp_class_entries = inspect.getmembers(mod, is_user_comp_class)
     plugin_info.comp_class_addrs = [entry[1].addr for entry in comp_class_entries]
+    _plugin_infos[path] = plugin_info
     return plugin_info
This page took 0.024823 seconds and 4 git commands to generate.