diff --git a/main.go b/main.go index 8be7ea2e..8b55ab1e 100644 --- a/main.go +++ b/main.go @@ -60,6 +60,7 @@ func xmain(args []string) { defer pprof.StopCPUProfile() } + var err error // IF no args, enter REPL mode if len(args) == 0 { @@ -69,13 +70,46 @@ func xmain(args []string) { fmt.Printf("- go version: %s\n", runtime.Version()) replCtx := repl.New(ctx) - cli.RunREPL(replCtx) + err = cli.RunREPL(replCtx) + } else { + _, err = py.RunFile(ctx, args[0], py.CompileOpts{}, nil) + } + if err != nil { + if py.IsException(py.SystemExit, err) { + handleSystemExit(err.(py.ExceptionInfo).Value.(*py.Exception)) + } + py.TracebackDump(err) + os.Exit(1) + } +} +func handleSystemExit(exc *py.Exception) { + args := exc.Args.(py.Tuple) + if len(args) == 0 { + os.Exit(0) + } else if len(args) == 1 { + if code, ok := args[0].(py.Int); ok { + c, err := code.GoInt() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + os.Exit(c) + } + msg, err := py.ReprAsString(args[0]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + } else { + fmt.Fprintln(os.Stderr, msg) + } + os.Exit(1) } else { - _, err := py.RunFile(ctx, args[0], py.CompileOpts{}, nil) + msg, err := py.ReprAsString(args) if err != nil { - py.TracebackDump(err) - os.Exit(1) + fmt.Fprintln(os.Stderr, err) + } else { + fmt.Fprintln(os.Stderr, msg) } + os.Exit(1) } } diff --git a/repl/cli/cli.go b/repl/cli/cli.go index 6648094a..6f7e3966 100644 --- a/repl/cli/cli.go +++ b/repl/cli/cli.go @@ -117,7 +117,7 @@ func (rl *readline) Print(out string) { } // RunREPL starts the REPL loop -func RunREPL(replCtx *repl.REPL) { +func RunREPL(replCtx *repl.REPL) error { if replCtx == nil { replCtx = repl.New(nil) } @@ -144,6 +144,10 @@ func RunREPL(replCtx *repl.REPL) { if line != "" { rl.AppendHistory(line) } - rl.repl.Run(line) + err = rl.repl.Run(line) + if err != nil { + return err + } } + return nil } diff --git a/repl/repl.go b/repl/repl.go index f6639b25..3938a7b6 100644 --- a/repl/repl.go +++ b/repl/repl.go @@ -66,7 +66,7 @@ func (r *REPL) SetUI(term UI) { } // Run runs a single line of the REPL -func (r *REPL) Run(line string) { +func (r *REPL) Run(line string) error { // Override the PrintExpr output temporarily oldPrintExpr := vm.PrintExpr vm.PrintExpr = r.term.Print @@ -76,13 +76,13 @@ func (r *REPL) Run(line string) { if r.continuation { if line != "" { r.previous += string(line) + "\n" - return + return nil } } // need +"\n" because "single" expects \n terminated input toCompile := r.previous + string(line) if toCompile == "" { - return + return nil } code, err := py.Compile(toCompile+"\n", r.prog, py.SingleMode, 0, true) if err != nil { @@ -97,7 +97,7 @@ func (r *REPL) Run(line string) { r.previous += string(line) + "\n" r.term.SetPrompt(ContinuationPrompt) } - return + return nil } } r.continuation = false @@ -105,12 +105,16 @@ func (r *REPL) Run(line string) { r.previous = "" if err != nil { r.term.Print(fmt.Sprintf("Compile error: %v", err)) - return + return nil } _, err = r.Context.RunCode(code, r.Module.Globals, r.Module.Globals, nil) if err != nil { + if py.IsException(py.SystemExit, err) { + return err + } py.TracebackDump(err) } + return nil } // WordCompleter takes the currently edited line with the cursor diff --git a/stdlib/sys/sys.go b/stdlib/sys/sys.go index 3a2318eb..fc6efc5a 100644 --- a/stdlib/sys/sys.go +++ b/stdlib/sys/sys.go @@ -133,7 +133,11 @@ func sys_exit(self py.Object, args py.Tuple) (py.Object, error) { return nil, err } // Raise SystemExit so callers may catch it or clean up. - return py.ExceptionNew(py.SystemExit, args, nil) + exc, err := py.ExceptionNew(py.SystemExit, args, nil) + if err != nil { + return nil, err + } + return nil, exc.(*py.Exception) } const getdefaultencoding_doc = `getdefaultencoding() -> string
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: