--- model: claude-opus-4-7[1m] service: claude timestamp: 2026-04-17T12:44:37Z git_ref: 5cd6df5 diff_cmd: git diff 5cd6df5~1..5cd6df5 --- Code generated in this turn was committed verbatim as `5cd6df58` ("Add `'subint'` spawn backend scaffold (#379)"). Per diff-ref mode, per-file code is captured via the pointers below, each followed by a prose summary. Non-code output (sanity-check results, design rationale) is included verbatim. ## Per-file generated content ### `tractor/spawn/_subint.py` (new, 100 lines) > `git diff 5cd6df5~1..5cd6df5 -- tractor/spawn/_subint.py` New scaffolding module for the PEP 734 subinterpreter backend. Contents: - AGPL header + module docstring (describes backend intent, 3.14+ availability gate, and explicit "SCAFFOLDING STUB" status pointing at issue #379). - Top-level `try/except ImportError` wrapping `from concurrent import interpreters as _interpreters` → sets module-global `_has_subints: bool`. This lets the registry stay introspectable on py<3.14 while spawn-time still fails cleanly. - `subint_proc()` coroutine with signature matching `trio_proc`/`mp_proc` exactly (same param names, defaults, and `TaskStatus[Portal]` typing) — intentional so Phase B.2 can drop the impl in without touching `_methods` or changing call-site binding. - Body raises `RuntimeError` on py<3.14 (with `sys.version` printed) or `NotImplementedError` with issue-#379 URL on py≥3.14. ### `tractor/spawn/_spawn.py` (modified, +15 LOC) > `git diff 5cd6df5~1..5cd6df5 -- tractor/spawn/_spawn.py` - `import sys` re-added (pruned during Phase A, now needed again for the py-version string in the `'subint'` gate-error). - `SpawnMethodKey = Literal[...]` grows `'subint'` as the 4th member, with inline comment `# py3.14+ via `concurrent.interpreters` (PEP 734)`. - `try_set_start_method()` match-block grows a new `case 'subint':` arm that imports `from ._subint import _has_subints` lazily and raises `RuntimeError` with a multi-line gate msg if unavailable. - Bottom-of-module late-import section grows `from ._subint import subint_proc` alongside the existing `_trio` / `_mp` imports. - `_methods` dict grows `'subint': subint_proc`. ### `tractor/_testing/pytest.py` (modified, +8 LOC) > `git diff 5cd6df5~1..5cd6df5 -- tractor/_testing/pytest.py` `pytest_configure()` wraps the `try_set_start_method(backend)` call in a `try/except RuntimeError` that re-raises as `pytest.UsageError(str(err))`. Rationale: the gate error on py<3.14 is legitimately a configuration problem, not a test failure, so pytest's UsageError path (exit code 4) gives a clean single-line banner instead of a traceback. ### `pyproject.toml` (modified, +2 / -1) > `git diff 5cd6df5~1..5cd6df5 -- pyproject.toml` - `requires-python` pin relaxed `>=3.12, <3.14` → `>=3.12, <3.15` to admit 3.14 as a valid target. - Added `"Programming Language :: Python :: 3.14"` to the trove classifiers. ## Non-code output (verbatim) ### Design choices captured in the prior turn (Previously confirmed by the user on April 17 in this session — relevant excerpts captured here for provenance since they drove the shape of the impl): 1. **Python pin**: `<3.15` + feature-gate the subint backend at spawn time — user answered option (a) from the design triage. 2. **Deferred `fork()`-via-subint hack** from issue #379's "Our own thoughts" section. 3. **Phase B phasing**: user approved the B.1 / B.2 / B.3 / B.4 breakdown — this commit is strictly B.1 (scaffolding only, no spawn-flow impl). 4. **Option (B) worktree strategy**: new worktree branched from `wkt/spawn_modularize`. *(Amended by user at runtime: user switched the existing `spawn_modularize` worktree to the `subint_spawner_backend` branch instead.)* ### Sanity-check output (verbatim terminal excerpts) Registry / feature-gate verification on py3.13: ``` SpawnMethodKey values: ('trio', 'mp_spawn', 'mp_forkserver', 'subint') _methods keys: ['trio', 'mp_spawn', 'mp_forkserver', 'subint'] _has_subints: False (py version: (3, 13) ) [expected] RuntimeError: The 'subint' spawn backend requires Python 3.14+ (stdlib `concurrent.interpreters`, PEP 734). ``` `try_set_start_method('subint')` gate on py3.13: ``` [expected] RuntimeError: Spawn method 'subint' requires Python 3.14+ (stdlib `concurrent.interpreters`, PEP 734). ``` Pytest `--spawn-backend=subint` on py3.13 (the new UsageError wrapper kicking in): ``` ERROR: Spawn method 'subint' requires Python 3.14+ (stdlib `concurrent.interpreters`, PEP 734). Current runtime: 3.13.11 (main, Dec 5 2025, 16:06:33) [GCC 15.2.0] ``` Collection probe: `404 tests collected in 0.18s` (no import errors from the new module). Spawn-relevant test subset (`tests/test_local.py test_rpc.py test_spawning.py test_multi_program.py tests/discovery/`): ``` 69 passed, 1 skipped, 10 warnings in 61.38s ``` Full suite was **not** run on py3.13 for this commit — the scaffolding is no-op on <3.14 and full-suite validation under py3.14 is pending that venv being set up by the user. ### Commit message Also AI-drafted (via `/commit-msg`, with the prose rewrapped through `/home/goodboy/.claude/skills/pr-msg/ scripts/rewrap.py --width 67`) — the 33-line message on commit `5cd6df58` itself. Not reproduced here; see `git log -1 5cd6df58`. ### Known follow-ups flagged to user - **`uv.lock` deferred**: pin-bump regenerated cp314 wheel entries in `uv.lock`, but the user chose to not stage `uv.lock` for this commit. Warned explicitly. - **Phase B.2 needs py3.14 venv** — running the actual subint impl requires it; user said they'd set it up separately.