Python Launch Lab — Project Plan¶
Overview¶
This lab systematically measures how Python launch modes behave on Windows across every major launcher and packaging mechanism. Each scenario is run, inspected, and recorded as machine-readable evidence.
Milestone M0 — Repo Skeleton ✅¶
- [x] Repository structure created
- [x]
pyproject.tomlwithlaunch_labpackage andpy-launch-labCLI - [x] Python modules:
cli,models,matrix,runner,inspect_pe,detect_windows,collect,report,html_report,util - [x] Fixture directories:
pkg_console,pkg_gui,pkg_dual,raw_py,raw_pyw,direct_exec - [x] Rust crate
pyshim-wincompiling on Windows - [x] GitHub Actions CI (
windows.yml,docs.yml) - [x] Basic unit tests: schema, matrix generation, importability
Milestone M1 — Static PE Inspection ✅¶
- [x] Implement
inspect_pe.py: read PE header from any Windows EXE - [x] Classify
IMAGE_SUBSYSTEM_WINDOWS_GUIvsIMAGE_SUBSYSTEM_WINDOWS_CUI - [x] Support inspection of Python, PythonW, uv, uvw executables
- [x] Store
pe_subsystemfield in result objects - [x] Unit tests for PE inspection (synthetic PE files and real executables on Windows)
Milestone M2 — Direct Python vs PythonW Launch Validation ✅¶
- [x] Implement
runner.py: spawn child processes with controlled environment - [x] Detect whether spawned process opens a console window (
detect_windows.pyusesCreateToolhelp32Snapshot) - [x] Detect
conhost.exeappearing in process tree - [x] Record
stdout_available,stderr_available,visible_window_detected - [x] Implement integration tests:
test_python_vs_pythonw.py - [x] Capture evidence artifacts for
python script.pyvspythonw script.py
Milestone M3 — uv and uvw Scenario Coverage ✅¶
- [x] Run scenarios for
uv run script.py,uv run script.pyw,uv run --gui-script - [x] Run scenarios for
uvxanduv tool run - [x] Run
uv tool installfor console and GUI fixture packages - [x] Integration tests:
test_uv_run.py,test_uv_tool_install.py,test_uvx.py,test_uvw.py - [x] Populate
artifacts/json/with per-scenario result JSON
Milestone M4 — Rust Shim Integration ✅¶
- [x] Implement
pyshim-winCLI with--hide-consoleflag (clap-based) - [x] Implement
launch.rs: spawn child process usingCreateProcessWwithCREATE_NO_WINDOWflag - [x] Implement
resolve.rs: locatepython,pythonw,uv,uvwon PATH with GUI alternative support - [x] Implement
detect.rs: detect console vs GUI subsystem via PE header parsing - [x] Emit structured JSON result from shim
- [x] Integration test:
test_shim.py
Milestone M5 — CI Artifacts and Reporting ✅¶
- [x] GitHub Actions
windows.ymlruns full matrix on Windows runners - [x] Artifacts uploaded to workflow run (JSON, Markdown, HTML)
- [x]
report.pygenerates Markdown summary from JSON results - [x]
html_report.pygenerates self-contained HTML report - [x]
docs/findings/populated with per-run findings - [x]
docs.ymldeploys docs to GitHub Pages using mkdocs-material
Scenario Matrix¶
See scenario-matrix.md for the full table.
Key Design Decisions¶
- Data-driven scenarios — scenario definitions live in
matrix.pyas plain Python objects, not embedded in test code. - Hard evidence — every scenario emits a JSON artifact; nothing is claimed without a recorded result.
- Windows first — PE inspection, process tree capture, and console detection are Windows-specific; non-Windows runs are skipped gracefully.
- No shell indirection — processes are spawned directly, not through
cmd.exeor PowerShell, unless a scenario explicitly tests shell behavior. - Rust shim —
pyshim-winis compiled as a GUI-subsystem executable so it never opens its own console window.