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 <jordan@centricular.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5633>
This commit is contained in:
Edward Hervey 2024-01-04 13:43:20 +00:00 committed by Edward Hervey
parent 0b65c0ead5
commit 7c68ef354b
3 changed files with 39 additions and 54 deletions

View file

@ -37,7 +37,7 @@ def load(paths=()):
def _load_plugins(path): def _load_plugins(path):
import imp import importlib
import glob import glob
files = glob.glob(os.path.join(path, "*.py")) 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]) name = os.path.basename(os.path.splitext(filename)[0])
if name == "__init__": if name == "__init__":
continue 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 yield module

View file

@ -1,7 +1,8 @@
import gi import gi
import os import os
import sys import sys
import imp import importlib.util
from importlib.machinery import PathFinder
from pathlib import Path from pathlib import Path
# Remove this dummy module the python path and # Remove this dummy module the python path and
@ -12,34 +13,17 @@ import gi
class GstOverrideImport: class GstOverrideImport:
def find_module(self, fullname, path=None, target=None): def find_spec(self, fullname, path, target=None):
if fullname.startswith('gi.overrides'): if not 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 return None
finally: finder = importlib.machinery.PathFinder()
if fp: # From find_spec the docs:
fp.close() # If name is for a submodule (contains a dot), the parent module is automatically imported.
return self spec = finder.find_spec(
return None fullname,
os.environ.get('_GI_OVERRIDES_PATH', '').split(os.pathsep)
def load_module(self, name): )
if name in sys.modules: return spec
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
sys.meta_path.insert(0, GstOverrideImport()) sys.meta_path.insert(0, GstOverrideImport())

View file

@ -1,30 +1,23 @@
import os import os
import sys import sys
import imp import importlib
class GstOverrideImport: class GstOverrideImport:
def find_module(self, fullname, path=None): def find_spec(self, fullname, path, target=None):
if fullname in ('gi.overrides.Gst', 'gi.overrides._gi_gst'): if not (fullname.startswith("gi.overrides.Gst") or fullname.startswith("gi.overrides._gi_gst")):
return self
return None return None
finder = importlib.machinery.PathFinder()
def load_module(self, name): # From find_spec the docs:
if name in sys.modules: # If name is for a submodule (contains a dot), the parent module is automatically imported.
return sys.modules[name] spec = finder.find_spec(
fullname,
fp, pathname, description = imp.find_module(name.split('.')[-1], [ [
os.environ.get('GST_OVERRIDE_SRC_PATH'), os.environ.get('GST_OVERRIDE_SRC_PATH'),
os.environ.get('GST_OVERRIDE_BUILD_PATH'), os.environ.get('GST_OVERRIDE_BUILD_PATH'),
]) ]
)
try: return spec
module = imp.load_module(name, fp, pathname, description)
finally:
if fp:
fp.close()
sys.modules[name] = module
return module
sys.meta_path.insert(0, GstOverrideImport()) sys.meta_path.insert(0, GstOverrideImport())