PyO3/pyo3 · error

`pyo3_build_config::get()` requires a direct dependency on `

Error message

`pyo3_build_config::get()` requires a direct dependency on `pyo3` or `pyo3-ffi`

What it means

pyo3_build_config::get() reads the interpreter config from the CARGO manifest dependency environment (DEP_ variables) that only exist when you depend directly on pyo3 or pyo3-ffi. If neither dependency link is present, get_inner panics because there is no config to load.

Source

Thrown at pyo3-build-config/src/lib.rs:145

        if let Some(framework_prefix) = interpreter_config.python_framework_prefix() {
            writeln!(writer, "cargo:rustc-link-arg=-Wl,-rpath,{framework_prefix}").unwrap();
        }
    }
}

/// Loads the configuration determined from the build environment.
///
/// This function must be called from a build script, and requires a direct dependency on at
/// least one of `pyo3` or `pyo3-ffi`.
pub fn get() -> &'static InterpreterConfig {
    static CONFIG: LazyLock<InterpreterConfig> = LazyLock::new(get_inner);
    &CONFIG
}

#[track_caller]
fn get_inner() -> InterpreterConfig {
    let Some(interpreter_config) = InterpreterConfig::from_cargo_dep_env() else {
        panic!("`pyo3_build_config::get()` requires a direct dependency on `pyo3` or `pyo3-ffi`")
    };
    interpreter_config.expect("failed to parse PyO3 config")
}

/// Registers `pyo3`s config names as reachable cfg expressions.
///
/// - <https://github.com/rust-lang/cargo/pull/13571>
/// - <https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-check-cfg>
#[doc(hidden)]
pub fn print_expected_cfgs() {
    println!("cargo:rustc-check-cfg=cfg(Py_LIMITED_API)");
    println!("cargo:rustc-check-cfg=cfg(Py_GIL_DISABLED)");
    println!("cargo:rustc-check-cfg=cfg(PyPy)");
    println!("cargo:rustc-check-cfg=cfg(GraalPy)");
    println!("cargo:rustc-check-cfg=cfg(RustPython)");
    println!(
        r#"cargo:rustc-check-cfg=cfg(py_sys_config, values("Py_DEBUG", "Py_REF_DEBUG", "Py_TRACE_REFS", "COUNT_ALLOCS"))"#
    );

View on GitHub (pinned to ac9b6899d3)

Solutions

  1. Add pyo3 (or pyo3-ffi) as a direct dependency in Cargo.toml so Cargo exposes DEP_PYTHON_PYO3_CONFIG
  2. Use pyo3-build-config's own APIs (e.g. from_interpreter/from_cargo_dep_env-equivalent setup) instead of get() if you don't depend on pyo3
  3. Verify your build script runs in a crate where the DEP_ env var is set: `println!("{:?}", std::env::var("DEP_PYTHON_PYO3_CONFIG"))`

Example fix

// before: only pyo3-build-config in build-dependencies
[build-dependencies]
pyo3-build-config = "0.22"
// after
[build-dependencies]
pyo3-build-config = "0.22"
[dependencies]
pyo3 = "0.22"
Defensive patterns

Strategy: validation

Validate before calling

if std::env::var("DEP_PYTHON_PYO3_CONFIG").is_err() {
    panic!("add a direct dependency on pyo3 or pyo3-ffi before calling pyo3_build_config::get()");
}

Prevention

When it happens

Trigger: Calling pyo3_build_config::get() from a build script of a crate that does not directly depend on pyo3 or pyo3-ffi (e.g. only transitive dependency, so no DEP_PYTHON_PYO3_CONFIG env var).

Common situations: Crate moved pyo3 to a transitive dependency; depending only on pyo3-build-config directly; build script of an indirect helper crate expecting config set by another crate.

Related errors


AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05). Data as JSON: /api/errors/610075b6846b24fa. Report an issue: GitHub.