Skip to content

fix(interpreter): propagate python version flags through exec transitions - #1539

Draft
xangcastle wants to merge 1 commit into
1.xfrom
xangcastle/1x-exec-marker-env
Draft

xangcastle wants to merge 1 commit into
1.xfrom
xangcastle/1x-exec-marker-env

Conversation

@xangcastle

Copy link
Copy Markdown
Member

Marker-gated dependencies are silently dropped from exec-configuration builds — most visibly from sdist build_tool venvs — because the python version flags reset to their defaults when the exec transition strips Starlark flags. Same bug class #917 fixed for the venv flag.

Real-world failure (enterprise report)

numcodecs 0.16.5 declares setuptools-scm in [build-system].requires. During get_requires_for_build_wheel, setuptools loads the entry points of every installed distribution, importing setuptools_scm → vcs_versioning → typing_extensions. The lock gates typing-extensions; python_full_version < '3.11'; the target builds under Python 3.10, but in exec configuration the marker evaluated against the flag default (3.11), so the gate resolved to :empty:

ModuleNotFoundError: No module named 'typing_extensions'
ERROR Backend subprocess exited when trying to invoke get_requires_for_build_wheel

setuptools_scm and vcs_versioning were present in the venv; only the marker-gated link was missing.

Mechanism

  • Conditional deps render as selects with no_match = ":empty" (uv_project/repository.bzl); decide_marker reads python_version/python_full_version from Starlark flags (markers/defs.bzl).
  • pep517_whl.tool is cfg = "exec". With --incompatible_exclude_starlark_flags_from_exec_config (flips on in Bazel 10, --incompatible_exclude_starlark_flags_from_exec_config bazelbuild/bazel#26909), python flags reset in exec; the build_tool's rule transition then re-derives the version from the rules_python default → markers decide with the wrong version → gated transitives vanish, while the exec toolchain may resolve a different interpreter entirely.
  • Probed semantics: Bazel 9.2 honors scope only when set explicitly on the target (skylib ≥1.8's attr default does not count); transition writes over excluded flags persist. Bazel 8.5.1 only has the --experimental_… spelling and ignores scope entirely — with it, even the venv flag and third-party flags reset (breaks the rust tool link), so the exclusion is unusable on 8.x regardless of this fix.

Fix

Explicit scope = "universal" on //py/private/interpreter:python_version and :freethreaded (propagated by the same python_transition, consumed by interpreter toolchain target_settings). Exact precedent: #917 for //uv/private/constraints/venv:venv.

Trade-off (same as #917): exec-built tools inherit the target's python version; there is currently no way to express a deliberately different exec interpreter — unchanged from the venv flag's behavior.

Test plan

New e2e cases/uv-exec-marker-build-dep: docopt sdist built with setuptools-scm in the build venv, real uv lock carrying setuptools-scm → vcs-versioning → typing-extensions; python_full_version < '3.11', target python_version = "3.10". The sdist is patched to make the typing_extensions import unconditional, standing in for setuptools' unconditional entry-point loading (in the bare e2e the import chain is version-guarded and the exec interpreter self-heals to 3.11, masking the client's crash).

  • Red (pre-fix, Bazel 9.2 + exclusion): ModuleNotFoundError: typing_extensions, build venv on python 3.11 for a 3.10 target; cquery shows the typing-extensions gate resolving to //private/sccs:empty in exec.
  • Green (post-fix): gate resolves to //:typing_extensions, build_tool resolves the 3.10 interpreter; case also passes on plain Bazel 8.5.1 and 9.2.
  • bazel test //py/... //uv/... 115/115; e2e regressions: uv-extra-marker, uv-conflict-817 (a+b), uv-abi3-compat-853, uv-sdist-dup-build-deps, uv-sdist-native-inputs, freethreaded-805 all pass; buildifier and gazelle clean.

Known pre-existing issues (not addressed here)

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 2287f677-5c29-4ebc-8a17-338dd0023a3f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@aspect-workflows

aspect-workflows Bot commented Sep 11, 2026

Copy link
Copy Markdown

✨ Aspect Workflows Tasks

📅 Fri Sep 11 15:07:00 UTC 2026

✅ 7 successful tasks

  • ✅ buildifier · ⏱ 34.5s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ gazelle · ⏱ 36.5s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ test (test-e2e-bazel-8) · ⏱ 32m 9s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (67/67 passed)
  • ✅ test (test-e2e-bazel-9) · ⏱ 35m 46s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (67/67 passed)
  • ✅ test (test-examples-uv_pip_compile-bazel-8) · ⏱ 29s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed)
  • ✅ test (test-root-bazel-8) · ⏱ 41m 58s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (129/129 passed)
  • ✅ test (test-root-bazel-9) · ⏱ 33m 53s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (128/128 passed)

⏱ Last updated Fri Sep 11 15:48:56 UTC 2026 · 📊 GitHub API quota 472/15,000 (3% used, resets in 47m, throttle 3×)
🚀 Powered by Aspect CLI (v2026.22.44)  |  Aspect Build · X · LinkedIn · YouTube

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.

1 participant