fix(python3): preserve user source whitespace and line numbers - #431
josephbajor wants to merge 1 commit into
Conversation
|
@josephbajor is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
🤖 auto-maintain reviewAutomated, advisory triage for
Review panel: 🟡 medium highest severity just-bash maintainer code review: 🟡 medium
General code review: 🟢 low
Adversarial security: 🟢 low
Adversarial security (second opinion): 🟡 medium
Standard Bash and host portability: 🟢 low
Posted by auto-maintain. This automated code review is advisory; a human maintainer makes the call. |
The Python worker prepends four spaces to every line of user code to put it inside a
tryblock. That also changes the contents of multiline strings. Valid Python can silently produce different data, or generate code that then fails withIndentationError. This happens after shell parsing, so changing heredoc quoting does not solve it; stdin,-c, and script files are all affected.Reproduced against upstream
mainat062ce005c0a7676163852fb6f0c8590cbdaa1d45(just-bash 3.4.2).Reproduce the silent data corruption
From a source checkout, run
pnpm install --frozen-lockfile && pnpm --filter just-bash build. Save this asrepro-python.mjsin the repository root, then runnode repro-python.mjs:Current upstream:
With this fix:
The corresponding native Python program is:
It prints
'alpha\nbeta\n'. No spaces occur beforebetaor the closing delimiter in the supplied source.How this becomes an indentation error
Replacing
sourcein the JS example with the following program reproduces the agent-facing failure:Native Python and this branch print
42and exit 0. Current upstream adds four spaces beforeprint(answer())inside the generated string, producing anIndentationErrorand exit 1. The regression suite covers this exact case in all three input modes.Change
Keep the setup and exception handler, but pass the unmodified user text to
compile(..., "exec")and execute that code object in the existing module globals. This executes the user code once in the same interpreter. Cache the original text inlinecacheand supply the user script name (or<stdin>/<string>) so tracebacks show original source lines rather than wrapper offsets.This also lets valid module-level
from __future__imports work. Ordinary globals, function access to those globals, andsys.exit()behavior are covered by regression tests. Actual indentation errors still fail; their diagnostics now point at the original user line.Changes are limited to the TypeScript worker source, regression tests, and a changeset. No compiled JavaScript is committed.
Verify
# Rebuild the worker whenever its TypeScript changes. pnpm --filter just-bash build pnpm --filter just-bash test:wasm src/commands/python3/python3.source-preservation.test.ts pnpm test:wasm-c, and files. 21 fail on unmodified upstream.test:run: 15,610 passed, 98 skipped; the same six existing filesystem tests fail as on unmodified upstream in this macOS environment. They concern symlinks/special mode bits and do not exercise Python.