diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d97e38fc4..a657c60a4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,6 +23,10 @@ jobs: RUST_BACKTRACE: '1' steps: - uses: actions/checkout@v3 + - uses: conda-incubator/setup-miniconda@v2 + with: + auto-activate-base: 'false' + activate-environment: '' - uses: actions/setup-python@v4 with: python-version: "3.7" diff --git a/Changelog.md b/Changelog.md index 93ae847ba..5aef77f6f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +* Fix `maturin develop` in Windows conda virtual environment in [#1146](https://github.com/PyO3/maturin/pull/1146) + ## [0.13.5] - 2022-09-27 * Fix resolving crate name bug in [#1142](https://github.com/PyO3/maturin/pull/1142) diff --git a/src/target.rs b/src/target.rs index dcbfc950f..a77b91638 100644 --- a/src/target.rs +++ b/src/target.rs @@ -579,13 +579,13 @@ impl Target { let venv = venv_base.as_ref(); if self.is_windows() { let bin_dir = venv.join("Scripts"); - if bin_dir.exists() { + if bin_dir.join("python.exe").exists() { return bin_dir; } // Python innstalled via msys2 on Windows might produce a POSIX-like venv // See https://github.com/PyO3/maturin/issues/1108 let bin_dir = venv.join("bin"); - if bin_dir.exists() { + if bin_dir.join("python.exe").exists() { return bin_dir; } // for conda environment diff --git a/tests/common/integration.rs b/tests/common/integration.rs index d5ea1aa9e..35c77c4ff 100644 --- a/tests/common/integration.rs +++ b/tests/common/integration.rs @@ -135,47 +135,32 @@ pub fn test_integration( Ok(()) } -/// Creates conda environments -#[cfg(target_os = "windows")] -fn create_conda_env(name: &str, major: usize, minor: usize) { - Command::new("conda") - .arg("create") - .arg("-n") - .arg(name) - .arg(format!("python={}.{}", major, minor)) - .arg("-q") - .arg("-y") - .output() - .expect("Conda not available."); -} - -#[cfg(target_os = "windows")] pub fn test_integration_conda(package: impl AsRef, bindings: Option) -> Result<()> { + use crate::common::create_conda_env; use std::path::PathBuf; use std::process::Stdio; let package_string = package.as_ref().join("Cargo.toml").display().to_string(); - // Since the python launcher has precedence over conda, we need to deactivate it. - // We do so by shadowing it with our own hello world binary. - let original_path = env::var_os("PATH").expect("PATH is not defined"); - let py_dir = env::current_dir()? - .join("test-data") - .to_str() - .unwrap() - .to_string(); - let mocked_path = py_dir + ";" + original_path.to_str().unwrap(); - env::set_var("PATH", mocked_path); - // Create environments to build against, prepended with "A" to ensure that integration // tests are executed with these environments - create_conda_env("A-pyo3-build-env-37", 3, 7); - create_conda_env("A-pyo3-build-env-38", 3, 8); - create_conda_env("A-pyo3-build-env-39", 3, 9); - create_conda_env("A-pyo3-build-env-310", 3, 10); + let mut interpreters = Vec::new(); + for minor in 7..=10 { + let (_, venv_python) = create_conda_env(&format!("A-maturin-env-3{}", minor), 3, minor)?; + interpreters.push(venv_python); + } // The first argument is ignored by clap - let mut cli = vec!["build", "--manifest-path", &package_string, "--quiet"]; + let mut cli = vec![ + "build", + "--manifest-path", + &package_string, + "--quiet", + "--interpreter", + ]; + for interp in &interpreters { + cli.push(interp.to_str().unwrap()); + } if let Some(ref bindings) = bindings { cli.push("--bindings"); @@ -190,13 +175,13 @@ pub fn test_integration_conda(package: impl AsRef, bindings: Option = vec![]; for ((filename, _), python_interpreter) in wheels.iter().zip(build_context.interpreter) { let executable = python_interpreter.executable; - if executable.to_str().unwrap().contains("pyo3-build-env-") { + if executable.to_str().unwrap().contains("maturin-env-") { conda_wheels.push((filename.clone(), executable)) } } assert_eq!( - 3, + interpreters.len(), conda_wheels.len(), "Error creating or detecting conda environments." ); @@ -215,7 +200,7 @@ pub fn test_integration_conda(package: impl AsRef, bindings: Option Result<(PathBuf, PathBuf)> { + use serde::Deserialize; + + #[derive(Deserialize)] + struct CondaCreateResult { + prefix: PathBuf, + success: bool, + } + + let mut cmd = if cfg!(windows) { + let mut cmd = Command::new("cmd.exe"); + cmd.arg("/c").arg("conda"); + cmd + } else { + Command::new("conda") + }; + let output = cmd + .arg("create") + .arg("-n") + .arg(name) + .arg(format!("python={}.{}", major, minor)) + .arg("-q") + .arg("-y") + .arg("--json") + .output() + .expect("Conda not available."); + let result: CondaCreateResult = serde_json::from_slice(&output.stdout)?; + if !result.success { + bail!("Failed to create conda environment {}.", name); + } + let target = Target::from_target_triple(None)?; + let python = target.get_venv_python(&result.prefix); + Ok((result.prefix, python)) +} diff --git a/tests/run.rs b/tests/run.rs index 66c9e5303..abede3c3c 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -162,14 +162,15 @@ fn integration_pyo3_mixed_py_subdir() { )); } -#[cfg(target_os = "windows")] #[test] -#[ignore] fn integration_pyo3_pure_conda() { - handle_result(integration::test_integration_conda( - "text-crates/pyo3-pure", - None, - )); + // Only run on GitHub Actions for now + if std::env::var("GITHUB_ACTIONS").is_ok() { + handle_result(integration::test_integration_conda( + "test-crates/pyo3-mixed", + None, + )); + } } #[test]