bugfix: make _source_single_file work in venvs (#14569)
				
					
				
			Using `sys.executable` to run Python in a sub-shell doesn't always work in a virtual environment as the `sys.executable` Python is not necessarily compatible with any loaded spack/other virtual environment. - revert use of sys.executable to print out subshell environment (#14496) - try instead to use an available python, then if there *is not* one, use `sys.executable` - this addresses RHEL8 (where there is no `python` and `PYTHONHOME` issue in a simpler way
This commit is contained in:
		
				
					committed by
					
						
						Todd Gamblin
					
				
			
			
				
	
			
			
			
						parent
						
							d646c8d8d5
						
					
				
				
					commit
					4d7d657366
				
			@@ -17,7 +17,6 @@
 | 
			
		||||
 | 
			
		||||
import llnl.util.tty as tty
 | 
			
		||||
import spack.util.executable as executable
 | 
			
		||||
from spack.util.module_cmd import py_cmd
 | 
			
		||||
 | 
			
		||||
from llnl.util.lang import dedupe
 | 
			
		||||
 | 
			
		||||
@@ -919,8 +918,14 @@ def _source_single_file(file_and_args, environment):
 | 
			
		||||
        source_file.extend(x for x in file_and_args)
 | 
			
		||||
        source_file = ' '.join(source_file)
 | 
			
		||||
 | 
			
		||||
        dump_environment = 'PYTHONHOME="{0}" "{1}" -c "{2}"'.format(
 | 
			
		||||
            sys.prefix, sys.executable, py_cmd)
 | 
			
		||||
        # If the environment contains 'python' use it, if not
 | 
			
		||||
        # go with sys.executable. Below we just need a working
 | 
			
		||||
        # Python interpreter, not necessarily sys.executable.
 | 
			
		||||
        python_cmd = executable.which('python3', 'python', 'python2')
 | 
			
		||||
        python_cmd = python_cmd.name if python_cmd else sys.executable
 | 
			
		||||
 | 
			
		||||
        dump_cmd = 'import os, json; print(json.dumps(dict(os.environ)))'
 | 
			
		||||
        dump_environment = python_cmd + ' -c "{0}"'.format(dump_cmd)
 | 
			
		||||
 | 
			
		||||
        # Try to source the file
 | 
			
		||||
        source_file_arguments = ' '.join([
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
# This list is not exhaustive. Currently we only use load and unload
 | 
			
		||||
# If we need another option that changes the environment, add it here.
 | 
			
		||||
module_change_commands = ['load', 'swap', 'unload', 'purge', 'use', 'unuse']
 | 
			
		||||
py_cmd = 'import os; import json; print(json.dumps(dict(os.environ)))'
 | 
			
		||||
py_cmd = "'import os;import json;print(json.dumps(dict(os.environ)))'"
 | 
			
		||||
 | 
			
		||||
# This is just to enable testing. I hate it but we can't find a better way
 | 
			
		||||
_test_mode = False
 | 
			
		||||
@@ -32,8 +32,7 @@ def module(*args):
 | 
			
		||||
    if args[0] in module_change_commands:
 | 
			
		||||
        # Do the module manipulation, then output the environment in JSON
 | 
			
		||||
        # and read the JSON back in the parent process to update os.environ
 | 
			
		||||
        module_cmd += ' > /dev/null; PYTHONHOME="{0}" "{1}" -c "{2}"'.format(
 | 
			
		||||
            sys.prefix, sys.executable, py_cmd)
 | 
			
		||||
        module_cmd += ' >/dev/null;' + sys.executable + ' -c %s' % py_cmd
 | 
			
		||||
        module_p  = subprocess.Popen(module_cmd,
 | 
			
		||||
                                     stdout=subprocess.PIPE,
 | 
			
		||||
                                     stderr=subprocess.STDOUT,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user