Constructing a SpecBuildInterface from another gives no inconsistent MRO (#7457)
fixes #7239
This commit is contained in:
		 Massimiliano Culpo
					Massimiliano Culpo
				
			
				
					committed by
					
						 Todd Gamblin
						Todd Gamblin
					
				
			
			
				
	
			
			
			 Todd Gamblin
						Todd Gamblin
					
				
			
						parent
						
							a4ed76c207
						
					
				
				
					commit
					a1c8ce82f2
				
			| @@ -458,5 +458,17 @@ class ObjectWrapper(object): | |||||||
|     def __init__(self, wrapped_object): |     def __init__(self, wrapped_object): | ||||||
|         wrapped_cls = type(wrapped_object) |         wrapped_cls = type(wrapped_object) | ||||||
|         wrapped_name = wrapped_cls.__name__ |         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__ |         self.__dict__ = wrapped_object.__dict__ | ||||||
|   | |||||||
| @@ -23,8 +23,10 @@ | |||||||
| # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| import pytest | import pytest | ||||||
|  | import llnl.util.lang | ||||||
| import spack | import spack | ||||||
| import spack.architecture | import spack.architecture | ||||||
|  |  | ||||||
| from spack.concretize import find_spec | from spack.concretize import find_spec | ||||||
| from spack.spec import Spec, CompilerSpec | from spack.spec import Spec, CompilerSpec | ||||||
| from spack.spec import ConflictsInSpecError, SpecError | from spack.spec import ConflictsInSpecError, SpecError | ||||||
| @@ -444,3 +446,22 @@ def test_regression_issue_4492(self): | |||||||
|         s._concrete = False |         s._concrete = False | ||||||
|  |  | ||||||
|         assert not s.concrete |         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__ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user