From 70eca7be482c5647bdbba8866dcfa7f17555ae5c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 8 Jun 2026 13:20:20 -0700 Subject: [PATCH] Key cffi build-script cache on PYO3_BASE_PYTHON when available PEP 517 build isolation creates venvs at random paths and points PYO3_PYTHON at them, so a `rerun-if-env-changed=PYO3_PYTHON` makes the build script re-run on every invocation and defeats caching (see PyO3/pyo3#6113). When PYO3_BASE_PYTHON (the stable underlying interpreter) is present, key the rerun on that instead. A venv cannot change the implementation, version, ABI, or headers of its base interpreter, which is all this script derives -- so the base path is a sound cache key. We still invoke PYO3_PYTHON to locate the binary, since the build venv is where cffi is installed. When PYO3_BASE_PYTHON is absent we fall back to keying on PYO3_PYTHON so manual interpreter switches still trigger a rebuild. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/rust/cryptography-cffi/build.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/rust/cryptography-cffi/build.rs b/src/rust/cryptography-cffi/build.rs index c018382c4380..5cb7825a158d 100644 --- a/src/rust/cryptography-cffi/build.rs +++ b/src/rust/cryptography-cffi/build.rs @@ -25,7 +25,21 @@ fn main() { let out_dir = env::var("OUT_DIR").unwrap(); // FIXME: maybe pyo3-build-config should provide a way to do this? let python = env::var("PYO3_PYTHON").unwrap_or_else(|_| "python3".to_string()); - println!("cargo:rerun-if-env-changed=PYO3_PYTHON"); + // PEP 517 build frontends create build isolation venvs at random paths and + // point PYO3_PYTHON at them, so keying the build-script cache on PYO3_PYTHON + // defeats caching (a rebuild every invocation). When the frontend provides + // PYO3_BASE_PYTHON (the stable underlying interpreter, ~sys._base_executable), + // key on that instead -- a venv cannot change the implementation, version, + // ABI, or headers of its base, which is all this script derives from the + // interpreter. We still invoke PYO3_PYTHON to find the binary (it has cffi + // installed; the base interpreter may not). When PYO3_BASE_PYTHON is absent, + // fall back to keying on PYO3_PYTHON so manual interpreter switches still + // trigger a rebuild. + if env::var_os("PYO3_BASE_PYTHON").is_some() { + println!("cargo:rerun-if-env-changed=PYO3_BASE_PYTHON"); + } else { + println!("cargo:rerun-if-env-changed=PYO3_PYTHON"); + } println!("cargo:rerun-if-changed=../../_cffi_src/"); println!("cargo:rerun-if-changed=../../cryptography/__about__.py"); let output = Command::new(&python)