diff options
author | Massimiliano Culpo <massimiliano.culpo@gmail.com> | 2018-03-12 09:07:08 +0100 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2018-03-12 17:07:08 +0900 |
commit | a1c8ce82f2ac46278a5716fa92d4d06df6f49caf (patch) | |
tree | 6757bd1dda41b8d21932ee26085038d171430975 | |
parent | a4ed76c2071d4dfd721adefe1f5702fd210df73f (diff) | |
download | spack-a1c8ce82f2ac46278a5716fa92d4d06df6f49caf.tar.gz spack-a1c8ce82f2ac46278a5716fa92d4d06df6f49caf.tar.bz2 spack-a1c8ce82f2ac46278a5716fa92d4d06df6f49caf.tar.xz spack-a1c8ce82f2ac46278a5716fa92d4d06df6f49caf.zip |
Constructing a SpecBuildInterface from another gives no inconsistent MRO (#7457)
fixes #7239
-rw-r--r-- | lib/spack/llnl/util/lang.py | 14 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize.py | 21 |
2 files changed, 34 insertions, 1 deletions
diff --git a/lib/spack/llnl/util/lang.py b/lib/spack/llnl/util/lang.py index 7189b6c0f3..e586bc268d 100644 --- a/lib/spack/llnl/util/lang.py +++ b/lib/spack/llnl/util/lang.py @@ -458,5 +458,17 @@ class ObjectWrapper(object): def __init__(self, wrapped_object): wrapped_cls = type(wrapped_object) wrapped_name = wrapped_cls.__name__ - self.__class__ = type(wrapped_name, (type(self), wrapped_cls), {}) + + # If the wrapped object is already an ObjectWrapper, or a derived class + # of it, adding type(self) in front of type(wrapped_object) + # results in an inconsistent MRO. + # + # TODO: the implementation below doesn't account for the case where we + # TODO: have different base classes of ObjectWrapper, say A and B, and + # TODO: we want to wrap an instance of A with B. + if type(self) not in wrapped_cls.__mro__: + self.__class__ = type(wrapped_name, (type(self), wrapped_cls), {}) + else: + self.__class__ = type(wrapped_name, (wrapped_cls,), {}) + self.__dict__ = wrapped_object.__dict__ diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index 2611c91f87..2482452208 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -23,8 +23,10 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## import pytest +import llnl.util.lang import spack import spack.architecture + from spack.concretize import find_spec from spack.spec import Spec, CompilerSpec from spack.spec import ConflictsInSpecError, SpecError @@ -444,3 +446,22 @@ class TestConcretize(object): s._concrete = False assert not s.concrete + + @pytest.mark.regression('7239') + def test_regression_issue_7239(self): + # Constructing a SpecBuildInterface from another SpecBuildInterface + # results in an inconsistent MRO + + # Normal Spec + s = Spec('mpileaks') + s.concretize() + + assert llnl.util.lang.ObjectWrapper not in type(s).__mro__ + + # Spec wrapped in a build interface + build_interface = s['mpileaks'] + assert llnl.util.lang.ObjectWrapper in type(build_interface).__mro__ + + # Mimics asking the build interface from a build interface + build_interface = s['mpileaks']['mpileaks'] + assert llnl.util.lang.ObjectWrapper in type(build_interface).__mro__ |