Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Free-threaded Python (3.14t/3.15t): importing _objtrace re-enables the GIL

Aperta
#867 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
39/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
python

Direzione di ricerca

Start with scout_apm/core/objtrace.py and the _objtrace C extension; inspect how the fallback is selected and where the extension declares module slots. Then review .github/workflows/main.yml and the tox environment selection for Python 3.14t and 3.15t. The issue proposes a short term fallback and CI coverage, while making the extension free-threading safe requires investigation and stress tests.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Problem

We publish free-threaded wheels (cp314t and cp315t). For example, scout-apm 4.0.0 on PyPI includes scout_apm-4.0.0-cp314-cp314t-*.whl, and cibuildwheel builds cp315t wheels on master. But nothing in CI tests the free-threaded builds, and the _objtrace C extension never declares that it's safe to run without the GIL. It has no Py_mod_gil slot.

So when scout_apm.core.install() imports scout_apm.core._objtrace on a free-threaded interpreter, CPython turns the GIL back on for the whole process:

RuntimeWarning: The global interpreter lock (GIL) has been enabled to load module 'scout_apm.core._objtrace', which has not declared that it can run safely without the GIL. To override this behavior and keep the GIL disabled (at your own risk), run with PYTHON_GIL=0 or -Xgil=0.

The impact:

  • Any free-threaded app with scout-apm installed quietly loses free-threading. sys._is_gil_enabled() becomes True after the import.
  • When warnings are errors (-W error, or our own pytest.ini), the import raises RuntimeWarning. The fallback in objtrace.py only catches ImportError, so the exception isn't handled. A free-threaded CI job would fail on this right away.

Reproduce

uv venv -p 3.15t venv && VIRTUAL_ENV=venv uv pip install "scout-apm @ ."
venv/bin/python -c "import sys; from scout_apm.core import objtrace; print(objtrace.is_extension, sys._is_gil_enabled())"
# RuntimeWarning as above, then: True True

What objtrace provides

objtrace only produces the per-span allocation tags: allocations, start_allocations and stop_allocations (tracked_request.py, add_allocation_tags). Memory increase per request (RSS via psutil) and the memory sampler don't depend on it. The agent already runs without objtrace on PyPy, with SCOUT_DISABLE_EXTENSIONS=1, and whenever the optional extension fails to compile. In those cases add_allocation_tags() just skips the tags.

Proposed plan

  1. Short term: on free-threaded builds, use the existing no-op fallback in objtrace.py instead of importing the extension, for example when sysconfig.get_config_var("Py_GIL_DISABLED") is set. The GIL stays off, and allocation tags are skipped like they are on PyPy.
  2. CI: add 3.14t and 3.15t jobs, with py314t-* and py315t-* tox envs. The env selection in main.yml currently strips the version down to digits (3.15t becomes 315) and matches ^py315 as a prefix, so it would also need to match the t suffix exactly.
  3. Longer term (needs investigation): make _objtrace actually safe without the GIL and declare Py_MOD_GIL_NOT_USED. The counters are already thread-local (__thread). The open questions:
    • enable() and disable() read and write installed without a lock. A concurrent double enable() would wrap our own hook and recurse infinitely.
    • We'd need to confirm whether calling PyMem_SetAllocator at runtime, while other threads are allocating, is safe on free-threaded CPython.
    • Stress tests on 3.14t/3.15t would be needed before shipping.
  4. Docs: say which Python builds and interpreters report allocation counts. Today the docs don't mention objtrace, PyPy or SCOUT_DISABLE_EXTENSIONS at all.

Found while adding Python 3.15 CI in #866.

Lingua principale
Python
Stelle
77
Fork
19
Merge medio
4h 6m
PR unite (30g)
2

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di scoutapp/scout_apm_python

Tutte le issue di scoutapp/scout_apm_python

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.