Skip to main content

1624. gopy pythonrun

What we are porting

Python/pythonrun.c (~1.7k lines). Three concerns:

  1. String / file evaluation. PyRun_SimpleString, PyRun_AnyFile, PyRun_FileEx, PyRun_String. The plumbing that takes a chunk of source, calls the parser, compiles, and runs through the VM.
  2. Interactive REPL. PyRun_InteractiveLoop and friends. Reads a line, parses, compiles, runs, prints. Until EOF.
  3. .pyc read/write helpers. _PyRun_PycFile and the marshal-magic check. (The marshal port itself lives in 1623; this spec uses it.)

pythonrun.c is the consumer layer that sits on top of parser + compile + vm. It does not own any state; it threads the right *state.Thread through to each subsystem.

Why this lands in v0.7 alongside lifecycle

lifecycle.Main (spec 1622) needs a target to dispatch to:

  • gopy script.py => pythonrun.RunFile.
  • gopy -c "..." => pythonrun.RunString.
  • gopy (no args) => pythonrun.InteractiveLoop.
  • gopy -m foo => deferred to v0.8 (import-driven).

In v0.6 cmd/gopy hand-rolled RunString inline. v0.7 moves that to pythonrun.RunString and adds the file and REPL arms.

Package layout

gopy/pythonrun/
runstring.go # PyRun_SimpleString and PyRun_String
runfile.go # PyRun_AnyFile and PyRun_FileEx
repl.go # PyRun_InteractiveLoop, the prompt loop
pyc.go # _PyRun_PycFile (marshal magic check)
exceptions.go # _PyErr_Print and the SystemExit / KeyboardInterrupt
# hooks pythonrun owns

v0.7 release blockers

  • 1624-A Port PyRun_SimpleStringFlags. Drives the v0.6 gopy -c smoke; same fixture must keep passing once the call site moves into pythonrun. CPython: Python/pythonrun.c:432 PyRun_SimpleStringFlags.
  • 1624-B Port PyRun_AnyFileExFlags plus the closeit-on-EOF semantics. CPython: Python/pythonrun.c:88 PyRun_AnyFileExFlags.
  • 1624-C Port PyRun_InteractiveLoopFlags for the basic REPL. v0.7 uses bufio.Scanner from stdin; readline editing is deferred to v0.9 (spec 1645). CPython: Python/pythonrun.c:128 PyRun_InteractiveLoopFlags.
  • 1624-D Port _PyErr_Print so unhandled exceptions print the traceback CPython would. CPython: Python/pythonrun.c:797 _PyErr_PrintEx.
  • 1624-E pythonrun_test.go panel: 12 fixtures driven through RunString, plus TestREPL exercising a pipe-based stdin against canned input.

Test gates

  • pythonrun/runstring_test.go: the v0.6 cpython_smoke panel re-rooted onto pythonrun.RunString. Same 13 cases must still match python3 stdout.
  • pythonrun/repl_test.go: feed "1+2\nprint('done')\n" through stdin, assert stdout is "3\ndone\n".
  • pythonrun/runfile_test.go: write a temp .py file with one expression, assert RunFile evaluates it and prints the result.

Out of scope

  • .pyc execution (_PyRun_PycFile) is wired but stubbed in v0.7; the marshal arm lands in v0.8.
  • PEP 657 traceback positions need the full source-position walker; v0.7 ships file:line:col only, no caret pinning.