Skip to content

Commit 8b4dffb

Browse files
authored
all: handle SystemExit
1 parent 285aad1 commit 8b4dffb

File tree

4 files changed

+58
-12
lines changed

4 files changed

+58
-12
lines changed

main.go

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func xmain(args []string) {
6060
defer pprof.StopCPUProfile()
6161
}
6262

63+
var err error
6364
// IF no args, enter REPL mode
6465
if len(args) == 0 {
6566

@@ -69,13 +70,46 @@ func xmain(args []string) {
6970
fmt.Printf("- go version: %s\n", runtime.Version())
7071

7172
replCtx := repl.New(ctx)
72-
cli.RunREPL(replCtx)
73+
err = cli.RunREPL(replCtx)
74+
} else {
75+
_, err = py.RunFile(ctx, args[0], py.CompileOpts{}, nil)
76+
}
77+
if err != nil {
78+
if py.IsException(py.SystemExit, err) {
79+
handleSystemExit(err.(py.ExceptionInfo).Value.(*py.Exception))
80+
}
81+
py.TracebackDump(err)
82+
os.Exit(1)
83+
}
84+
}
7385

86+
func handleSystemExit(exc *py.Exception) {
87+
args := exc.Args.(py.Tuple)
88+
if len(args) == 0 {
89+
os.Exit(0)
90+
} else if len(args) == 1 {
91+
if code, ok := args[0].(py.Int); ok {
92+
c, err := code.GoInt()
93+
if err != nil {
94+
fmt.Fprintln(os.Stderr, err)
95+
os.Exit(1)
96+
}
97+
os.Exit(c)
98+
}
99+
msg, err := py.ReprAsString(args[0])
100+
if err != nil {
101+
fmt.Fprintln(os.Stderr, err)
102+
} else {
103+
fmt.Fprintln(os.Stderr, msg)
104+
}
105+
os.Exit(1)
74106
} else {
75-
_, err := py.RunFile(ctx, args[0], py.CompileOpts{}, nil)
107+
msg, err := py.ReprAsString(args)
76108
if err != nil {
77-
py.TracebackDump(err)
78-
os.Exit(1)
109+
fmt.Fprintln(os.Stderr, err)
110+
} else {
111+
fmt.Fprintln(os.Stderr, msg)
79112
}
113+
os.Exit(1)
80114
}
81115
}

repl/cli/cli.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ func (rl *readline) Print(out string) {
117117
}
118118

119119
// RunREPL starts the REPL loop
120-
func RunREPL(replCtx *repl.REPL) {
120+
func RunREPL(replCtx *repl.REPL) error {
121121
if replCtx == nil {
122122
replCtx = repl.New(nil)
123123
}
@@ -144,6 +144,10 @@ func RunREPL(replCtx *repl.REPL) {
144144
if line != "" {
145145
rl.AppendHistory(line)
146146
}
147-
rl.repl.Run(line)
147+
err = rl.repl.Run(line)
148+
if err != nil {
149+
return err
150+
}
148151
}
152+
return nil
149153
}

repl/repl.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func (r *REPL) SetUI(term UI) {
6666
}
6767

6868
// Run runs a single line of the REPL
69-
func (r *REPL) Run(line string) {
69+
func (r *REPL) Run(line string) error {
7070
// Override the PrintExpr output temporarily
7171
oldPrintExpr := vm.PrintExpr
7272
vm.PrintExpr = r.term.Print
@@ -76,13 +76,13 @@ func (r *REPL) Run(line string) {
7676
if r.continuation {
7777
if line != "" {
7878
r.previous += string(line) + "\n"
79-
return
79+
return nil
8080
}
8181
}
8282
// need +"\n" because "single" expects \n terminated input
8383
toCompile := r.previous + string(line)
8484
if toCompile == "" {
85-
return
85+
return nil
8686
}
8787
code, err := py.Compile(toCompile+"\n", r.prog, py.SingleMode, 0, true)
8888
if err != nil {
@@ -97,20 +97,24 @@ func (r *REPL) Run(line string) {
9797
r.previous += string(line) + "\n"
9898
r.term.SetPrompt(ContinuationPrompt)
9999
}
100-
return
100+
return nil
101101
}
102102
}
103103
r.continuation = false
104104
r.term.SetPrompt(NormalPrompt)
105105
r.previous = ""
106106
if err != nil {
107107
r.term.Print(fmt.Sprintf("Compile error: %v", err))
108-
return
108+
return nil
109109
}
110110
_, err = r.Context.RunCode(code, r.Module.Globals, r.Module.Globals, nil)
111111
if err != nil {
112+
if py.IsException(py.SystemExit, err) {
113+
return err
114+
}
112115
py.TracebackDump(err)
113116
}
117+
return nil
114118
}
115119

116120
// WordCompleter takes the currently edited line with the cursor

stdlib/sys/sys.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ func sys_exit(self py.Object, args py.Tuple) (py.Object, error) {
133133
return nil, err
134134
}
135135
// Raise SystemExit so callers may catch it or clean up.
136-
return py.ExceptionNew(py.SystemExit, args, nil)
136+
exc, err := py.ExceptionNew(py.SystemExit, args, nil)
137+
if err != nil {
138+
return nil, err
139+
}
140+
return nil, exc.(*py.Exception)
137141
}
138142

139143
const getdefaultencoding_doc = `getdefaultencoding() -> string

0 commit comments

Comments
 (0)