fn ensure_python_version()

in include/pyo3/pyo3-ffi/build.rs [44:122]


fn ensure_python_version(interpreter_config: &InterpreterConfig) -> Result<()> {
    // This is an undocumented env var which is only really intended to be used in CI / for testing
    // and development.
    if std::env::var("UNSAFE_PYO3_SKIP_VERSION_CHECK").as_deref() == Ok("1") {
        return Ok(());
    }

    match interpreter_config.implementation {
        PythonImplementation::CPython => {
            let versions = SUPPORTED_VERSIONS_CPYTHON;
            ensure!(
                interpreter_config.version >= versions.min,
                "the configured Python interpreter version ({}) is lower than PyO3's minimum supported version ({})",
                interpreter_config.version,
                versions.min,
            );
            ensure!(
                interpreter_config.version <= versions.max || env_var("PYO3_USE_ABI3_FORWARD_COMPATIBILITY").map_or(false, |os_str| os_str == "1"),
                "the configured Python interpreter version ({}) is newer than PyO3's maximum supported version ({})\n\
                 = help: please check if an updated version of PyO3 is available. Current version: {}\n\
                 = help: set PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 to suppress this check and build anyway using the stable ABI",
                interpreter_config.version,
                versions.max,
                std::env::var("CARGO_PKG_VERSION").unwrap(),
            );
        }
        PythonImplementation::PyPy => {
            let versions = SUPPORTED_VERSIONS_PYPY;
            ensure!(
                interpreter_config.version >= versions.min,
                "the configured PyPy interpreter version ({}) is lower than PyO3's minimum supported version ({})",
                interpreter_config.version,
                versions.min,
            );
            // PyO3 does not support abi3, so we cannot offer forward compatibility
            ensure!(
                interpreter_config.version <= versions.max,
                "the configured PyPy interpreter version ({}) is newer than PyO3's maximum supported version ({})\n\
                 = help: please check if an updated version of PyO3 is available. Current version: {}",
                interpreter_config.version,
                versions.max,
                std::env::var("CARGO_PKG_VERSION").unwrap()
            );
        }
        PythonImplementation::GraalPy => {
            let versions = SUPPORTED_VERSIONS_GRAALPY;
            ensure!(
                interpreter_config.version >= versions.min,
                "the configured GraalPy interpreter version ({}) is lower than PyO3's minimum supported version ({})",
                interpreter_config.version,
                versions.min,
            );
            // GraalPy does not support abi3, so we cannot offer forward compatibility
            ensure!(
                interpreter_config.version <= versions.max,
                "the configured GraalPy interpreter version ({}) is newer than PyO3's maximum supported version ({})\n\
                 = help: please check if an updated version of PyO3 is available. Current version: {}",
                interpreter_config.version,
                versions.max,
                std::env::var("CARGO_PKG_VERSION").unwrap()
            );
        }
    }

    if interpreter_config.abi3 {
        match interpreter_config.implementation {
            PythonImplementation::CPython => {}
            PythonImplementation::PyPy => warn!(
                "PyPy does not yet support abi3 so the build artifacts will be version-specific. \
                See https://foss.heptapod.net/pypy/pypy/-/issues/3397 for more information."
            ),
            PythonImplementation::GraalPy => warn!(
                "GraalPy does not support abi3 so the build artifacts will be version-specific."
            ),
        }
    }

    Ok(())
}