diff --git a/interfaces/cython/SConscript b/interfaces/cython/SConscript index 7b7839e4202..3388bdcd1b1 100644 --- a/interfaces/cython/SConscript +++ b/interfaces/cython/SConscript @@ -36,9 +36,12 @@ script = """\ from sysconfig import * import numpy import json +import site vars = get_config_vars() vars["plat"] = get_platform() vars["numpy_include"] = numpy.get_include() +vars["site_packages"] = site.getsitepackages() +vars["user_site_packages"] = site.getusersitepackages() print(json.dumps(vars)) """ info = json.loads(get_command_output(localenv["python_cmd"], "-c", script)) @@ -50,6 +53,8 @@ py_version_short = parse_version(info["py_version_short"]) py_version_full = parse_version(info["py_version"]) py_version_nodot = info["py_version_nodot"] numpy_include = info["numpy_include"] +site_packages = info["site_packages"] +user_site_packages = info["user_site_packages"] localenv.Prepend(CPPPATH=[Dir('#include'), inc, numpy_include]) localenv.Prepend(LIBS=localenv['cantera_libs']) @@ -137,6 +142,27 @@ elif not env["default_prefix"]: install_cmd.append(f"--prefix={env['prefix']}") python_prefix = env["prefix"] +# Check for existing Python module installation. Allow pip to remove an existing +# installation only we're installing to the same location. Also disable uninstallation +# if we're installing to a staging directory. +if env["stage_dir"]: + install_cmd.append("--ignore-installed") +else: + info = get_command_output(localenv["python_cmd"], "-m", "pip", "show", "cantera", + ignore_errors=True) + + if user_install: + test_prefix = Path(user_site_packages).parents[2] + elif python_prefix is None: + test_prefix = Path(site_packages).parents[2] + else: + test_prefix = Path(python_prefix) + + match = re.search(r"Location: (.*)\n", info, re.MULTILINE) + existing_prefix = Path(match.group(1)).parents[2] if match else None + if existing_prefix and existing_prefix != test_prefix: + install_cmd.append("--ignore-installed") + if env["stage_dir"]: # Get the absolute path to the stage directory. If the stage directory is a relative # path, consider it to be relative to the root of the Cantera source directory. diff --git a/site_scons/buildutils.py b/site_scons/buildutils.py index 05dc82f3a08..f47707c4eed 100644 --- a/site_scons/buildutils.py +++ b/site_scons/buildutils.py @@ -1188,7 +1188,7 @@ def our_spawn(sh: str, escape: str, cmd: str, args: str, environ: "Dict[str, str return our_spawn -def get_command_output(cmd: str, *args: str): +def get_command_output(cmd: str, *args: str, ignore_errors=False): """ Run a command with arguments and return its output. """ @@ -1196,12 +1196,16 @@ def get_command_output(cmd: str, *args: str): if "PYTHONHOME" in environ: # Can cause problems when trying to run a different Python interpreter del environ["PYTHONHOME"] + kwargs = {} + if ignore_errors: + kwargs["stderr"] = subprocess.DEVNULL data = subprocess.run( [cmd] + list(args), env=environ, stdout=subprocess.PIPE, universal_newlines=True, - check=True, + check=not ignore_errors, + **kwargs, ) return data.stdout.strip()