Ensure PythonExtension is consistent when finding externals (#40012)
PythonExtension is a base class for PythonPackage, and is meant to be used for any package that is a Python extension but is not built using "python_pip". The "update_external_dependency" method in the base class calls another method that is defined in the derived class. Push "get_external_python_for_prefix" up in the hierarchy to make method calls consistent.
This commit is contained in:
		 Massimiliano Culpo
					Massimiliano Culpo
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							6a249944f5
						
					
				
				
					commit
					34402beeb7
				
			| @@ -229,6 +229,47 @@ def update_external_dependencies(self, extendee_spec=None): | |||||||
|                     python._mark_concrete() |                     python._mark_concrete() | ||||||
|             self.spec.add_dependency_edge(python, depflag=dt.BUILD | dt.LINK | dt.RUN, virtuals=()) |             self.spec.add_dependency_edge(python, depflag=dt.BUILD | dt.LINK | dt.RUN, virtuals=()) | ||||||
| 
 | 
 | ||||||
|  |     def get_external_python_for_prefix(self): | ||||||
|  |         """ | ||||||
|  |         For an external package that extends python, find the most likely spec for the python | ||||||
|  |         it depends on. | ||||||
|  | 
 | ||||||
|  |         First search: an "installed" external that shares a prefix with this package | ||||||
|  |         Second search: a configured external that shares a prefix with this package | ||||||
|  |         Third search: search this prefix for a python package | ||||||
|  | 
 | ||||||
|  |         Returns: | ||||||
|  |           spack.spec.Spec: The external Spec for python most likely to be compatible with self.spec | ||||||
|  |         """ | ||||||
|  |         python_externals_installed = [ | ||||||
|  |             s for s in spack.store.STORE.db.query("python") if s.prefix == self.spec.external_path | ||||||
|  |         ] | ||||||
|  |         if python_externals_installed: | ||||||
|  |             return python_externals_installed[0] | ||||||
|  | 
 | ||||||
|  |         python_external_config = spack.config.get("packages:python:externals", []) | ||||||
|  |         python_externals_configured = [ | ||||||
|  |             spack.spec.parse_with_version_concrete(item["spec"]) | ||||||
|  |             for item in python_external_config | ||||||
|  |             if item["prefix"] == self.spec.external_path | ||||||
|  |         ] | ||||||
|  |         if python_externals_configured: | ||||||
|  |             return python_externals_configured[0] | ||||||
|  | 
 | ||||||
|  |         python_externals_detection = spack.detection.by_path( | ||||||
|  |             ["python"], path_hints=[self.spec.external_path] | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         python_externals_detected = [ | ||||||
|  |             d.spec | ||||||
|  |             for d in python_externals_detection.get("python", []) | ||||||
|  |             if d.prefix == self.spec.external_path | ||||||
|  |         ] | ||||||
|  |         if python_externals_detected: | ||||||
|  |             return python_externals_detected[0] | ||||||
|  | 
 | ||||||
|  |         raise StopIteration("No external python could be detected for %s to depend on" % self.spec) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class PythonPackage(PythonExtension): | class PythonPackage(PythonExtension): | ||||||
|     """Specialized class for packages that are built using pip.""" |     """Specialized class for packages that are built using pip.""" | ||||||
| @@ -274,47 +315,6 @@ def list_url(cls): | |||||||
|             name = cls.pypi.split("/")[0] |             name = cls.pypi.split("/")[0] | ||||||
|             return "https://pypi.org/simple/" + name + "/" |             return "https://pypi.org/simple/" + name + "/" | ||||||
| 
 | 
 | ||||||
|     def get_external_python_for_prefix(self): |  | ||||||
|         """ |  | ||||||
|         For an external package that extends python, find the most likely spec for the python |  | ||||||
|         it depends on. |  | ||||||
| 
 |  | ||||||
|         First search: an "installed" external that shares a prefix with this package |  | ||||||
|         Second search: a configured external that shares a prefix with this package |  | ||||||
|         Third search: search this prefix for a python package |  | ||||||
| 
 |  | ||||||
|         Returns: |  | ||||||
|           spack.spec.Spec: The external Spec for python most likely to be compatible with self.spec |  | ||||||
|         """ |  | ||||||
|         python_externals_installed = [ |  | ||||||
|             s for s in spack.store.STORE.db.query("python") if s.prefix == self.spec.external_path |  | ||||||
|         ] |  | ||||||
|         if python_externals_installed: |  | ||||||
|             return python_externals_installed[0] |  | ||||||
| 
 |  | ||||||
|         python_external_config = spack.config.get("packages:python:externals", []) |  | ||||||
|         python_externals_configured = [ |  | ||||||
|             spack.spec.parse_with_version_concrete(item["spec"]) |  | ||||||
|             for item in python_external_config |  | ||||||
|             if item["prefix"] == self.spec.external_path |  | ||||||
|         ] |  | ||||||
|         if python_externals_configured: |  | ||||||
|             return python_externals_configured[0] |  | ||||||
| 
 |  | ||||||
|         python_externals_detection = spack.detection.by_path( |  | ||||||
|             ["python"], path_hints=[self.spec.external_path] |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|         python_externals_detected = [ |  | ||||||
|             d.spec |  | ||||||
|             for d in python_externals_detection.get("python", []) |  | ||||||
|             if d.prefix == self.spec.external_path |  | ||||||
|         ] |  | ||||||
|         if python_externals_detected: |  | ||||||
|             return python_externals_detected[0] |  | ||||||
| 
 |  | ||||||
|         raise StopIteration("No external python could be detected for %s to depend on" % self.spec) |  | ||||||
| 
 |  | ||||||
|     @property |     @property | ||||||
|     def headers(self): |     def headers(self): | ||||||
|         """Discover header files in platlib.""" |         """Discover header files in platlib.""" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user