REPL
Running gopy with no script drops into the interactive prompt.
The banner matches CPython's:
gopy 0.12.0 (3.14.0+) [go1.26 darwin/arm64]
Type "help", "copyright", "credits" or "license" for more information.
>>>
Behaviour
Each line is parsed in mode="single". Expression statements print
their value via sys.displayhook, so
>>> 2 + 2
4
is real output, not a print call.
A blank line ends a multi-line block. The classic continuation
prompt is ... :
>>> def double(x):
... return x * 2
...
>>> double(21)
42
History
gopy uses myreadline/ for line editing. The history file path is
the same one CPython uses: $XDG_STATE_HOME/python_history, falling
back to ~/.python_history.
Hooks
The REPL respects sys.displayhook, sys.excepthook, and
sys.__interactivehook__. Replacing displayhook is the canonical
way to customise how repr-style output is rendered.
>>> import sys
>>> def loud(value):
... if value is None: return
... print(f"=> {value!r}")
>>> sys.displayhook = loud
>>> 1 + 1
=> 2
Soft and hard exits
Ctrl-D on an empty line exits cleanly. Ctrl-C raises
KeyboardInterrupt at the current prompt and clears the
in-progress buffer. exit() and quit() are real functions that
raise SystemExit.
Line editing
gopy's line editor is myreadline/. By default it runs the bare
StdioReadline mode: prompt is drawn, input is read to newline.
There is no in-place editing, no history navigation, and no tab
completion in that mode.
To get a full-featured terminal experience today, pipe through
rlwrap:
rlwrap gopy
A future build tag will link in peterh/liner or GNU readline.
Plugging in a custom reader
A Go host that embeds the REPL can supply its own line reader
via myreadline.SetReader. The function receives stdin / stdout
plus the prompt and returns the user's line.
import "github.com/tamnd/gopy/myreadline"
myreadline.SetReader(func(stdin io.Reader, stdout io.Writer, prompt string) (string, error) {
// Run your own line editor here.
})
This is what an embedder would use to integrate a TUI library or a network shell.
Quirks worth knowing
- Multi-line input ends on a blank line, not on dedent. Pasting
blocks copied with the leading prompt characters (
>>>,...) does not work yet; strip them first. - The displayhook only fires in
mode="single". Inside adefbody, expression statements at the inner level are evaluated but their values are not printed. _holds the value of the last expression printed at the prompt. Re-binding_(a common idiom in i18n code) breaks this; the REPL never restores the binding.