From e7dcdff81dcefb0a9a0096c4a2cc857d67697f2e Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 30 Jun 2025 00:57:55 +0900 Subject: [PATCH 1/2] all: handle SystemExit --- main.go | 30 ++++++++++++++++++++++++++++++ repl/repl.go | 31 +++++++++++++++++++++++++++++++ stdlib/sys/sys.go | 6 +++++- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 8be7ea2e..99580354 100644 --- a/main.go +++ b/main.go @@ -74,6 +74,36 @@ func xmain(args []string) { } else { _, err := py.RunFile(ctx, args[0], py.CompileOpts{}, nil) if err != nil { + if py.IsException(py.SystemExit, err) { + args := err.(py.ExceptionInfo).Value.(*py.Exception).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 { + msg, err := py.ReprAsString(args) + if err != nil { + fmt.Fprintln(os.Stderr, err) + } else { + fmt.Fprintln(os.Stderr, msg) + } + os.Exit(1) + } + } py.TracebackDump(err) os.Exit(1) } diff --git a/repl/repl.go b/repl/repl.go index f6639b25..faf9859d 100644 --- a/repl/repl.go +++ b/repl/repl.go @@ -7,6 +7,7 @@ package repl import ( "fmt" + "os" "sort" "strings" @@ -109,6 +110,36 @@ func (r *REPL) Run(line string) { } _, err = r.Context.RunCode(code, r.Module.Globals, r.Module.Globals, nil) if err != nil { + if py.IsException(py.SystemExit, err) { + args := err.(py.ExceptionInfo).Value.(*py.Exception).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 { + msg, err := py.ReprAsString(args) + if err != nil { + fmt.Fprintln(os.Stderr, err) + } else { + fmt.Fprintln(os.Stderr, msg) + } + os.Exit(1) + } + } py.TracebackDump(err) } } 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 From ecdd85c5c8a70e999fbfce4eab385c4d603c6ab3 Mon Sep 17 00:00:00 2001 From: AN Long Date: Thu, 3 Jul 2025 21:52:48 +0900 Subject: [PATCH 2/2] Reduce code duplication --- main.go | 72 ++++++++++++++++++++++++++----------------------- repl/cli/cli.go | 8 ++++-- repl/repl.go | 41 +++++----------------------- 3 files changed, 51 insertions(+), 70 deletions(-) diff --git a/main.go b/main.go index 99580354..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,43 +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 { - if py.IsException(py.SystemExit, err) { - args := err.(py.ExceptionInfo).Value.(*py.Exception).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 { - msg, err := py.ReprAsString(args) - if err != nil { - fmt.Fprintln(os.Stderr, err) - } else { - fmt.Fprintln(os.Stderr, msg) - } - os.Exit(1) - } - } - 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 faf9859d..3938a7b6 100644 --- a/repl/repl.go +++ b/repl/repl.go @@ -7,7 +7,6 @@ package repl import ( "fmt" - "os" "sort" "strings" @@ -67,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 @@ -77,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 { @@ -98,7 +97,7 @@ func (r *REPL) Run(line string) { r.previous += string(line) + "\n" r.term.SetPrompt(ContinuationPrompt) } - return + return nil } } r.continuation = false @@ -106,42 +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) { - args := err.(py.ExceptionInfo).Value.(*py.Exception).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 { - msg, err := py.ReprAsString(args) - if err != nil { - fmt.Fprintln(os.Stderr, err) - } else { - fmt.Fprintln(os.Stderr, msg) - } - os.Exit(1) - } + return err } py.TracebackDump(err) } + return nil } // WordCompleter takes the currently edited line with the cursor pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy