Source code for mantidimaging.core.operations.loader
# Copyright (C) 2023 ISIS Rutherford Appleton Laboratory UKRI
# SPDX - License - Identifier: GPL-3.0-or-later
from __future__ import annotations
import os
import pkgutil
import sys
from typing import List, Protocol, cast, Union, TYPE_CHECKING
from importlib.machinery import FileFinder, ModuleSpec
from importlib.abc import Loader
if TYPE_CHECKING:
from PyInstaller.loader.pyimod02_importers import FrozenImporter
from mantidimaging.core.operations.base_filter import BaseFilter
MODULES_OPERATIONS: dict[str, Union['FrozenImporter', Loader]] = {}
if not MODULES_OPERATIONS:
for finder, module_name, _ in pkgutil.walk_packages([os.path.dirname(__file__)]):
if getattr(sys, 'frozen', False):
# If we're running a PyInstaller executable then we will get back a FrozenImporter object instead of a
# FileFinder. FrozenImporter implements load_module directly, but needs to use the full import name for
# the module to load it from the PYZ archive.
assert hasattr(finder, 'load_module')
MODULES_OPERATIONS[f'mantidimaging.core.operations.{module_name}'] = finder
else:
assert isinstance(finder, FileFinder)
spec = finder.find_spec(module_name)
assert isinstance(spec, ModuleSpec)
assert isinstance(spec.loader, Loader)
MODULES_OPERATIONS[module_name] = spec.loader
[docs]class OperationModule(Protocol):
FILTER_CLASS: BaseFilter
[docs]def load_filter_packages(ignored_packages=None) -> List[BaseFilter]:
"""
Imports all subpackages with a FILTER_CLASS attribute, which should be an extension of BaseFilter.
These classes are then used to provide the names, required inputs, and behaviour to execute
then named filter on a stack of images.
:param ignored_packages: List of ignore rules
"""
operation_modules = []
for name in MODULES_OPERATIONS.keys():
if not ignored_packages or not any([ignore in name for ignore in ignored_packages]):
module = MODULES_OPERATIONS[name].load_module(name)
if hasattr(module, 'FILTER_CLASS'):
operation_module = cast("OperationModule", module)
operation_modules.append(operation_module.FILTER_CLASS)
return operation_modules