Skip to content

pyo3-build-config: CONDA_PREFIX set but no valid Python interpreter causes build failure #6177

Description

@trim21

🐛 Bug Report

pyo3-build-config blindly trusts CONDA_PREFIX to locate the Python interpreter, without verifying the interpreter actually exists at the derived path.

Environment

  • OS: Linux
  • pyo3 version: 0.27.2
  • Rust: stable

💥 Reproducing

# Set CONDA_PREFIX to a non-existent or deleted environment
export CONDA_PREFIX=/nonexistent/path
# VIRTUAL_ENV is not set

cargo build  # fails

Error:

error: failed to run the Python interpreter at /nonexistent/path/bin/python:
No such file or directory (os error 2)

🔍 Root Cause

In pyo3-build-config/src/impl_.rs:

fn get_env_interpreter() -> Option<PathBuf> {
    match (env_var("VIRTUAL_ENV"), env_var("CONDA_PREFIX")) {
        (Some(dir), None) => Some(venv_interpreter(&dir, cfg!(windows))),
        (None, Some(dir)) => Some(conda_env_interpreter(&dir, cfg!(windows))),
        // ...
    }
}

conda_env_interpreter constructs $CONDA_PREFIX/bin/python without checking if the file actually exists.

This is problematic because CONDA_PREFIX can be set in situations where no valid Python interpreter is present:

  1. A conda/pixi environment was deleted but the shell still carries the env var (e.g., VSCode launched from a shell with the env active, then the env was cleaned up)
  2. Non-conda tools like pixi also set CONDA_PREFIX, and the environment might not contain Python at all
  3. Leftover env vars from a previous session

✅ Proposed Fix

get_env_interpreter should verify that the derived interpreter path exists before returning it:

(None, Some(dir)) => {
    let path = conda_env_interpreter(&dir, cfg!(windows));
    if path.exists() {
        Some(path)
    } else {
        warn!(
            "CONDA_PREFIX is set to `{}` but no Python interpreter found at `{}`; ignoring",
            dir, path.display()
        );
        None
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions