PyO3/pyo3 · error

broken Python interpreter: {}

Error message

broken Python interpreter: {}

What it means

InterpreterConfig::from_interpreter runs a probe script against the Python interpreter and parses its key/value output. If the interpreter produces no parseable output at all (empty map), pyo3 concludes the interpreter is broken rather than trusting an empty configuration, and fails the build with this message naming the interpreter path.

Source

Thrown at pyo3-build-config/src/impl_.rs:486

print("implementation", platform.python_implementation())
print("version_major", sys.version_info[0])
print("version_minor", sys.version_info[1])
print("shared", PYPY or GRAALPY or ANACONDA or WINDOWS or FRAMEWORK or SHARED)
print("python_framework_prefix", FRAMEWORK_PREFIX)
print_if_set("ld_version", get_config_var("LDVERSION"))
print_if_set("libdir", get_config_var("LIBDIR"))
print_if_set("base_prefix", base_prefix)
print("executable", sys.executable)
print("calcsize_pointer", struct.calcsize("P"))
print("mingw", get_platform().startswith("mingw"))
print("cygwin", get_platform().startswith("cygwin"))
print("ext_suffix", get_config_var("EXT_SUFFIX"))
print("gil_disabled", get_config_var("Py_GIL_DISABLED"))
"#;
        let output = run_python_script(interpreter.as_ref(), SCRIPT)?;
        let map: HashMap<String, String> = parse_script_output(&output);

        ensure!(
            !map.is_empty(),
            "broken Python interpreter: {}",
            interpreter.as_ref().display()
        );

        if let Some(value) = map.get("graalpy_major") {
            let graalpy_version = PythonVersion {
                major: value
                    .parse()
                    .context("failed to parse GraalPy major version")?,
                minor: map["graalpy_minor"]
                    .parse()
                    .context("failed to parse GraalPy minor version")?,
            };
            ensure!(
                graalpy_version >= MINIMUM_SUPPORTED_VERSION_GRAALPY,
                "At least GraalPy version {} needed, got {}",
                MINIMUM_SUPPORTED_VERSION_GRAALPY,

View on GitHub (pinned to ac9b6899d3)

Solutions

  1. Test the interpreter directly: `<path> -c "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))"` and confirm real output
  2. Replace shim/stub interpreters (Windows Store alias, broken pyenv/conda shim) with a real Python executable via PYO3_PYTHON
  3. Reinstall the Python distribution if it silently ignores piped scripts
  4. Check that the 'interpreter' is actually Python and not a shell alias or App Execution Alias

Example fix

// shell, before
export PYO3_PYTHON=/c/Users/me/AppData/Local/Microsoft/WindowsApps/python3.exe  # Store stub
// after
export PYO3_PYTHON=C:/Python312/python.exe
Defensive patterns

Strategy: validation

Validate before calling

// shell
OUT=$(${PYO3_PYTHON:-python3} -c 'import sysconfig; print("ext_suffix", sysconfig.get_config_var("EXT_SUFFIX"))'); [ -n "$OUT" ] || echo 'empty output: interpreter is a stub/shim — replace it'

Prevention

When it happens

Trigger: run_python_script succeeds with exit 0 but stdout is empty or unparseable (parse_script_output yields an empty HashMap), so ensure!(!map.is_empty()) fires — typically an interpreter that 'succeeds' but ignores stdin or produces no stdout.

Common situations: Windows Store python.exe stub that prints a store-advertisement and exits 0; wrapper scripts swallowing stdin; interpreters that hang/succeed without evaluating piped scripts; Aliased python shim (e.g. conda, pyenv shims) misbehaving.

Related errors


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