@@ -78,7 +78,6 @@ def log(x):
7878 f.write('%s\n' % (x,))
7979
8080py3 = sys.version_info[0] == 3
81- orig_stdout = sys.__stdout__
8281stdscr = None
8382
8483
@@ -2097,7 +2096,7 @@ def gethw():
20972096
20982097 """
20992098 h, w = struct.unpack(
2100- "hhhh", fcntl.ioctl(orig_stdout , termios.TIOCGWINSZ, "\000"*8))[0:2]
2099+ "hhhh", fcntl.ioctl(sys.__stdout__ , termios.TIOCGWINSZ, "\000"*8))[0:2]
21012100 return h, w
21022101
21032102
@@ -2156,7 +2155,30 @@ def newwin(*args):
21562155 return win
21572156
21582157
2159- def main_curses(scr, args, interactive=True):
2158+ def curses_wrapper(func, *args, **kwargs):
2159+ """Like curses.wrapper(), but reuses stdscr when called again."""
2160+ global stdscr
2161+ if stdscr is None:
2162+ stdscr = curses.initscr()
2163+ try:
2164+ curses.noecho()
2165+ curses.cbreak()
2166+ stdscr.keypad(1)
2167+
2168+ try:
2169+ curses.start_color()
2170+ except curses.error:
2171+ pass
2172+
2173+ return func(stdscr, *args, **kwargs)
2174+ finally:
2175+ stdscr.keypad(0)
2176+ curses.echo()
2177+ curses.nocbreak()
2178+ curses.endwin()
2179+
2180+
2181+ def main_curses(scr, args, interactive=True, locals_=None):
21602182 """main function for the curses convenience wrapper
21612183
21622184 Initialise the two main objects: the interpreter
@@ -2189,10 +2211,9 @@ def main_curses(scr, args, interactive=True):
21892211 curses.raw(True)
21902212 main_win, statusbar = init_wins(scr, cols)
21912213
2192- curses.raw(True)
2193-
2194- interpreter = Interpreter(dict(__name__='__main__', __doc__=None),
2195- getpreferredencoding())
2214+ if locals_ is None:
2215+ locals_ = dict(__name__='__main__', __doc__=None)
2216+ interpreter = Interpreter(locals_, getpreferredencoding())
21962217
21972218 repl = Repl(main_win, interpreter, statusbar, idle)
21982219 interpreter.syntaxerror_callback = repl.clear_current_line
@@ -2209,6 +2230,7 @@ def main_curses(scr, args, interactive=True):
22092230 interpreter.runcode(code_obj)
22102231 sys.argv = old_argv
22112232 if not interactive:
2233+ curses.raw(False)
22122234 return repl.getstdout()
22132235
22142236 repl.repl()
@@ -2222,10 +2244,13 @@ def main_curses(scr, args, interactive=True):
22222244 main_win.refresh()
22232245 statusbar.win.clear()
22242246 statusbar.win.refresh()
2247+ curses.raw(False)
22252248 return repl.getstdout()
22262249
22272250
2228- def main(args=None):
2251+ def main(args=None, locals_=None):
2252+ global stdscr
2253+
22292254 if args is None:
22302255 args = sys.argv[1:]
22312256
@@ -2238,6 +2263,8 @@ def main(args=None):
22382263 parser.add_option('--interactive', '-i', action='store_true',
22392264 help='Drop to bpython shell after running file '
22402265 'instead of exiting')
2266+ parser.add_option('--quiet', '-q', action='store_true',
2267+ help="Don't flush the output to stdout.")
22412268 parser.add_option('--version', '-V', action='store_true',
22422269 help='print version and exit')
22432270
@@ -2265,33 +2292,26 @@ def main(args=None):
22652292
22662293 setlocale(LC_ALL, '')
22672294
2268- tb = None
2269-
22702295 path = os.path.expanduser('~/.bpythonrc') # migrating old configuration file
22712296 if os.path.isfile(path):
22722297 migrate_rc(path)
22732298 loadini(OPTS, options.config)
22742299
2300+ # Save stdin, stdout and stderr for later restoration
2301+ orig_stdin = sys.stdin
2302+ orig_stdout = sys.stdout
2303+ orig_stderr = sys.stderr
2304+
22752305 try:
2276- o = curses.wrapper(main_curses, exec_args, options.interactive)
2277- except:
2278- tb = traceback.format_exc()
2279- # I don't know why this is necessary; without it the wrapper doesn't always do
2280- # its job.
2281- if stdscr is not None:
2282- stdscr.clear()
2283- stdscr.keypad(0)
2284- curses.echo()
2285- curses.nocbreak()
2286- curses.endwin()
2287-
2288- sys.stdout = orig_stdout
2289- if tb:
2290- print tb
2291- sys.exit(1)
2306+ o = curses_wrapper(main_curses, exec_args, options.interactive,
2307+ locals_)
2308+ finally:
2309+ sys.stdin = orig_stdin
2310+ sys.stderr = orig_stderr
2311+ sys.stdout = orig_stdout
22922312
22932313# Fake stdout data so everything's still visible after exiting
2294- if OPTS.flush_output:
2314+ if OPTS.flush_output and not options.quiet :
22952315 sys.stdout.write(o)
22962316 sys.stdout.flush()
22972317
0 commit comments