agentleFS
jscott3201jscott3201/yet-more-skills/skills/pyo3-free-threading/SKILL.md

pyo3-free-threading

Skill4 starsChanged 2 months agoApache-2.0View on GitHub

Use to audit or validate PyO3 on GIL-disabled CPython, including module declarations, synchronization, pyclass mutation, global initialization, and dependency imports. Do not infer support from a build flag alone.

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Treat free-threading as a runtime and concurrency contract, not a compiler switch.

    line 9
  2. Distinctive:

    Keep free-threading, subinterpreters, and embedded interpreter restart/finalization as distinct claims.

    line 29

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

PyO3 Free-Threading

Treat free-threading as a runtime and concurrency contract, not a compiler switch. Read the installed Python, PyO3, and native dependency versions before making compatibility claims. Preserve the repository's supported ordinary Python versions.

Establish the environment

Record the executable, implementation/version, native architecture, free-threaded build marker, and actual GIL state before and after importing the extension and its normal dependencies. A free-threaded build can run with the GIL enabled; a dependency import can enable it. Missing runtime introspection is unknown, not proof of disabled execution.

Use the interpreter probe with explicit trusted module names and the intended executable. It runs imports in a bounded child process and reports their origins. It does not build the extension, establish thread safety, or force GIL-disabled mode. Use a scratch working directory and --isolated for an installed-wheel check when that matches the deployment. If the caller forces the GIL off externally, record that separately: it cannot demonstrate that modules voluntarily advertise compatibility.

Audit the shared state

Since PyO3 0.28, generated modules default to declaring thread-safe support. Absence of gil_used=false is not a defect on those versions. An explicit declaration is still not a proof of application invariants. Inspect all exported submodules, dependencies, shared pyclasses, caches, callback registries, globals, and raw/unsafe assumptions.

Python<'py> denotes attachment, not exclusive access to application state on a GIL-disabled runtime. Pyclass borrow checking can reject simultaneous mutable access; it is not a queueing mutex. Define whether concurrent calls serialize, reject, or operate independently. Prefer immutable ownership or appropriately scoped synchronization over blanket unsafe Send/Sync or unsendable annotations.

Detach for long Python-independent work and blocking waits where the pinned API requires it; runtime-wide synchronization can still occur without the GIL. Check joins, one-time initialization, and lock acquisition that can block another thread needing Python. Use PyO3's version-supported PyOnceLock or synchronization helpers when appropriate, but still analyze lock order and reentrant callbacks. Never hold a core lock while invoking arbitrary Python merely because an interpreter-aware lock helper exists.

Validate behavior, not just import

Test the same instance from multiple threads, independent instances, mixed read/write methods, callback exceptions, close during work, and repeated create/destroy. Use barriers/events for ordering and a subprocess timeout for hangs. Run representative ordinary and GIL-disabled variants, verify post-import state, and measure scaling separately from correctness.

Keep free-threading, subinterpreters, and embedded interpreter restart/finalization as distinct claims. Report exact exercised scope and unsupported dependencies. A compatibility opt-out can be honest temporary containment, not a performance success.

Read validation details.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.