Skip to content

Support PYO3_BASE_PYTHON to make builds caching-friendly#6114

Open
alex wants to merge 4 commits into
PyO3:mainfrom
alex:claude/fervent-curie-63rVI
Open

Support PYO3_BASE_PYTHON to make builds caching-friendly#6114
alex wants to merge 4 commits into
PyO3:mainfrom
alex:claude/fervent-curie-63rVI

Conversation

@alex

@alex alex commented Jun 7, 2026

Copy link
Copy Markdown
Member

When a project is built by a PEP 517 frontend with build isolation, the frontend creates a randomly-named temporary virtualenv and the build tool points PYO3_PYTHON inside it. Because pyo3-build-config registers rerun-if-env-changed=PYO3_PYTHON, the ephemeral path defeats cargo's build cache and forces recompilation of the pyo3 crates on every build, even when the underlying interpreter is identical.

Build tools can now additionally export PYO3_BASE_PYTHON pointing at a stable interpreter path (e.g. sys._base_executable). When set, it takes precedence over PYO3_PYTHON, and PYO3_PYTHON is not read at all - so changes to the ephemeral path no longer trigger rebuilds.

Fixes #6113

https://claude.ai/code/session_01JhPTZXLDhuxTSXCZNJuuAA

claude added 2 commits June 7, 2026 15:33
When a project is built by a PEP 517 frontend with build isolation, the
frontend creates a randomly-named temporary virtualenv and the build tool
points PYO3_PYTHON inside it. Because pyo3-build-config registers
rerun-if-env-changed=PYO3_PYTHON, the ephemeral path defeats cargo's
build cache and forces recompilation of the pyo3 crates on every build,
even when the underlying interpreter is identical.

Build tools can now additionally export PYO3_BASE_PYTHON pointing at a
stable interpreter path (e.g. sys._base_executable). When set, it takes
precedence over PYO3_PYTHON, and PYO3_PYTHON is not read at all - so
changes to the ephemeral path no longer trigger rebuilds.

Fixes PyO3#6113

https://claude.ai/code/session_01JhPTZXLDhuxTSXCZNJuuAA
…to PR number

- rumdl requires one sentence per line in the guide
- the changelog check requires the newsfragment to be named after the
  PR number (6114), not the issue number

https://claude.ai/code/session_01JhPTZXLDhuxTSXCZNJuuAA
@ngoldbaum

Copy link
Copy Markdown
Contributor

Can you add tests to the noxfile to cover the uncovered branches?

claude added 2 commits June 8, 2026 16:18
Extract the PYO3_BASE_PYTHON / PYO3_PYTHON resolution out of
find_interpreter into a pure `explicit_interpreter` helper and unit-test
all three branches: PYO3_BASE_PYTHON taking precedence (and PYO3_PYTHON
not being read at all in that case), falling back to PYO3_PYTHON, and
neither being set.

Addresses review feedback from @ngoldbaum requesting coverage of the
newly-added branches.

https://claude.ai/code/session_01JhPTZXLDhuxTSXCZNJuuAA
ngoldbaum asked for tests covering the branches added to find_interpreter.
Those branches only run inside the build script, which the normal test
suite exercises via the active virtualenv, so they were never hit.

Add a test-interpreter-discovery nox session that drives a build with
PYO3_PRINT_CONFIG=1 under controlled PYO3_BASE_PYTHON / PYO3_PYTHON
values and asserts the resulting config. It covers all three cases:
PYO3_BASE_PYTHON selecting the interpreter, taking precedence over a
bogus PYO3_PYTHON (proving PYO3_PYTHON is not executed), and the
PYO3_PYTHON fallback. Run it in the test-version-limits CI job, which
already reports coverage with --include-build-script.

This reverts the earlier find_interpreter refactor, which is no longer
needed now that the branches are covered via the build script.

https://claude.ai/code/session_01JhPTZXLDhuxTSXCZNJuuAA
@alex

alex commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

Ok, (Claude) added a test -- first one was silly so ignore it :-)

@alex

alex commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

(netlify stuff is unrelated)

@alex

alex commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

Hmm, codecov doesn't seem to have budged, but the new nox test should precisely hit these lines.

@ngoldbaum

Copy link
Copy Markdown
Contributor

It looks like failed builds don't contribute to coverage?

@alex

alex commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

Ugh, is this somehow caused by the netlify thing? That'd be mega annoying.

@ngoldbaum

Copy link
Copy Markdown
Contributor

No, I think it's because you're doing builds with PYO3_PRINT_CONFIG which causes a build failure and ultimately doesn't contribute to coverage. The test-version-limits job does have successful builds, so it contributes to coverage.

Is there any reason why this can't be a unit test in _impl.py?

But also the test exists so I'm not particularly worried if the coverage report doesn't reflect that for dumb reasons.

@alex

alex commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

I could do a unit test, but I think it'd be much less actually validating than these nox tests (which were a good idea, thanks!)

@alex

alex commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

@ngoldbaum anything else required to merge this do you think?

@ngoldbaum

Copy link
Copy Markdown
Contributor

I think it's probably fine but I want to give @davidhewitt chance to weigh in on the idea, since we're just about to cut a release.

@alex

alex commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

Thanks much! (For obvious reasons, would love it if this could slip into 0.29!)

@alex alex mentioned this pull request Jun 8, 2026
@davidhewitt

Copy link
Copy Markdown
Member

Doesn't this run into the same concern as PyO3/setuptools-rust#448 (comment) wrt needing the PEP517 build dependencies as part of the build process?

@alex

alex commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

@davidhewitt it shouldn't -- the PYO3_PYTHON env var is still available and still points at the right binary (for use by cryptography/pydantic), it's just that pyo3 itself doesn't need it and so it can get something cache-friendlier.

@davidhewitt

Copy link
Copy Markdown
Member

My worry is things like pyo3_build_config::InterpreterConfig::executable, which will currently be PYO3_PYTHON. I think some build scripts might depend on that executable to launch other Python scripts, which require to be run in the actual build venv?

@alex

alex commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

Hmm, that's definitely tougher. The way it's documented doesn't really commit us to it being the in-venv python, but it's quite hard to be sure what users are relying on.

I do think we should look for a way to make this change -- it's a significant improvement in build times.

@alex

alex commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

I guess a question is do you think docs (+changelog of course) would be sufficient?

@davidhewitt

Copy link
Copy Markdown
Member

I wonder if we could make pyo3_build_config::get() automatically substitute executable with PYO3_PYTHON (if set)? That might avoid breakage but introduce other weirdness.

Another thought, could we make it opt-in with PYO3_USE_BASE_PYTHON, which is user-set, so even if maturin is populating PYO3_BASE_PYTHON, it's ignored except where users opt in. This would avoid breakage, however maybe it's just layering additional complexity when really there's a more elegant general solution to #1708. I don't think rust-analyzer would set PYO3_BASE_PYTHON env var(s) without user input, for example.

I am genuinely sympathetic to this problem (#1708 is a longstanding issue and big user pain) but I'm not confident this is quite the right patch as-is.

Given that 0.29 is already looking like a massive release, I'd much prefer that we explored this space more and got the right solution into 0.30. I really do want to have better user-facing build times, and I hate to block improvements, but we've lived this far with the build time cost and I'm not yet confident in this pathway.

Please accept my apologies on dragging feet a bit here. I really want to get 0.29 shipped to resolve the security issues and 3.15 beta support, then we can figure out the full design here with clear heads. If we can find a fully-backcompat solution here, maybe we can even land this in 0.29.1 to avoid a longer wait to 0.30.

@alex

alex commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

I don't think this should be opt-in -- it means the vast majority of users won't benefit from the gains. My mental model here is: pyo3 only needs base python for the correctness of its build scripts, therefore this should be possible :-) We just need to figure out the backwards compatibility impact on other APIs.

And no worries about punting to 0.30. Cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make pyo3-build-config more caching friendly

4 participants