From e9d5b011446407e6c8f0eb02ecf680731a027d6f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 6 Nov 2023 11:45:45 +0100 Subject: [PATCH] osbuild: add new testutil.imports module to help test stages This commit adds `osbuild.testutil.imports.import_module_from_path` that can be used to import arbitrary python source files. This allows importing files from the stages directory that have a non python friendly filename like `org.osbuild.kickstart`. --- osbuild/testutil/__init__.py | 3 +++ osbuild/testutil/imports.py | 27 +++++++++++++++++++++++++++ test/mod/test_testutil_imports.py | 17 +++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 osbuild/testutil/__init__.py create mode 100644 osbuild/testutil/imports.py create mode 100644 test/mod/test_testutil_imports.py diff --git a/osbuild/testutil/__init__.py b/osbuild/testutil/__init__.py new file mode 100644 index 0000000000..09d6d43b24 --- /dev/null +++ b/osbuild/testutil/__init__.py @@ -0,0 +1,3 @@ +""" +Test related utilities +""" diff --git a/osbuild/testutil/imports.py b/osbuild/testutil/imports.py new file mode 100644 index 0000000000..3fb14aeeef --- /dev/null +++ b/osbuild/testutil/imports.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +""" +Import related utilities +""" +import importlib +from types import ModuleType + + +def import_module_from_path(fullname, path: str) -> ModuleType: + """import_module_from_path imports the given path as a python module + + This helper is useful when importing things that are not in the + import path or have invalid python import filenames, e.g. all + filenames in the stages/ dir of osbuild. + + Keyword arguments: + fullname -- The absolute name of the module (can be arbitrary, used on in ModuleSpec.name) + path -- The full path to the python file + """ + loader = importlib.machinery.SourceFileLoader(fullname, path) + spec = importlib.util.spec_from_loader(loader.name, loader) + if spec is None: + # mypy warns that spec might be None so handle it + raise ImportError(f"cannot import {fullname} from {path}, got None as the spec") + mod = importlib.util.module_from_spec(spec) + loader.exec_module(mod) + return mod diff --git a/test/mod/test_testutil_imports.py b/test/mod/test_testutil_imports.py new file mode 100644 index 0000000000..8b8e9a06f9 --- /dev/null +++ b/test/mod/test_testutil_imports.py @@ -0,0 +1,17 @@ +# +# Tests for the 'osbuild.util.testutil' module. +# +import os.path +import tempfile + +import pytest + +from osbuild.testutil.imports import import_module_from_path + + +canary = "import-went-okay" + + +def test_import_module_from_path_happy(): + mod = import_module_from_path("myself", __file__) + assert mod.canary == "import-went-okay"