summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2018-03-12 09:07:08 +0100
committerTodd Gamblin <tgamblin@llnl.gov>2018-03-12 17:07:08 +0900
commita1c8ce82f2ac46278a5716fa92d4d06df6f49caf (patch)
tree6757bd1dda41b8d21932ee26085038d171430975
parenta4ed76c2071d4dfd721adefe1f5702fd210df73f (diff)
downloadspack-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.py14
-rw-r--r--lib/spack/spack/test/concretize.py21
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__