4747import unicodedata
4848import textwrap
4949from cStringIO import StringIO
50+ from itertools import takewhile
5051from locale import LC_ALL , getpreferredencoding , setlocale
5152from optparse import OptionParser
5253from urlparse import urljoin
@@ -1939,7 +1940,7 @@ def newwin(*args):
19391940 return win
19401941
19411942
1942- def main_curses (scr ):
1943+ def main_curses (scr , args , interactive = True ):
19431944 """main function for the curses convenience wrapper
19441945
19451946 Initialise the two main objects: the interpreter
@@ -1984,6 +1985,14 @@ def main_curses(scr):
19841985 sys .stdout = repl
19851986 sys .stderr = repl
19861987
1988+ if args :
1989+ with open (args [0 ], 'r' ) as sourcefile :
1990+ code_obj = compile (sourcefile .read (), args [0 ], 'exec' )
1991+ old_argv , sys .argv = sys .argv , args
1992+ interpreter .runcode (code_obj )
1993+ sys .argv = old_argv
1994+ if not interactive :
1995+ return repl .getstdout ()
19871996
19881997 repl .repl ()
19891998 if OPTS .hist_length :
@@ -1997,15 +2006,30 @@ def main_curses(scr):
19972006
19982007def main (args = None ):
19992008 if args is None :
2000- args = sys .argv
2009+ args = sys .argv [ 1 :]
20012010
2002- parser = OptionParser ()
2011+ parser = OptionParser (usage = 'Usage: %prog [options] [file [args]]\n '
2012+ 'NOTE: If bpython sees an argument it does '
2013+ 'not know, execution falls back to the '
2014+ 'regular Python interpreter.' )
20032015 parser .add_option ('--config' , '-c' , default = '~/.bpython.ini' ,
20042016 help = 'use CONFIG instead of default config file' )
2017+ parser .add_option ('--interactive' , '-i' , action = 'store_true' ,
2018+ help = 'Drop to bpython shell after running file '
2019+ 'instead of exiting' )
20052020 parser .add_option ('--version' , '-V' , action = 'store_true' ,
20062021 help = 'print version and exit' )
20072022
2008- options , args = parser .parse_args (args )
2023+ all_args = set (parser ._short_opt .keys () + parser ._long_opt .keys ())
2024+ if args and not all_args .intersection (args ):
2025+ # Just let Python handle this
2026+ os .execv (sys .executable , [sys .executable ] + args )
2027+ else :
2028+ # Split args in bpython args and args for the executed file
2029+ real_args = list (takewhile (lambda arg : arg in all_args , args ))
2030+ exec_args = args [len (real_args ):]
2031+
2032+ options , args = parser .parse_args (real_args )
20092033
20102034 if options .version :
20112035 print 'bpython version' , __version__ ,
@@ -2028,7 +2052,7 @@ def main(args=None):
20282052 loadini (OPTS , options .config )
20292053
20302054 try :
2031- o = curses .wrapper (main_curses )
2055+ o = curses .wrapper (main_curses , exec_args , options . interactive )
20322056 except :
20332057 tb = traceback .format_exc ()
20342058# I don't know why this is necessary; without it the wrapper doesn't always do
0 commit comments