diff --git a/lib/spack/spack/subprocess_context.py b/lib/spack/spack/subprocess_context.py index 02c135f3469..c7d39054eb1 100644 --- a/lib/spack/spack/subprocess_context.py +++ b/lib/spack/spack/subprocess_context.py @@ -17,6 +17,7 @@ import pickle import pydoc from types import ModuleType +from typing import Any import spack.config import spack.environment @@ -35,11 +36,17 @@ def append_patch(patch): patches.append(patch) -def serialize(obj): - serialized_obj = io.BytesIO() - pickle.dump(obj, serialized_obj) - serialized_obj.seek(0) - return serialized_obj +def serialize(pkg) -> io.BytesIO: + serialized_pkg = io.BytesIO() + pickle.dump(pkg, serialized_pkg) + serialized_pkg.seek(0) + return serialized_pkg + + +def deserialize(serialized_pkg: io.BytesIO) -> Any: + pkg = pickle.load(serialized_pkg) + pkg.spec._package = pkg + return pkg class SpackTestProcess: @@ -87,8 +94,7 @@ def restore(self): # Order of operation is important, since the package might be retrieved # from a repo defined within the environment configuration - pkg = pickle.load(self.serialized_pkg) if self.serialize else self.pkg - return pkg + return deserialize(self.serialized_pkg) if self.serialize else self.pkg class GlobalStateMarshaler: diff --git a/lib/spack/spack/test/package_class.py b/lib/spack/spack/test/package_class.py index 5b2abefb34f..0300b21dfa8 100644 --- a/lib/spack/spack/test/package_class.py +++ b/lib/spack/spack/test/package_class.py @@ -24,6 +24,7 @@ import spack.package_base import spack.spec import spack.store +import spack.subprocess_context from spack.build_systems.generic import Package from spack.error import InstallError from spack.solver.input_analysis import NoStaticAnalysis, StaticAnalysis @@ -323,3 +324,11 @@ def test_package_subscript(default_mock_concretization): # Subscript on concrete for d in root.traverse(): assert isinstance(root_pkg[d.name], spack.package_base.PackageBase) + + +def test_deserialize_preserves_package_attribute(default_mock_concretization): + x = default_mock_concretization("mpileaks").package + assert x.spec._package is x + + y = spack.subprocess_context.deserialize(spack.subprocess_context.serialize(x)) + assert y.spec._package is y