diff --git a/CHANGELOG.md b/CHANGELOG.md index ebf8bc2a6ab..908a94d3865 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,9 +33,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Mark FFI definitions removed in Python 3.10 `PyParser_ASTFromString`, `PyParser_ASTFromStringObject`, `PyParser_ASTFromFile`, `PyParser_ASTFromFileObject`, `PyParser_SimpleParseStringFlags`, `PyParser_SimpleParseStringFlagsFilename`, `PyParser_SimpleParseFileFlags`, `PyParser_SimpleParseString`, `PyParser_SimpleParseFile`, `Py_SymtableString`, and `Py_SymtableStringObject`. [#1830](https://github.com/PyO3/pyo3/pull/1830) - `pyo3`'s `Cargo.toml` now advertises `links = "python"` to inform Cargo that it links against *libpython*. [#1819](https://github.com/PyO3/pyo3/pull/1819) +### Fixed + +- Fix building with a conda environment on Windows. [#1873](https://github.com/PyO3/pyo3/pull/1873) + ## [0.14.5] - 2021-09-05 -## Added +### Added - Make `pyo3_build_config::InterpreterConfig` and subfields public. [#1848](https://github.com/PyO3/pyo3/pull/1848) - Add `resolve-config` feature to the `pyo3-build-config` to control whether its build script does anything. [#1856](https://github.com/PyO3/pyo3/pull/1856) diff --git a/pyo3-build-config/src/impl_.rs b/pyo3-build-config/src/impl_.rs index 8f822d20155..1bc0fb3d97b 100644 --- a/pyo3-build-config/src/impl_.rs +++ b/pyo3-build-config/src/impl_.rs @@ -2,7 +2,7 @@ use std::{ collections::{HashMap, HashSet}, convert::AsRef, env, - ffi::OsString, + ffi::{OsStr, OsString}, fmt::Display, fs::{self, DirEntry}, io::{BufRead, BufReader, Read, Write}, @@ -1080,10 +1080,28 @@ fn run_python_script(interpreter: &Path, script: &str) -> Result { } } -fn get_venv_path() -> Option { +fn venv_interpreter(virtual_env: &OsStr, windows: bool) -> PathBuf { + if windows { + Path::new(virtual_env).join("Scripts").join("python.exe") + } else { + Path::new(virtual_env).join("bin").join("python") + } +} + +fn conda_env_interpreter(conda_prefix: &OsStr, windows: bool) -> PathBuf { + if windows { + Path::new(conda_prefix).join("python.exe") + } else { + Path::new(conda_prefix).join("bin").join("python") + } +} + +fn get_env_interpreter() -> Option { match (env_var("VIRTUAL_ENV"), env_var("CONDA_PREFIX")) { - (Some(dir), None) => Some(PathBuf::from(dir)), - (None, Some(dir)) => Some(PathBuf::from(dir)), + // Use cfg rather can CARGO_TARGET_OS because this affects where files are located on the + // build host + (Some(dir), None) => Some(venv_interpreter(&dir, cfg!(windows))), + (None, Some(dir)) => Some(conda_env_interpreter(&dir, cfg!(windows))), (Some(_), Some(_)) => { warn!( "Both VIRTUAL_ENV and CONDA_PREFIX are set. PyO3 will ignore both of these for \ @@ -1105,14 +1123,8 @@ fn get_venv_path() -> Option { pub fn find_interpreter() -> Result { if let Some(exe) = env_var("PYO3_PYTHON") { Ok(exe.into()) - } else if let Some(venv_path) = get_venv_path() { - // Use cfg rather can CARGO_TARGET_OS because this affects how files are located on the - // host OS - if cfg!(windows) { - Ok(venv_path.join("Scripts\\python")) - } else { - Ok(venv_path.join("bin/python")) - } + } else if let Some(env_interpreter) = get_env_interpreter() { + Ok(env_interpreter) } else { println!("cargo:rerun-if-env-changed=PATH"); ["python", "python3"] @@ -1181,7 +1193,7 @@ pub fn make_interpreter_config() -> Result { #[cfg(test)] mod tests { - use std::io::Cursor; + use std::{io::Cursor, iter::FromIterator}; use super::*; @@ -1516,4 +1528,30 @@ mod tests { } ) } + + #[test] + fn test_venv_interpreter() { + let base = OsStr::new("base"); + assert_eq!( + venv_interpreter(&base, true), + PathBuf::from_iter(&["base", "Scripts", "python.exe"]) + ); + assert_eq!( + venv_interpreter(&base, false), + PathBuf::from_iter(&["base", "bin", "python"]) + ); + } + + #[test] + fn test_conda_env_interpreter() { + let base = OsStr::new("base"); + assert_eq!( + conda_env_interpreter(&base, true), + PathBuf::from_iter(&["base", "python.exe"]) + ); + assert_eq!( + conda_env_interpreter(&base, false), + PathBuf::from_iter(&["base", "bin", "python"]) + ); + } }