Constructing a SpecBuildInterface from another gives no inconsistent MRO (#7457)

fixes #7239
This commit is contained in:
Massimiliano Culpo 2018-03-12 09:07:08 +01:00 committed by Todd Gamblin
parent a4ed76c207
commit a1c8ce82f2
2 changed files with 34 additions and 1 deletions

View File

@ -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__

View File

@ -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 @@ def test_regression_issue_4492(self):
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__