Skip to content

Commit 4cbc5f5

Browse files
committed
Pass exit status (i.e. arguments passed to SystemExit) to shell. Fixes bpython#227.
1 parent 06628e1 commit 4cbc5f5

File tree

4 files changed

+39
-15
lines changed

4 files changed

+39
-15
lines changed

bpython/cli.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ def __init__(self, scr, interp, statusbar, config, idle=None):
321321
self.list_win = newwin(get_colpair(config, 'background'), 1, 1, 1, 1)
322322
self.cpos = 0
323323
self.do_exit = False
324+
self.exit_value = None
324325
self.f_string = ''
325326
self.idle = idle
326327
self.in_hist = False
@@ -1066,9 +1067,10 @@ def push(self, s, insert_into_history=True):
10661067
curses.raw(False)
10671068
try:
10681069
return repl.Repl.push(self, s, insert_into_history)
1069-
except SystemExit:
1070+
except SystemExit, e:
10701071
# Avoid a traceback on e.g. quit()
10711072
self.do_exit = True
1073+
self.exit_value = e.args
10721074
return False
10731075
finally:
10741076
curses.raw(True)
@@ -1131,6 +1133,7 @@ def repl(self):
11311133
if not more:
11321134
self.prev_block_finished = stdout_position
11331135
self.s = ''
1136+
return self.exit_value
11341137

11351138
def reprint_line(self, lineno, tokens):
11361139
"""Helper function for paren highlighting: Reprint line at offset
@@ -1821,6 +1824,9 @@ def main_curses(scr, args, config, interactive=True, locals_=None,
18211824
I've tried to keep it well factored but it needs some
18221825
tidying up, especially in separating the curses stuff
18231826
from the rest of the repl.
1827+
1828+
Returns a tuple (exit value, output), where exit value is a tuple
1829+
with arguments passed to SystemExit.
18241830
"""
18251831
global stdscr
18261832
global DO_RESIZE
@@ -1873,7 +1879,7 @@ def main_curses(scr, args, config, interactive=True, locals_=None,
18731879
if banner is not None:
18741880
clirepl.write(banner)
18751881
clirepl.write('\n')
1876-
clirepl.repl()
1882+
exit_value = clirepl.repl()
18771883

18781884
main_win.erase()
18791885
main_win.refresh()
@@ -1886,7 +1892,7 @@ def main_curses(scr, args, config, interactive=True, locals_=None,
18861892
signal.signal(signal.SIGWINCH, old_sigwinch_handler)
18871893
signal.signal(signal.SIGCONT, old_sigcont_handler)
18881894

1889-
return clirepl.getstdout()
1895+
return (exit_value, clirepl.getstdout())
18901896

18911897

18921898
def main(args=None, locals_=None, banner=None):
@@ -1901,23 +1907,23 @@ def main(args=None, locals_=None, banner=None):
19011907
orig_stderr = sys.stderr
19021908

19031909
try:
1904-
o = curses_wrapper(main_curses, exec_args, config,
1905-
options.interactive, locals_,
1906-
banner=banner)
1910+
(exit_value, output) = curses_wrapper(
1911+
main_curses, exec_args, config, options.interactive, locals_,
1912+
banner=banner)
19071913
finally:
19081914
sys.stdin = orig_stdin
19091915
sys.stderr = orig_stderr
19101916
sys.stdout = orig_stdout
19111917

19121918
# Fake stdout data so everything's still visible after exiting
19131919
if config.flush_output and not options.quiet:
1914-
sys.stdout.write(o)
1920+
sys.stdout.write(output)
19151921
if hasattr(sys.stdout, 'flush'):
19161922
sys.stdout.flush()
1917-
1923+
return repl.extract_exit_value(exit_value)
19181924

19191925
if __name__ == '__main__':
19201926
from bpython.cli import main
1921-
main()
1927+
sys.exit(main())
19221928

19231929
# vim: sw=4 ts=4 sts=4 ai et

bpython/gtk_.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ def __init__(self, interpreter, config):
336336
gtk.TextView.__init__(self)
337337
repl.Repl.__init__(self, interpreter, config)
338338
self.interp.writetb = self.writetb
339+
self.exit_value = None
339340
self.editing = Nested()
340341
self.reset_indent = False
341342
self.modify_font(pango.FontDescription(self.config.gtk_font))
@@ -694,7 +695,8 @@ def push_line(self):
694695
self.highlight_current_line()
695696
try:
696697
return self.push(line + '\n')
697-
except SystemExit:
698+
except SystemExit, e:
699+
self.exit_value = e.args
698700
self.emit('exit-event')
699701
return False
700702

@@ -857,8 +859,8 @@ def main(args=None):
857859
except KeyboardInterrupt:
858860
pass
859861

860-
return 0
862+
return repl.extract_exit_value(repl_widget.exit_value)
861863

862864
if __name__ == '__main__':
863865
from bpython.gtk_ import main
864-
main()
866+
sys.exit(main())

bpython/repl.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,3 +1027,14 @@ def token_is_any_of(token):
10271027
return any(check(token) for check in is_token_types)
10281028

10291029
return token_is_any_of
1030+
1031+
def extract_exit_value(args):
1032+
"""Given the arguments passed to `SystemExit`, return the value that
1033+
should be passed to `sys.exit`.
1034+
"""
1035+
if len(args) == 0:
1036+
return None
1037+
elif len(args) == 1:
1038+
return args[0]
1039+
else:
1040+
return args

bpython/urwid.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,8 @@ def __init__(self, event_loop, palette, interpreter, config):
621621
self.current_output = None
622622
self._completion_update_suppressed = False
623623

624+
self.exit_value = None
625+
624626
load_urwid_command_map(config)
625627

626628
# Subclasses of Repl need to implement echo, current_line, cw
@@ -913,7 +915,8 @@ def push(self, s, insert_into_history=True):
913915
# Pretty blindly adapted from bpython.cli
914916
try:
915917
return repl.Repl.push(self, s, insert_into_history)
916-
except SystemExit:
918+
except SystemExit, e:
919+
self.exit_value = e.args
917920
raise urwid.ExitMainLoop()
918921
except KeyboardInterrupt:
919922
# KeyboardInterrupt happened between the except block around
@@ -1296,7 +1299,9 @@ def run_find_coroutine():
12961299

12971300
if config.flush_output and not options.quiet:
12981301
sys.stdout.write(myrepl.getstdout())
1299-
sys.stdout.flush()
1302+
if hasattr(sys.stdout, "flush"):
1303+
sys.stdout.flush()
1304+
return repl.extract_exit_value(myrepl.exit_value)
13001305

13011306
def load_urwid_command_map(config):
13021307
urwid.command_map[key_dispatch[config.up_one_line_key]] = 'cursor up'
@@ -1325,4 +1330,4 @@ def load_urwid_command_map(config):
13251330
'yank_from_buffer': 'C-y'},
13261331
"""
13271332
if __name__ == '__main__':
1328-
main()
1333+
sys.exit(main())

0 commit comments

Comments
 (0)