Skip to content

fix: detect free-threaded Python from venv and uv before setting PYTHONMALLOC - #539

Merged
not-matthias merged 2 commits into
mainfrom
cod-296-fails-with-python313-freethreaded
Sep 18, 2026
Merged

not-matthias merged 2 commits into
mainfrom
cod-296-fails-with-python313-freethreaded

Conversation

@not-matthias

Copy link
Copy Markdown
Member

Problem

Free-threaded CPython (3.13t+) refuses to start with PYTHONMALLOC=malloc. The valgrind executor already skips that override when it detects a free-threaded interpreter, but the detection only probed python on the PATH. It missed the interpreter the benchmark actually runs under when that interpreter lives in a virtual environment or is selected by uv, so runs using astral-sh/setup-uv with python-version: 3.13t still failed.

Change

Probe every interpreter the benchmark command could resolve to, and skip the override if any of them is free-threaded:

  • python / python3 on the PATH
  • $VIRTUAL_ENV/bin/python
  • .venv/bin/python in the benchmark working directory
  • the interpreter uv python find $UV_PYTHON resolves to (setup-uv exports UV_PYTHON from its python-version input). uv downloads interpreters lazily, so when the request is not installed yet the request string itself (3.13t, +freethreaded) decides.

The probe now reads sys.abiflags instead of sysconfig.get_config_var('Py_GIL_DISABLED'). import sysconfig fails when _PYTHON_SYSCONFIGDATA_NAME is set for a different interpreter (common in Nix shells), which turned the old check into a silent false negative for exactly the venvs it needs to detect.

Verification

Release-mode smoke runs against real interpreters created with uv venv:

scenario free-threaded detected
no venv, PATH python 3.12 no
plain 3.12 .venv in cwd no
3.14t .venv in cwd yes
UV_PYTHON=3.14t (installed), no venv yes
UV_PYTHON=3.13t (not installed), no venv yes (request fallback)
UV_PYTHON=3.12, no venv no
VIRTUAL_ENV=<3.14t venv>, cwd has no venv yes

Plus rstest cases for the UV_PYTHON request-string classifier.

@codspeed

codspeed Bot commented Sep 16, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

✅ 17 untouched benchmarks


Comparing cod-296-fails-with-python313-freethreaded (5af022c) with main (88c994e)

Open in CodSpeed

@not-matthias
not-matthias marked this pull request as ready for review September 16, 2026 14:11
@not-matthias

Copy link
Copy Markdown
Member Author

NOTE: This PR tries to fix the known cases when a free-threaded python can be used and try to not use the environment variable. However, there are many more cases that can bypass our checks (e.g. using custom compiled python).

In the future, we can explore removing PYTHONMALLOC, but this would be a breaking change so it should only be included in the next runner release (as to why this partial solution exists)

@greptile-apps

greptile-apps Bot commented Sep 16, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

The PR is not safe to merge until free-threaded detection stops depending on an import that can fail under the interpreter environments this change is meant to support.

Fix All in Claude CodeFindings

  1. P1 Sysconfig Probe Breaks Detection
Fix with agent prompt
### Issue 1
src/executor/valgrind/helpers/python.rs:7-9
If `_PYTHON_SYSCONFIGDATA_NAME` refers to configuration data that the candidate interpreter does not provide, importing `sysconfig` fails. The probe then treats that free-threaded interpreter as a regular build, and `measure` sets `PYTHONMALLOC=malloc`, causing Python to refuse to start. Keep the `sys.abiflags` probe from the previous revision because it does not import interpreter-specific configuration data.

```suggestion
/// Free-threaded builds carry the `t` ABI flag. `sys.abiflags` needs no `sysconfig`
/// import, which fails when `_PYTHON_SYSCONFIGDATA_NAME` names a module the
/// interpreter does not ship.
const GIL_DISABLED_PROBE: &str = "import sys; print(int('t' in sys.abiflags))";
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

The PR expands free-threaded Python detection to cover PATH interpreters, conventional virtual environments, and UV_PYTHON, and adds an experimental option to suppress the allocator override. The newest revision, however, restores the environment-sensitive probe that the PR was intended to replace.

  • Propagates the allocator-override setting through CLI and executor configuration.
  • Resolves and probes Python candidates associated with virtual environments and uv.
  • Classifies free-threaded uv request strings when no installed interpreter can be resolved.
  • Reintroduces a sysconfig import that can make free-threaded detection fail in Nix or cross-interpreter environments.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Build candidate interpreter list] --> B[Run free-threading probe]
    B --> C{Probe succeeds and reports GIL disabled?}
    C -- Yes --> D[Do not set PYTHONMALLOC]
    C -- No or import failure --> E{Override explicitly disabled?}
    E -- Yes --> D
    E -- No --> F[Set PYTHONMALLOC=malloc]
    F --> G[Free-threaded Python refuses to start after a false negative]
Loading

Reviews (2) · Last reviewed commit: "feat(simulation): add Python allocator o..."

Comment thread src/executor/valgrind/helpers/python.rs

@GuillaumeLagrange GuillaumeLagrange left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

olgtm

Comment thread src/executor/valgrind/helpers/python.rs Outdated
Comment thread src/cli/experimental.rs Outdated
…ONMALLOC

Free-threaded CPython (3.13t+) refuses to start with PYTHONMALLOC=malloc,
so the valgrind executor skips that override when the interpreter is
free-threaded. The detection only probed `python` on the PATH, which
misses the interpreter the benchmark actually runs under when it lives
in a virtual environment or is selected by uv.

Probe every interpreter the command could resolve to and skip the
override if any of them is free-threaded:

- `python` / `python3` on the PATH
- `$VIRTUAL_ENV/bin/python`
- `.venv/bin/python` in the benchmark working directory
- the interpreter `uv python find $UV_PYTHON` resolves to; when uv has
  not downloaded it yet, classify the request string (`3.13t`,
  `+freethreaded`) directly

The probe reads `sys.abiflags` instead of `sysconfig`, since
`sysconfig` fails to import when `_PYTHON_SYSCONFIGDATA_NAME` is set
for a different interpreter, which turned the old check into a false
negative for exactly the free-threaded venvs it needs to detect.
Add an experimental flag that unsets PYTHONMALLOC for simulation runs, allowing integrations to validate workloads without the forced malloc allocator before it becomes the default behavior.
@not-matthias
not-matthias force-pushed the cod-296-fails-with-python313-freethreaded branch from 51f8918 to 5af022c Compare September 18, 2026 11:42
@not-matthias

Copy link
Copy Markdown
Member Author

@greptileai review

Comment thread src/executor/valgrind/helpers/python.rs
@not-matthias
not-matthias merged commit 5af022c into main Sep 18, 2026
48 checks passed
@not-matthias
not-matthias deleted the cod-296-fails-with-python313-freethreaded branch September 18, 2026 12:14
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.

2 participants