Skip to content

Make scripts/run_demo.py and scripts/check.py run on Windows - #2

Open
FormosaMCN wants to merge 2 commits into
anthropics:mainfrom
FormosaMCN:windows-run-demo-compat
Open

Make scripts/run_demo.py and scripts/check.py run on Windows#2
FormosaMCN wants to merge 2 commits into
anthropics:mainfrom
FormosaMCN:windows-run-demo-compat

Conversation

@FormosaMCN

@FormosaMCN FormosaMCN commented Sep 3, 2026

Copy link
Copy Markdown

scripts/run_demo.py assumes a POSIX host and fails before any web app starts, so the demos cannot be run on Windows at all. scripts/check.py fails on the first result line for an unrelated reason on the same platform.

What was broken

  1. node_modules/.bin/next is a shell shim on Windows, not something CreateProcess can execute. Starting the storefront raised OSError: [WinError 193] %1 is not a valid Win32 application.
  2. Shutdown called os.killpg / os.getpgid, which do not exist on Windows, so the failure above surfaced as an AttributeError from the finally block and left uvicorn orphaned on its port.
  3. Both scripts print check marks. A Windows console in a non-UTF-8 code page (cp950 here, cp1252 elsewhere) cannot encode them, so run_demo.py's log-relay threads and its "demo is up" line, and check.py's first ok(), all die with UnicodeEncodeError.

What changed

  • Point NEXT at next.cmd on Windows, and use npm.cmd for the first-run workspace install for the same reason.
  • Route termination through a stop_process() helper: taskkill /T /F on Windows, and the existing SIGTERM-then-SIGKILL process-group path everywhere else.
  • Reconfigure stdout to UTF-8 in both scripts.

No behaviour change on POSIX.

Note on the second commit

The helper was originally named terminate(). That was wrong: main() already defines a local terminate(signum, frame) signal handler, which shadowed it throughout main()'s body — including the finally block that calls it. Shutdown raised TypeError: terminate() missing 1 required positional argument: 'frame' and left the child servers running. The second commit renames it and adds the encoding fixes; both are worth reading together.

Verification

On Windows 11, Python 3.11, Node 24, cp950 console:

  • All four verticals boot with python scripts/run_demo.py <vertical> --all — API, storefront, and merchant portal each answer, and the ✓ ... demo is up banner renders.
  • stop_process() takes down a spawned process tree (checked directly against a live child).
  • ruff check . and ruff format --check . pass; scripts/check.py reports clean with no environment overrides.
  • pytest: 1103 passed, 1 skipped, 1 failed — see below.

Notes for a reviewer

Two Windows findings are not addressed here, because neither is a bug in these scripts:

  • commerce-common/tests/test_memory_stores.py::test_the_file_store_is_owner_only_and_keeps_purge_generations_across_instances fails on Windows: it asserts mode 0o600 and gets 0o666. NTFS has no POSIX mode bits, so os.chmod cannot express owner-only there. That is a real gap for a Windows deployment, not just a test artifact, and it probably deserves either a skip with a reason or a note in docs/safety.md.
  • tzdata is not in requirements.txt. Windows ships no system IANA database, so without it four timezone tests fail with unknown IANA timezone: 'Europe/Lisbon'. A tzdata; sys_platform == "win32" marker would cover it.

🤖 Generated with Claude Code

Mars-ai88 and others added 2 commits September 3, 2026 20:00
run_demo.py assumed a POSIX host and failed before any web app started.

- `node_modules/.bin/next` is a shell shim on Windows, not something
  CreateProcess can execute; starting the storefront raised
  OSError: [WinError 193]. Point NEXT at `next.cmd` there, and use
  `npm.cmd` for the first-run workspace install for the same reason.
- Shutdown called os.killpg/os.getpgid, which do not exist on Windows,
  so the failure above surfaced as AttributeError from the finally block
  and left the API process orphaned on its port. Route termination
  through a `terminate()` helper that uses `taskkill /T /F` on Windows
  and keeps the existing SIGTERM-then-SIGKILL process-group path
  elsewhere.

Verified on Windows 11: `python scripts/run_demo.py retail --all` now
boots the API (:8000), storefront (:3000), and merchant portal (:3100),
and Ctrl-C takes the whole tree down.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Follow-ups found by running all four verticals on a cp950 console.

- run_demo.py: main() defines a local `terminate(signum, frame)` signal
  handler, which shadowed the module-level helper added in the previous
  commit, including in main()'s own finally block. Shutdown therefore
  raised `TypeError: terminate() missing 1 required positional argument:
  'frame'` and left child servers holding their ports. Rename the helper
  to `stop_process`.
- run_demo.py and check.py both print check marks. On a Windows console
  in a non-UTF-8 code page these die with UnicodeEncodeError: the log
  relay threads and the "demo is up" line in run_demo.py, and the first
  ok() in check.py. Reconfigure stdout to UTF-8 in both.

Verified on Windows 11 (cp950): all four verticals boot with
`run_demo.py <vertical> --all`, `stop_process` takes down a spawned
process tree, and `scripts/check.py` reports clean with no environment
overrides.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@FormosaMCN FormosaMCN changed the title Make scripts/run_demo.py run on Windows Make scripts/run_demo.py and scripts/check.py run on Windows Sep 3, 2026

@sylvesterkaczmarek sylvesterkaczmarek left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stop_process(..., force=False) still passes /F to taskkill, so the first Windows shutdown pass is already a forced kill. The 10-second wait and later force=True escalation therefore have no effect, unlike the POSIX SIGTERM→SIGKILL flow. Could /F be added only when force is true, with a graceful-first shutdown regression?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants