[all modules] Python is not found #104

Closed
opened 2026-06-23 20:04:49 -04:00 by justin · 1 comment
Owner

most physical systems use python3 as the command for python not python. we need to switch all mentions of python (when used as a command) to python3


Build scope (AI-ready)

Problem

Course content invokes the interpreter as a bare python (e.g. python cli.py list). On most current systems — default Debian/Ubuntu and macOS — there is no python on PATH, only python3, so learners who copy these commands into their host shell hit command not found. The repo's own infrastructure (CI, tools/check.sh, tools/build_wiki.py, security-scan.sh, audit.sh, verify.sh, shebangs) already standardized on python3; the course-facing prose, lab READMEs, lab .py docstrings, blog posts, and a few Dockerfiles/CI examples did not. Goal: make python3 the canonical command name everywhere it is used as a host-shell command.

Scope of the change

~103 files contain a python <something> command invocation. The replacement is mechanically simple but is not a blind global sed s/python /python3 / — several contexts are commands-in-name-only or already correct and must be left alone (see Stop-lines). The real edit set:

  • Module READMEs (modules/*/README.md) and lab READMEs (modules/*/lab/**/README.md, capstone/README.md, capstone/lab/start/README.md): python cli.py …, python -m unittest/pytest, python --version, etc.
  • Lab .py docstrings / usage comments that show python cli.py … (e.g. modules/01-the-copy-paste-problem/lab/start/cli.py, every lab/start/cli.py, tasks-app/cli.py, serve.py, triage.py, reviewer.py, orient.py, sync.py, run_eval.py, llm_judge.py, tasks_mcp_server.py, reference_test_tasks.py). These are comments, not executed code — no behavior change, just the printed instructions.
  • Blog posts (blog/*.md): same command examples mirrored from the modules.
  • Lab prompt / instruction files: modules/07-*/lab/agent-a-prompt.md, agent-b-prompt.md, modules/26-*/lab/agent-prompts/agent-42-count.md, agent-44-clear.md, modules/05-*/lab/instructions-file-starter.md, modules/09-*/lab/example-issues.md, modules/11-*/lab/issue.md, modules/24-*/lab/sample-issue.md, modules/21-*/lab/add-command-skill.md, modules/22-*/lab/suspicious-skill/SKILL.md.
  • modules/04-*/lab/verify.sh: line invoking python cli.py (the rest of that script already uses python3).

Command forms to convert: python cli.py, python -m unittest|pytest, python -c "…", python --version, python <script>.py (serve.py, triage.py, reviewer.py, run_eval.py, llm_judge.py, orient.py, sync.py, agent_runner.py, tasks_mcp_server.py, tools/sync.py).

Stop-lines — do NOT change these

  1. Module 01 convention note must be inverted, not just substituted. modules/01-the-copy-paste-problem/README.md lines ~151–154 (mirrored in blog/02-getting-started-the-copy-paste-problem.md) contain a deliberate note: "whichever of python / python3 just printed a version, that's the one you'll type … we write python … read it as python3 if that's command-not-found." This note makes python the canonical course-wide spelling. Flipping the commands without rewriting this note leaves the course self-contradicting. Rewrite it so python3 is the canonical spelling and python is the fallback (and keep the python --version / python3 --version "check which you have" guidance).
  2. venv-internal interpreter references (Module 20) stay python. modules/20-mcp-servers-giving-the-ai-hands/README.md deliberately teaches that a bare "command": "python" in MCP config is the #1 connection failure, and instructs using the venv's absolute path .venv/bin/python / ...\.venv\Scripts\python.exe. Leave every .venv/bin/python, python.exe, the "command": "python" example being warned against, and the surrounding prose untouched. Line 273 already correctly uses python3 -m venv. Only the bare host-shell examples here (python cli.py list, python tasks_mcp_server.py) convert to python3.
  3. Image names are not commands. FROM python:3.12-slim, image: python:3.12, docker run … python:3.12-slim … — the python: token is a Docker image tag, never touch it.
  4. Container-internal invocations are a judgment call — default: leave as python. In modules/16-*/lab/Dockerfile (ENTRYPOINT ["python","cli.py"]), modules/18-*/lab/Dockerfile (CMD ["python","serve.py"], HEALTHCHECK … python -c), the M16 README docker run … python:3.12-slim python -c/-m, and the CI-example yamls (modules/14-*/lab/ci-starter.yml uses actions/setup-pythonpython symlink; gitlab-ci-starter.yml runs in image: python:3.12), python resolves correctly because the python base image / setup-python provides it. These are not "physical systems." Recommended: leave them as python (they are correct and changing them risks implying the base image lacks python). If the implementer prefers uniformity, converting them is harmless but optional — pick one and be consistent. The lab cli.py docstrings copied into these modules still convert (they describe host-shell usage).
  5. The word "Python" the language (capital P in prose, "Python 3.10+", python:3.12-slim) is not a command — leave it.
  6. Already-python3 infrastructure (tools/, .gitea/workflows/, .github/workflows/, tools/check.sh, security-scan.sh, audit.sh, shebangs #!/usr/bin/env python3) is already correct — no change.

Open decision: pippip3?

The same "physical systems only ship pip3" logic applies to ~30 bare pip install … occurrences (ruff, bandit, pip-audit, pytest, mcp[cli], etc. across modules 05/13/14/15/16/17/18/19/20/23/24/25 and blogs). The Module 01 convention note explicitly pairs python3 with pip3, so flipping pythonpython3 while leaving pip makes that note inconsistent. The issue text names only python. Recommendation: include the companion pippip3 (or python3 -m pip) change for consistency, OR explicitly note in the PR that pip was left out of scope. Confirm with the maintainer if unsure; do not silently do half. (Same container/CI stop-lines apply: pip inside a Dockerfile/python image is fine.)

Recommended approach

  1. Rewrite the Module 01 convention note (and its blog mirror) to make python3 canonical (Stop-line 1) — do this first so the rest of the change is consistent with the stated convention.
  2. Convert host-shell python <cmd>python3 <cmd> across the file set above, respecting every stop-line. A scripted pass is fine but must exclude: image-tag lines (python:), .venv/.../python paths, python.exe, the M20 "command": "python" teaching examples, and (default) container/CI-internal invocations. Hand-review Module 20 and the two Dockerfiles rather than sed-ing them.
  3. Decide pip (above) and apply uniformly.

Acceptance criteria / how to verify

  • Build: python3 tools/build_wiki.py --repo-root . --out /tmp/awc-wiki-build --web-base https://git.jpaul.io/justin/ai-workflow-course --branch main --host gitea succeeds (the CI build step).
  • Test: bash tools/check.sh passes — lab .py still py-compiles, shell scripts still parse, JSON/YAML still parse, no-em-dash guard clean, every README still has its template sections. (Docstring/comment edits don't affect compilation, but run it to be sure nothing structural broke.)
  • Grep audit: after the change, grep -rnE '\bpython ' modules capstone blog | grep -vE 'python3|python:|\.venv|python\.exe' should return only the deliberately-retained container/CI-internal and M20-"command" cases (Stop-lines 2/4) — review each remaining hit and confirm it's an intentional keep.
  • Spot-check Module 01 reads coherently: the convention note now establishes python3 as canonical and the lab commands match it.
  • Both CI workflows (.gitea/workflows/ci.yml, .github/workflows/ci.yml) are green on the PR.

Target surface(s)

Course content only: modules/**, capstone/**, blog/** (Markdown, lab .py docstrings/comments, lab .sh/.yml examples, lab prompt files). No application logic changes — the lab .py files only change in comments/docstrings. No changes to tools/, .gitea/, .github/ infrastructure (already python3).

most physical systems use python3 as the command for python not python. we need to switch all mentions of python (when used as a command) to python3 --- ## Build scope (AI-ready) ### Problem Course content invokes the interpreter as a bare `python` (e.g. `python cli.py list`). On most current systems — default Debian/Ubuntu and macOS — there is no `python` on PATH, only `python3`, so learners who copy these commands into their host shell hit `command not found`. The repo's own infrastructure (CI, `tools/check.sh`, `tools/build_wiki.py`, `security-scan.sh`, `audit.sh`, `verify.sh`, shebangs) already standardized on `python3`; the **course-facing prose, lab READMEs, lab `.py` docstrings, blog posts, and a few Dockerfiles/CI examples** did not. Goal: make `python3` the canonical command name everywhere it is used as a host-shell command. ### Scope of the change ~103 files contain a `python <something>` command invocation. The replacement is mechanically simple but is **not** a blind global `sed s/python /python3 /` — several contexts are commands-in-name-only or already correct and must be left alone (see Stop-lines). The real edit set: - **Module READMEs** (`modules/*/README.md`) and **lab READMEs** (`modules/*/lab/**/README.md`, `capstone/README.md`, `capstone/lab/start/README.md`): `python cli.py …`, `python -m unittest/pytest`, `python --version`, etc. - **Lab `.py` docstrings / usage comments** that show `python cli.py …` (e.g. `modules/01-the-copy-paste-problem/lab/start/cli.py`, every `lab/start/cli.py`, `tasks-app/cli.py`, `serve.py`, `triage.py`, `reviewer.py`, `orient.py`, `sync.py`, `run_eval.py`, `llm_judge.py`, `tasks_mcp_server.py`, `reference_test_tasks.py`). These are comments, not executed code — no behavior change, just the printed instructions. - **Blog posts** (`blog/*.md`): same command examples mirrored from the modules. - **Lab prompt / instruction files**: `modules/07-*/lab/agent-a-prompt.md`, `agent-b-prompt.md`, `modules/26-*/lab/agent-prompts/agent-42-count.md`, `agent-44-clear.md`, `modules/05-*/lab/instructions-file-starter.md`, `modules/09-*/lab/example-issues.md`, `modules/11-*/lab/issue.md`, `modules/24-*/lab/sample-issue.md`, `modules/21-*/lab/add-command-skill.md`, `modules/22-*/lab/suspicious-skill/SKILL.md`. - **`modules/04-*/lab/verify.sh`**: line invoking `python cli.py` (the rest of that script already uses `python3`). Command forms to convert: `python cli.py`, `python -m unittest|pytest`, `python -c "…"`, `python --version`, `python <script>.py` (`serve.py`, `triage.py`, `reviewer.py`, `run_eval.py`, `llm_judge.py`, `orient.py`, `sync.py`, `agent_runner.py`, `tasks_mcp_server.py`, `tools/sync.py`). ### Stop-lines — do NOT change these 1. **Module 01 convention note must be *inverted*, not just substituted.** `modules/01-the-copy-paste-problem/README.md` lines ~151–154 (mirrored in `blog/02-getting-started-the-copy-paste-problem.md`) contain a deliberate note: *"whichever of `python` / `python3` just printed a version, that's the one you'll type … we write `python` … read it as `python3` if that's command-not-found."* This note makes `python` the canonical course-wide spelling. Flipping the commands without rewriting this note leaves the course self-contradicting. Rewrite it so `python3` is the canonical spelling and `python` is the fallback (and keep the `python --version` / `python3 --version` "check which you have" guidance). 2. **venv-internal interpreter references (Module 20) stay `python`.** `modules/20-mcp-servers-giving-the-ai-hands/README.md` deliberately teaches that a bare `"command": "python"` in MCP config is the #1 connection failure, and instructs using the venv's absolute path `.venv/bin/python` / `...\.venv\Scripts\python.exe`. Leave every `.venv/bin/python`, `python.exe`, the `"command": "python"` example being warned against, and the surrounding prose untouched. Line 273 already correctly uses `python3 -m venv`. Only the bare host-shell examples here (`python cli.py list`, `python tasks_mcp_server.py`) convert to `python3`. 3. **Image names are not commands.** `FROM python:3.12-slim`, `image: python:3.12`, `docker run … python:3.12-slim …` — the `python:` token is a Docker image tag, never touch it. 4. **Container-internal invocations are a judgment call — default: leave as `python`.** In `modules/16-*/lab/Dockerfile` (`ENTRYPOINT ["python","cli.py"]`), `modules/18-*/lab/Dockerfile` (`CMD ["python","serve.py"]`, `HEALTHCHECK … python -c`), the M16 README `docker run … python:3.12-slim python -c/-m`, and the CI-example yamls (`modules/14-*/lab/ci-starter.yml` uses `actions/setup-python` → `python` symlink; `gitlab-ci-starter.yml` runs in `image: python:3.12`), `python` resolves correctly because the python base image / setup-python provides it. These are not "physical systems." Recommended: leave them as `python` (they are correct and changing them risks implying the base image lacks `python`). If the implementer prefers uniformity, converting them is harmless but optional — pick one and be consistent. **The lab `cli.py` docstrings copied into these modules still convert** (they describe host-shell usage). 5. **The word "Python" the language** (capital P in prose, "Python 3.10+", `python:3.12-slim`) is not a command — leave it. 6. **Already-`python3` infrastructure** (`tools/`, `.gitea/workflows/`, `.github/workflows/`, `tools/check.sh`, `security-scan.sh`, `audit.sh`, shebangs `#!/usr/bin/env python3`) is already correct — no change. ### Open decision: `pip` → `pip3`? The same "physical systems only ship `pip3`" logic applies to ~30 bare `pip install …` occurrences (ruff, bandit, pip-audit, pytest, `mcp[cli]`, etc. across modules 05/13/14/15/16/17/18/19/20/23/24/25 and blogs). The Module 01 convention note explicitly **pairs** `python3` with `pip3`, so flipping `python`→`python3` while leaving `pip` makes that note inconsistent. The issue text names only `python`. **Recommendation: include the companion `pip`→`pip3` (or `python3 -m pip`) change for consistency, OR explicitly note in the PR that pip was left out of scope.** Confirm with the maintainer if unsure; do not silently do half. (Same container/CI stop-lines apply: `pip` inside a Dockerfile/python image is fine.) ### Recommended approach 1. Rewrite the Module 01 convention note (and its blog mirror) to make `python3` canonical (Stop-line 1) — do this first so the rest of the change is consistent with the stated convention. 2. Convert host-shell `python <cmd>` → `python3 <cmd>` across the file set above, respecting every stop-line. A scripted pass is fine but must exclude: image-tag lines (`python:`), `.venv/.../python` paths, `python.exe`, the M20 `"command": "python"` teaching examples, and (default) container/CI-internal invocations. Hand-review Module 20 and the two Dockerfiles rather than sed-ing them. 3. Decide pip (above) and apply uniformly. ### Acceptance criteria / how to verify - **Build:** `python3 tools/build_wiki.py --repo-root . --out /tmp/awc-wiki-build --web-base https://git.jpaul.io/justin/ai-workflow-course --branch main --host gitea` succeeds (the CI build step). - **Test:** `bash tools/check.sh` passes — lab `.py` still py-compiles, shell scripts still parse, JSON/YAML still parse, no-em-dash guard clean, every README still has its template sections. (Docstring/comment edits don't affect compilation, but run it to be sure nothing structural broke.) - **Grep audit:** after the change, `grep -rnE '\bpython ' modules capstone blog | grep -vE 'python3|python:|\.venv|python\.exe'` should return only the deliberately-retained container/CI-internal and M20-`"command"` cases (Stop-lines 2/4) — review each remaining hit and confirm it's an intentional keep. - **Spot-check Module 01** reads coherently: the convention note now establishes `python3` as canonical and the lab commands match it. - Both CI workflows (`.gitea/workflows/ci.yml`, `.github/workflows/ci.yml`) are green on the PR. ### Target surface(s) Course content only: `modules/**`, `capstone/**`, `blog/**` (Markdown, lab `.py` docstrings/comments, lab `.sh`/`.yml` examples, lab prompt files). No application logic changes — the lab `.py` files only change in comments/docstrings. No changes to `tools/`, `.gitea/`, `.github/` infrastructure (already `python3`).
justin added the autopilot label 2026-06-23 20:04:49 -04:00
claude added the ai-ready label 2026-06-23 20:08:31 -04:00
claude removed the autopilot label 2026-06-23 20:25:06 -04:00
Contributor

🤖 autopilot: merged @ (merge-only — no deploy to verify).

🤖 autopilot: merged @ (merge-only — no deploy to verify).
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: justin/ai-workflow-course#104