From a3645fd372d42dbd1affa38af958a3d30aa10d33 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Fri, 21 Feb 2025 09:54:22 +0100 Subject: [PATCH] Make BaseConfiguration pickleable (#47545) Signed-off-by: Massimiliano Culpo --- lib/spack/spack/modules/common.py | 19 +++++++++---------- lib/spack/spack/test/modules/common.py | 8 ++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/spack/spack/modules/common.py b/lib/spack/spack/modules/common.py index 2ce05a818f4..702d473c556 100644 --- a/lib/spack/spack/modules/common.py +++ b/lib/spack/spack/modules/common.py @@ -330,18 +330,17 @@ class BaseConfiguration: default_projections = {"all": "{name}/{version}-{compiler.name}-{compiler.version}"} def __init__(self, spec: spack.spec.Spec, module_set_name: str, explicit: bool) -> None: - # Module where type(self) is defined - m = inspect.getmodule(self) - assert m is not None # make mypy happy - self.module = m # Spec for which we want to generate a module file self.spec = spec self.name = module_set_name self.explicit = explicit - # Dictionary of configuration options that should be applied - # to the spec + # Dictionary of configuration options that should be applied to the spec self.conf = merge_config_rules(self.module.configuration(self.name), self.spec) + @property + def module(self): + return inspect.getmodule(self) + @property def projections(self): """Projection from specs to module names""" @@ -775,10 +774,6 @@ def __init__( ) -> None: self.spec = spec - # This class is meant to be derived. Get the module of the - # actual writer. - self.module = inspect.getmodule(self) - assert self.module is not None # make mypy happy m = self.module # Create the triplet of configuration/layout/context @@ -816,6 +811,10 @@ def __init__( name = type(self).__name__ raise ModulercHeaderNotDefined(msg.format(name)) + @property + def module(self): + return inspect.getmodule(self) + def _get_template(self): """Gets the template that will be rendered for this spec.""" # Get templates and put them in the order of importance: diff --git a/lib/spack/spack/test/modules/common.py b/lib/spack/spack/test/modules/common.py index 76f64a22f52..0d858806e5d 100644 --- a/lib/spack/spack/test/modules/common.py +++ b/lib/spack/spack/test/modules/common.py @@ -2,6 +2,7 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import os +import pickle import stat import pytest @@ -223,3 +224,10 @@ def test_check_module_set_name(mutable_config): with pytest.raises(spack.error.ConfigError, match=msg): spack.cmd.modules.check_module_set_name("third") + + +@pytest.mark.parametrize("module_type", ["tcl", "lmod"]) +def test_module_writers_are_pickleable(default_mock_concretization, module_type): + s = default_mock_concretization("mpileaks") + writer = spack.modules.module_types[module_type](s, "default") + assert pickle.loads(pickle.dumps(writer)).spec == s