From 7c68ef354b4fadbf455f93986bae5b11ead3078a Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 4 Jan 2024 13:43:20 +0000 Subject: [PATCH] gst-python: Fix override loading in python >= 3.12 The `imp` module got removed in python 3.12 and the `importlib` module should be used instead. This is also a good excuse to switch to the new finder module from PEP 451 : https://www.python.org/dev/peps/pep-0451/ This only requires implement the `find_spec()` method in our custom loaders Co-authored-by: Stefan <107316-stefan6419846@users.noreply.gitlab.freedesktop.org> Co-authored-by: Jordan Petrids Part-of: --- .../GstDebugViewer/Plugins/__init__.py | 14 +++++-- subprojects/gst-python/gi/__init__.py | 42 ++++++------------- .../gst-python/testsuite/overrides_hack.py | 37 +++++++--------- 3 files changed, 39 insertions(+), 54 deletions(-) diff --git a/subprojects/gst-devtools/debug-viewer/GstDebugViewer/Plugins/__init__.py b/subprojects/gst-devtools/debug-viewer/GstDebugViewer/Plugins/__init__.py index 847a1a8a25..22660606d5 100644 --- a/subprojects/gst-devtools/debug-viewer/GstDebugViewer/Plugins/__init__.py +++ b/subprojects/gst-devtools/debug-viewer/GstDebugViewer/Plugins/__init__.py @@ -37,7 +37,7 @@ def load(paths=()): def _load_plugins(path): - import imp + import importlib import glob files = glob.glob(os.path.join(path, "*.py")) @@ -47,8 +47,16 @@ def _load_plugins(path): name = os.path.basename(os.path.splitext(filename)[0]) if name == "__init__": continue - fp, pathname, description = imp.find_module(name, [path]) - module = imp.load_module(name, fp, pathname, description) + + finder = importlib.machinery.PathFinder() + spec = finder.find_spec( + name, + os.environ.get('_GI_OVERRIDES_PATH', '').split(os.pathsep) + ) + if spec is None: + raise ModuleNotFoundError(name) + module = importlib.util.module_from_spec(spec) + yield module diff --git a/subprojects/gst-python/gi/__init__.py b/subprojects/gst-python/gi/__init__.py index 4f356a6ede..18b9b1f147 100644 --- a/subprojects/gst-python/gi/__init__.py +++ b/subprojects/gst-python/gi/__init__.py @@ -1,7 +1,8 @@ import gi import os import sys -import imp +import importlib.util +from importlib.machinery import PathFinder from pathlib import Path # Remove this dummy module the python path and @@ -12,34 +13,17 @@ import gi class GstOverrideImport: - def find_module(self, fullname, path=None, target=None): - if fullname.startswith('gi.overrides'): - fp = None - try: - fp, _, _ = imp.find_module(fullname.split( - '.')[-1], os.environ.get('_GI_OVERRIDES_PATH', '').split(os.pathsep),) - except ImportError: - return None - finally: - if fp: - fp.close() - return self - return None - - def load_module(self, name): - if name in sys.modules: - return sys.modules[name] - - fp, pathname, description = imp.find_module(name.split( - '.')[-1], os.environ.get('_GI_OVERRIDES_PATH', '').split(os.pathsep),) - - try: - module = imp.load_module(name, fp, pathname, description) - finally: - if fp: - fp.close() - sys.modules[name] = module - return module + def find_spec(self, fullname, path, target=None): + if not fullname.startswith("gi.overrides"): + return None + finder = importlib.machinery.PathFinder() + # From find_spec the docs: + # If name is for a submodule (contains a dot), the parent module is automatically imported. + spec = finder.find_spec( + fullname, + os.environ.get('_GI_OVERRIDES_PATH', '').split(os.pathsep) + ) + return spec sys.meta_path.insert(0, GstOverrideImport()) diff --git a/subprojects/gst-python/testsuite/overrides_hack.py b/subprojects/gst-python/testsuite/overrides_hack.py index 19c69d0de5..cc7efd6903 100644 --- a/subprojects/gst-python/testsuite/overrides_hack.py +++ b/subprojects/gst-python/testsuite/overrides_hack.py @@ -1,30 +1,23 @@ import os import sys -import imp +import importlib class GstOverrideImport: - def find_module(self, fullname, path=None): - if fullname in ('gi.overrides.Gst', 'gi.overrides._gi_gst'): - return self - return None - - def load_module(self, name): - if name in sys.modules: - return sys.modules[name] - - fp, pathname, description = imp.find_module(name.split('.')[-1], [ - os.environ.get('GST_OVERRIDE_SRC_PATH'), - os.environ.get('GST_OVERRIDE_BUILD_PATH'), - ]) - - try: - module = imp.load_module(name, fp, pathname, description) - finally: - if fp: - fp.close() - sys.modules[name] = module - return module + def find_spec(self, fullname, path, target=None): + if not (fullname.startswith("gi.overrides.Gst") or fullname.startswith("gi.overrides._gi_gst")): + return None + finder = importlib.machinery.PathFinder() + # From find_spec the docs: + # If name is for a submodule (contains a dot), the parent module is automatically imported. + spec = finder.find_spec( + fullname, + [ + os.environ.get('GST_OVERRIDE_SRC_PATH'), + os.environ.get('GST_OVERRIDE_BUILD_PATH'), + ] + ) + return spec sys.meta_path.insert(0, GstOverrideImport())