Expand `/run-tests` venv pre-flight to cover all cases

Rework section 3 from a worktree-only check into a
structured 3-step flow: detect active venv, interpret
results (Case A: active, B: none, C: worktree), then
run import + collection checks.

Deats,
- Case B prompts via `AskUserQuestion` when no venv
  is detected, offering `uv sync` or manual activate
- add `uv run` fallback section for envs where venv
  activation isn't practical
- new allowed-tools: `uv run python`, `uv run pytest`,
  `uv pip show`, `AskUserQuestion`

(this commit msg was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
subint_spawner_backend
Gud Boi 2026-04-14 18:05:32 -04:00
parent 263249029b
commit 355beac082
1 changed files with 88 additions and 21 deletions

View File

@ -8,8 +8,11 @@ allowed-tools:
- Bash(python -m pytest *) - Bash(python -m pytest *)
- Bash(python -c *) - Bash(python -c *)
- Bash(python --version *) - Bash(python --version *)
- Bash(git rev-parse *) - Bash(UV_PROJECT_ENVIRONMENT=py* uv run python *)
- Bash(UV_PROJECT_ENVIRONMENT=py* uv run pytest *)
- Bash(UV_PROJECT_ENVIRONMENT=py* uv sync *) - Bash(UV_PROJECT_ENVIRONMENT=py* uv sync *)
- Bash(UV_PROJECT_ENVIRONMENT=py* uv pip show *)
- Bash(git rev-parse *)
- Bash(ls *) - Bash(ls *)
- Bash(cat *) - Bash(cat *)
- Bash(jq * .pytest_cache/*) - Bash(jq * .pytest_cache/*)
@ -17,6 +20,7 @@ allowed-tools:
- Grep - Grep
- Glob - Glob
- Task - Task
- AskUserQuestion
--- ---
Run the `tractor` test suite using `pytest`. Follow this Run the `tractor` test suite using `pytest`. Follow this
@ -91,41 +95,104 @@ python -m pytest tests/ -x --tb=short --no-header --tpt-proto uds
python -m pytest tests/ -x --tb=short --no-header -k "cancel and not slow" python -m pytest tests/ -x --tb=short --no-header -k "cancel and not slow"
``` ```
## 3. Pre-flight checks (before running tests) ## 3. Pre-flight: venv detection (MANDATORY)
### Worktree venv detection **Always verify a `uv` venv is active before running
`python` or `pytest`.** This project uses
`UV_PROJECT_ENVIRONMENT=py<MINOR>` naming (e.g.
`py313`) — never `.venv`.
If running inside a git worktree (`git rev-parse ### Step 1: detect active venv
--git-common-dir` differs from `--git-dir`), verify
the Python being used is from the **worktree's own Run this check first:
venv**, not the main repo's. Check:
```sh
python -c "
import sys, os
venv = os.environ.get('VIRTUAL_ENV', '')
prefix = sys.prefix
print(f'VIRTUAL_ENV={venv}')
print(f'sys.prefix={prefix}')
print(f'executable={sys.executable}')
"
```
### Step 2: interpret results
**Case A — venv is active** (`VIRTUAL_ENV` is set
and points to a `py<MINOR>/` dir under the project
root or worktree):
Use bare `python` / `python -m pytest` for all
commands. This is the normal, fast path.
**Case B — no venv active** (`VIRTUAL_ENV` is empty
or `sys.prefix` points to a system Python):
Use `AskUserQuestion` to ask the user:
> "No uv venv is active. Should I activate one
> via `UV_PROJECT_ENVIRONMENT=py<MINOR> uv sync`,
> or would you prefer to activate your shell venv
> first?"
Options:
1. **"Create/sync venv"** — run
`UV_PROJECT_ENVIRONMENT=py<MINOR> uv sync` where
`<MINOR>` is detected from `python --version`
(e.g. `313` for 3.13). Then use
`py<MINOR>/bin/python` for all subsequent
commands in this session.
2. **"I'll activate it myself"** — stop and let the
user `source py<MINOR>/bin/activate` or similar.
**Case C — inside a git worktree** (`git rev-parse
--git-common-dir` differs from `--git-dir`):
Verify Python resolves from the **worktree's own
venv**, not the main repo's:
```sh ```sh
python -c "import tractor; print(tractor.__file__)" python -c "import tractor; print(tractor.__file__)"
``` ```
If the path points outside the worktree (e.g. to If the path points outside the worktree, create a
the main repo), set up a local venv first: worktree-local venv:
```sh ```sh
UV_PROJECT_ENVIRONMENT=py<MINOR> uv sync UV_PROJECT_ENVIRONMENT=py<MINOR> uv sync
``` ```
where `<MINOR>` matches the active cpython minor Then use `py<MINOR>/bin/python` for all commands.
version (detect via `python --version`, e.g.
`py313` for 3.13, `py314` for 3.14). Then use
`py<MINOR>/bin/python` for all subsequent commands.
**Why this matters**: without a worktree-local venv, **Why this matters**: without the correct venv,
subprocesses spawned by tractor resolve modules from subprocesses spawned by tractor resolve modules
the main repo's editable install, causing spurious from the wrong editable install, causing spurious
`AttributeError` / `ModuleNotFoundError` for code `AttributeError` / `ModuleNotFoundError`.
that only exists on the worktree's branch.
### Import + collection checks ### Fallback: `uv run`
Always run these, especially after refactors or If the user can't or won't activate a venv, all
module moves — they catch import errors instantly: `python` and `pytest` commands can be prefixed
with `UV_PROJECT_ENVIRONMENT=py<MINOR> uv run`:
```sh
# instead of: python -m pytest tests/ -x
UV_PROJECT_ENVIRONMENT=py313 uv run pytest tests/ -x
# instead of: python -c 'import tractor'
UV_PROJECT_ENVIRONMENT=py313 uv run python -c 'import tractor'
```
`uv run` auto-discovers the project and venv,
but is slower than a pre-activated venv due to
lock-file resolution on each invocation. Prefer
activating the venv when possible.
### Step 3: import + collection checks
After venv is confirmed, always run these
(especially after refactors or module moves):
```sh ```sh
# 1. package import smoke check # 1. package import smoke check