diff options
| author | Dylan Baker <dylan@pnwbakers.com> | 2022-07-14 12:59:48 -0700 |
|---|---|---|
| committer | Eli Schwartz <eschwartz93@gmail.com> | 2022-08-17 16:25:36 -0400 |
| commit | 6843f56f6b8e71e75c287de31686913eea5e4a44 (patch) | |
| tree | a92e933d88d48dd2bfd4a1fc2bb652296f053332 /mesonbuild | |
| parent | 2801ead6d3a144f3cf7ae03f61bb463c7aeac0a9 (diff) | |
| download | meson-6843f56f6b8e71e75c287de31686913eea5e4a44.tar.gz | |
modules: use module level information about new and deprecation
Instead of using FeatureNew/FeatureDeprecated in the module.
The goal here is to be able to handle information about modules in a
single place, instead of having to handle it separately. Each module
simply defines some metadata, and then the interpreter handles the rest.
Diffstat (limited to 'mesonbuild')
25 files changed, 114 insertions, 54 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index c89749485..fef8f4b4d 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -599,7 +599,7 @@ class Interpreter(InterpreterBase, HoldableObject): dep = df.lookup(kwargs, force_fallback=True) self.build.stdlibs[for_machine][l] = dep - def _import_module(self, modname: str, required: bool) -> NewExtensionModule: + def _import_module(self, modname: str, required: bool, node: mparser.BaseNode) -> NewExtensionModule: if modname in self.modules: return self.modules[modname] try: @@ -607,11 +607,15 @@ class Interpreter(InterpreterBase, HoldableObject): except ImportError: if required: raise InvalidArguments(f'Module "{modname}" does not exist') - ext_module = NotFoundExtensionModule() + ext_module = NotFoundExtensionModule(modname) else: ext_module = module.initialize(self) assert isinstance(ext_module, (ExtensionModule, NewExtensionModule)) self.build.modules.append(modname) + if ext_module.INFO.added: + FeatureNew.single_use(f'module {ext_module.INFO.name}', ext_module.INFO.added, self.subproject, location=node) + if ext_module.INFO.deprecated: + FeatureDeprecated.single_use(f'module {ext_module.INFO.name}', ext_module.INFO.deprecated, self.subproject, location=node) self.modules[modname] = ext_module return ext_module @@ -627,20 +631,19 @@ class Interpreter(InterpreterBase, HoldableObject): modname = args[0] disabled, required, _ = extract_required_kwarg(kwargs, self.subproject) if disabled: - return NotFoundExtensionModule() + return NotFoundExtensionModule(modname) if modname.startswith('unstable-'): plainname = modname.split('-', 1)[1] try: # check if stable module exists - mod = self._import_module(plainname, required) - # XXX: this is actually not helpful, since it doesn't do a version check + mod = self._import_module(plainname, required, node) mlog.warning(f'Module {modname} is now stable, please use the {plainname} module instead.') return mod except InvalidArguments: mlog.warning(f'Module {modname} has no backwards or forwards compatibility and might not exist in future releases.', location=node) modname = 'unstable_' + plainname - return self._import_module(modname, required) + return self._import_module(modname, required, node) @typed_pos_args('files', varargs=str) @noKwargs diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index 56370d17f..068194026 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -15,6 +15,7 @@ # This file contains the base representation for import('modname') from __future__ import annotations +import dataclasses import typing as T from .. import mesonlib @@ -163,6 +164,17 @@ class ModuleObject(HoldableObject): class MutableModuleObject(ModuleObject): pass + +@dataclasses.dataclass +class ModuleInfo: + + """Metadata about a Module.""" + + name: str + added: T.Optional[str] = None + deprecated: T.Optional[str] = None + + class NewExtensionModule(ModuleObject): """Class for modern modules @@ -170,6 +182,8 @@ class NewExtensionModule(ModuleObject): provides the found method. """ + INFO: ModuleInfo + def __init__(self) -> None: super().__init__() self.methods.update({ @@ -203,6 +217,10 @@ class NotFoundExtensionModule(NewExtensionModule): provides the found method. """ + def __init__(self, name: str) -> None: + super().__init__() + self.INFO = ModuleInfo(name) + @staticmethod def found() -> bool: return False diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py index 1950254e8..326aac6ac 100644 --- a/mesonbuild/modules/cmake.py +++ b/mesonbuild/modules/cmake.py @@ -18,7 +18,7 @@ import os, os.path, pathlib import shutil import typing as T -from . import ExtensionModule, ModuleReturnValue, ModuleObject +from . import ExtensionModule, ModuleReturnValue, ModuleObject, ModuleInfo from .. import build, mesonlib, mlog, dependencies from ..cmake import TargetOptions, cmake_defines_to_args @@ -247,7 +247,8 @@ class CmakeModule(ExtensionModule): cmake_detected = False cmake_root = None - @FeatureNew('CMake Module', '0.50.0') + INFO = ModuleInfo('cmake', '0.50.0') + def __init__(self, interpreter): super().__init__(interpreter) self.methods.update({ diff --git a/mesonbuild/modules/dlang.py b/mesonbuild/modules/dlang.py index d9255d928..7a9b99fd5 100644 --- a/mesonbuild/modules/dlang.py +++ b/mesonbuild/modules/dlang.py @@ -18,17 +18,18 @@ import json import os -from . import ExtensionModule +from . import ExtensionModule, ModuleInfo from .. import dependencies from .. import mlog -from ..interpreterbase import FeatureNew, typed_pos_args +from ..interpreterbase import typed_pos_args from ..mesonlib import Popen_safe, MesonException class DlangModule(ExtensionModule): class_dubbin = None init_dub = False - @FeatureNew('Dlang Module', '0.48.0') + INFO = ModuleInfo('dlang', '0.48.0') + def __init__(self, interpreter): super().__init__(interpreter) self.methods.update({ diff --git a/mesonbuild/modules/fs.py b/mesonbuild/modules/fs.py index d0f5e2e79..f0e3f4c88 100644 --- a/mesonbuild/modules/fs.py +++ b/mesonbuild/modules/fs.py @@ -18,7 +18,7 @@ import os from pathlib import Path, PurePath, PureWindowsPath from .. import mlog -from . import ExtensionModule +from . import ExtensionModule, ModuleInfo from ..mesonlib import ( File, MesonException, @@ -41,7 +41,8 @@ if T.TYPE_CHECKING: class FSModule(ExtensionModule): - @FeatureNew('Fs Module', '0.53.0') + INFO = ModuleInfo('fs', '0.53.0') + def __init__(self, interpreter: 'Interpreter') -> None: super().__init__(interpreter) self.methods.update({ diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 230783ad0..1c21cce97 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -24,7 +24,7 @@ import subprocess import textwrap import typing as T -from . import ExtensionModule +from . import ExtensionModule, ModuleInfo from . import ModuleReturnValue from .. import build from .. import interpreter @@ -272,6 +272,9 @@ gresource_dep_needed_version = '>= 2.51.1' native_glib_version: T.Optional[str] = None class GnomeModule(ExtensionModule): + + INFO = ModuleInfo('gnome') + def __init__(self, interpreter: 'Interpreter') -> None: super().__init__(interpreter) self.gir_dep: T.Optional[Dependency] = None diff --git a/mesonbuild/modules/hotdoc.py b/mesonbuild/modules/hotdoc.py index beb92b843..b354d1793 100644 --- a/mesonbuild/modules/hotdoc.py +++ b/mesonbuild/modules/hotdoc.py @@ -20,10 +20,10 @@ from collections import OrderedDict from mesonbuild import mesonlib from mesonbuild import mlog, build from mesonbuild.coredata import MesonException -from . import ModuleReturnValue +from . import ModuleReturnValue, ModuleInfo from . import ExtensionModule from ..dependencies import Dependency, InternalDependency -from ..interpreterbase import FeatureNew, InvalidArguments, noPosargs, noKwargs, typed_pos_args +from ..interpreterbase import InvalidArguments, noPosargs, noKwargs, typed_pos_args from ..interpreter import CustomTargetHolder from ..programs import ExternalProgram @@ -38,6 +38,7 @@ MIN_HOTDOC_VERSION = '0.8.100' class HotdocTargetBuilder: + def __init__(self, name, state, hotdoc, interpreter, kwargs): self.hotdoc = hotdoc self.build_by_default = kwargs.pop('build_by_default', False) @@ -396,7 +397,9 @@ class HotdocTarget(build.CustomTarget): class HotDocModule(ExtensionModule): - @FeatureNew('Hotdoc Module', '0.48.0') + + INFO = ModuleInfo('hotdoc', '0.48.0') + def __init__(self, interpreter): super().__init__(interpreter) self.hotdoc = ExternalProgram('hotdoc') diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index f5eec96ae..2af11988c 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -16,7 +16,7 @@ from __future__ import annotations from os import path import typing as T -from . import ExtensionModule, ModuleReturnValue +from . import ExtensionModule, ModuleReturnValue, ModuleInfo from .. import build from .. import mesonlib from .. import mlog @@ -124,6 +124,9 @@ PRESET_ARGS = { class I18nModule(ExtensionModule): + + INFO = ModuleInfo('i18n') + def __init__(self, interpreter: 'Interpreter'): super().__init__(interpreter) self.methods.update({ diff --git a/mesonbuild/modules/java.py b/mesonbuild/modules/java.py index a8e5062ca..a48750a03 100644 --- a/mesonbuild/modules/java.py +++ b/mesonbuild/modules/java.py @@ -22,7 +22,7 @@ from mesonbuild.build import CustomTarget, CustomTargetIndex, GeneratedList, Tar from mesonbuild.compilers import detect_compiler_for from mesonbuild.interpreterbase.decorators import ContainerTypeInfo, FeatureDeprecated, FeatureNew, KwargInfo, typed_pos_args, typed_kwargs from mesonbuild.mesonlib import version_compare, MachineChoice -from . import NewExtensionModule, ModuleReturnValue +from . import NewExtensionModule, ModuleReturnValue, ModuleInfo if T.TYPE_CHECKING: from . import ModuleState @@ -30,7 +30,9 @@ if T.TYPE_CHECKING: from ..interpreter import Interpreter class JavaModule(NewExtensionModule): - @FeatureNew('Java Module', '0.60.0') + + INFO = ModuleInfo('java', '0.60.0') + def __init__(self, interpreter: Interpreter): super().__init__() self.methods.update({ diff --git a/mesonbuild/modules/keyval.py b/mesonbuild/modules/keyval.py index 36daea8ca..94db56733 100644 --- a/mesonbuild/modules/keyval.py +++ b/mesonbuild/modules/keyval.py @@ -15,9 +15,9 @@ import os import typing as T -from . import ExtensionModule +from . import ExtensionModule, ModuleInfo from .. import mesonlib -from ..interpreterbase import FeatureNew, noKwargs, typed_pos_args +from ..interpreterbase import noKwargs, typed_pos_args if T.TYPE_CHECKING: from ..interpreter import Interpreter @@ -25,7 +25,8 @@ if T.TYPE_CHECKING: class KeyvalModule(ExtensionModule): - @FeatureNew('Keyval Module', '0.55.0') + INFO = ModuleInfo('keyval', '0.55.0') + def __init__(self, interp: 'Interpreter'): super().__init__(interp) self.methods.update({ diff --git a/mesonbuild/modules/modtest.py b/mesonbuild/modules/modtest.py index e36899f0e..15f823778 100644 --- a/mesonbuild/modules/modtest.py +++ b/mesonbuild/modules/modtest.py @@ -15,7 +15,7 @@ from __future__ import annotations import typing as T -from . import ExtensionModule +from . import ExtensionModule, ModuleInfo from ..interpreterbase import noKwargs, noPosargs if T.TYPE_CHECKING: @@ -25,6 +25,9 @@ if T.TYPE_CHECKING: class TestModule(ExtensionModule): + + INFO = ModuleInfo('modtest') + def __init__(self, interpreter: Interpreter) -> None: super().__init__(interpreter) self.methods.update({ diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index 830341cc1..394b4805d 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -16,7 +16,7 @@ from pathlib import PurePath import os import typing as T -from . import ExtensionModule +from . import ExtensionModule, ModuleInfo from . import ModuleReturnValue from .. import build from .. import dependencies @@ -276,6 +276,9 @@ class DependenciesHelper: self.cflags = _fn(self.cflags) class PkgConfigModule(ExtensionModule): + + INFO = ModuleInfo('pkgconfig') + def __init__(self, interpreter): super().__init__(interpreter) self.methods.update({ diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py index 5a6daa0d9..91443b804 100644 --- a/mesonbuild/modules/python.py +++ b/mesonbuild/modules/python.py @@ -20,7 +20,7 @@ import os import shutil import typing as T -from . import ExtensionModule +from . import ExtensionModule, ModuleInfo from .. import mesonlib from .. import mlog from ..coredata import UserFeatureOption @@ -663,7 +663,8 @@ class PythonInstallation(ExternalProgramHolder): class PythonModule(ExtensionModule): - @FeatureNew('Python Module', '0.46.0') + INFO = ModuleInfo('python', '0.46.0') + def __init__(self, interpreter: 'Interpreter') -> None: super().__init__(interpreter) self.installations: T.Dict[str, ExternalProgram] = {} diff --git a/mesonbuild/modules/python3.py b/mesonbuild/modules/python3.py index 1e7463c70..52f8531f1 100644 --- a/mesonbuild/modules/python3.py +++ b/mesonbuild/modules/python3.py @@ -15,15 +15,16 @@ import sysconfig from .. import mesonlib -from . import ExtensionModule -from ..interpreterbase import typed_pos_args, noPosargs, noKwargs, permittedKwargs, FeatureDeprecated, FeatureNew +from . import ExtensionModule, ModuleInfo +from ..interpreterbase import typed_pos_args, noPosargs, noKwargs, permittedKwargs from ..build import known_shmod_kwargs from ..programs import ExternalProgram class Python3Module(ExtensionModule): - @FeatureNew('python3 module', '0.38.0') - @FeatureDeprecated('python3 module', '0.48.0') + + INFO = ModuleInfo('python3', '0.38.0', deprecated='0.48.0') + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.methods.update({ diff --git a/mesonbuild/modules/qt4.py b/mesonbuild/modules/qt4.py index e85a1506f..b8948f7f4 100644 --- a/mesonbuild/modules/qt4.py +++ b/mesonbuild/modules/qt4.py @@ -13,10 +13,13 @@ # limitations under the License. from .qt import QtBaseModule +from . import ModuleInfo class Qt4Module(QtBaseModule): + INFO = ModuleInfo('qt4') + def __init__(self, interpreter): QtBaseModule.__init__(self, interpreter, qt_version=4) diff --git a/mesonbuild/modules/qt5.py b/mesonbuild/modules/qt5.py index 873c2dbeb..3933ea033 100644 --- a/mesonbuild/modules/qt5.py +++ b/mesonbuild/modules/qt5.py @@ -13,10 +13,13 @@ # limitations under the License. from .qt import QtBaseModule +from . import ModuleInfo class Qt5Module(QtBaseModule): + INFO = ModuleInfo('qt5') + def __init__(self, interpreter): QtBaseModule.__init__(self, interpreter, qt_version=5) diff --git a/mesonbuild/modules/qt6.py b/mesonbuild/modules/qt6.py index 3cfe2439c..66fc43f27 100644 --- a/mesonbuild/modules/qt6.py +++ b/mesonbuild/modules/qt6.py @@ -13,12 +13,13 @@ # limitations under the License. from .qt import QtBaseModule -from ..interpreterbase import FeatureNew +from . import ModuleInfo class Qt6Module(QtBaseModule): - @FeatureNew('Qt6 Module', '0.57.0') + INFO = ModuleInfo('qt6', '0.57.0') + def __init__(self, interpreter): QtBaseModule.__init__(self, interpreter, qt_version=6) diff --git a/mesonbuild/modules/sourceset.py b/mesonbuild/modules/sourceset.py index f091f6e56..7bec2b718 100644 --- a/mesonbuild/modules/sourceset.py +++ b/mesonbuild/modules/sourceset.py @@ -15,7 +15,7 @@ from __future__ import annotations import typing as T -from . import ExtensionModule, ModuleObject, MutableModuleObject +from . import ExtensionModule, ModuleObject, MutableModuleObject, ModuleInfo from .. import build from .. import dependencies from .. import mesonlib @@ -289,7 +289,9 @@ class SourceFilesObject(ModuleObject): return list(self.files.deps) class SourceSetModule(ExtensionModule): - @FeatureNew('SourceSet module', '0.51.0') + + INFO = ModuleInfo('sourceset', '0.51.0') + def __init__(self, interpreter: Interpreter): super().__init__(interpreter) self.methods.update({ diff --git a/mesonbuild/modules/unstable_cuda.py b/mesonbuild/modules/unstable_cuda.py index 08dc016fe..e2340fc2b 100644 --- a/mesonbuild/modules/unstable_cuda.py +++ b/mesonbuild/modules/unstable_cuda.py @@ -19,11 +19,11 @@ import re from ..mesonlib import version_compare from ..compilers import CudaCompiler -from . import NewExtensionModule +from . import NewExtensionModule, ModuleInfo from ..interpreterbase import ( flatten, permittedKwargs, noKwargs, - InvalidArguments, FeatureNew + InvalidArguments ) if T.TYPE_CHECKING: @@ -32,7 +32,8 @@ if T.TYPE_CHECKING: class CudaModule(NewExtensionModule): - @FeatureNew('CUDA module', '0.50.0') + INFO = ModuleInfo('CUDA', '0.50.0') + def __init__(self, *args, **kwargs): super().__init__() self.methods.update({ diff --git a/mesonbuild/modules/unstable_external_project.py b/mesonbuild/modules/unstable_external_project.py index 82e51e88c..74279a694 100644 --- a/mesonbuild/modules/unstable_external_project.py +++ b/mesonbuild/modules/unstable_external_project.py @@ -18,7 +18,7 @@ import shlex import subprocess import typing as T -from . import ExtensionModule, ModuleReturnValue, NewExtensionModule +from . import ExtensionModule, ModuleReturnValue, NewExtensionModule, ModuleInfo from .. import mlog, build from ..compilers.compilers import CFLAGS_MAPPING from ..envconfig import ENV_VAR_PROG_MAP @@ -273,7 +273,9 @@ class ExternalProject(NewExtensionModule): class ExternalProjectModule(ExtensionModule): - @FeatureNew('External build system Module', '0.56.0') + + INFO = ModuleInfo('External build system', '0.56.0') + def __init__(self, interpreter: 'Interpreter'): super().__init__(interpreter) self.methods.update({'add_project': self.add_project, diff --git a/mesonbuild/modules/unstable_icestorm.py b/mesonbuild/modules/unstable_icestorm.py index b4ddd5c53..50809b9a9 100644 --- a/mesonbuild/modules/unstable_icestorm.py +++ b/mesonbuild/modules/unstable_icestorm.py @@ -16,11 +16,10 @@ from __future__ import annotations import itertools import typing as T -from . import ExtensionModule, ModuleReturnValue +from . import ExtensionModule, ModuleReturnValue, ModuleInfo from .. import build from .. import mesonlib from ..interpreter.type_checking import CT_INPUT_KW -from ..interpreterbase import FeatureNew from ..interpreterbase.decorators import KwargInfo, typed_kwargs, typed_pos_args if T.TYPE_CHECKING: @@ -37,7 +36,8 @@ if T.TYPE_CHECKING: class IceStormModule(ExtensionModule): - @FeatureNew('FPGA/Icestorm Module', '0.45.0') + INFO = ModuleInfo('FPGA/Icestorm', '0.45.0') + def __init__(self, interpreter: Interpreter) -> None: super().__init__(interpreter) self.tools: T.Dict[str, ExternalProgram] = {} diff --git a/mesonbuild/modules/unstable_rust.py b/mesonbuild/modules/unstable_rust.py index e31a69701..cc0620d88 100644 --- a/mesonbuild/modules/unstable_rust.py +++ b/mesonbuild/modules/unstable_rust.py @@ -15,12 +15,12 @@ import os import typing as T -from . import ExtensionModule, ModuleReturnValue +from . import ExtensionModule, ModuleReturnValue, ModuleInfo from .. import mlog from ..build import BothLibraries, BuildTarget, CustomTargetIndex, Executable, ExtractedObjects, GeneratedList, IncludeDirs, CustomTarget, StructuredSources from ..dependencies import Dependency, ExternalLibrary from ..interpreter.interpreter import TEST_KWARGS, OUTPUT_KW -from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, FeatureNew, typed_kwargs, typed_pos_args, noPosargs +from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noPosargs from ..mesonlib import File if T.TYPE_CHECKING: @@ -50,7 +50,8 @@ class RustModule(ExtensionModule): """A module that holds helper functions for rust.""" - @FeatureNew('rust module', '0.57.0') + INFO = ModuleInfo('rust', '0.57.0') + def __init__(self, interpreter: 'Interpreter') -> None: super().__init__(interpreter) self._bindgen_bin: T.Optional['ExternalProgram'] = None diff --git a/mesonbuild/modules/unstable_simd.py b/mesonbuild/modules/unstable_simd.py index 8715a149b..67663805b 100644 --- a/mesonbuild/modules/unstable_simd.py +++ b/mesonbuild/modules/unstable_simd.py @@ -15,13 +15,12 @@ from .. import mesonlib, compilers, mlog from .. import build -from . import ExtensionModule - -from ..interpreterbase import FeatureNew +from . import ExtensionModule, ModuleInfo class SimdModule(ExtensionModule): - @FeatureNew('SIMD module', '0.42.0') + INFO = ModuleInfo('SIMD', '0.42.0') + def __init__(self, interpreter): super().__init__(interpreter) # FIXME add Altivec and AVX512. diff --git a/mesonbuild/modules/unstable_wayland.py b/mesonbuild/modules/unstable_wayland.py index 94c11f140..392e1a770 100644 --- a/mesonbuild/modules/unstable_wayland.py +++ b/mesonbuild/modules/unstable_wayland.py @@ -16,10 +16,10 @@ from __future__ import annotations import os import typing as T -from . import ExtensionModule, ModuleReturnValue +from . import ExtensionModule, ModuleReturnValue, ModuleInfo from ..build import CustomTarget from ..interpreter.type_checking import NoneType, in_set_validator -from ..interpreterbase import FeatureNew, typed_pos_args, typed_kwargs, KwargInfo +from ..interpreterbase import typed_pos_args, typed_kwargs, KwargInfo from ..mesonlib import File, MesonException if T.TYPE_CHECKING: @@ -45,7 +45,8 @@ if T.TYPE_CHECKING: class WaylandModule(ExtensionModule): - @FeatureNew('wayland module', '0.62.0') + INFO = ModuleInfo('wayland', '0.62.0') + def __init__(self, interpreter: Interpreter) -> None: super().__init__(interpreter) diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py index 58a08a7a5..17ee5f10c 100644 --- a/mesonbuild/modules/windows.py +++ b/mesonbuild/modules/windows.py @@ -18,7 +18,7 @@ import re import typing as T -from . import ExtensionModule +from . import ExtensionModule, ModuleInfo from . import ModuleReturnValue from .. import mesonlib, build from .. import mlog @@ -55,6 +55,9 @@ class ResourceCompilerType(enum.Enum): wrc = 3 class WindowsModule(ExtensionModule): + + INFO = ModuleInfo('windows') + def __init__(self, interpreter: 'Interpreter'): super().__init__(interpreter) self._rescomp: T.Optional[T.Tuple[ExternalProgram, ResourceCompilerType]] = None |
