#! /usr/bin/env python# App-level version of py.py.# See test/test_app_main."""options: -i inspect interactively after running script -O dummy optimization flag for compatibility with C Python -c cmd program passed in as CMD (terminates option list) -S do not 'import site' on initialization -u unbuffered binary stdout and stderr -h, --help show this help message and exit -m mod library module to be run as a script (terminates option list) -W arg warning control (arg is action:message:category:module:lineno) -E ignore environment variables (such as PYTHONPATH) -R ignored (see http://bugs.python.org/issue14621) --version print the PyPy version --info print translation information about this PyPy executable"""importsysDEBUG=False# dump exceptions before calling the except hookoriginalexcepthook=sys.__excepthook__defhandle_sys_exit(e):# exit if we catch a w_SystemExitexitcode=e.codeifexitcodeisNone:exitcode=0else:try:exitcode=int(exitcode)except:# not an integer: print it to stderrtry:print>>sys.stderr,exitcodeexcept:pass# too badexitcode=1raiseSystemExit(exitcode)defrun_toplevel(f,*fargs,**fkwds):"""Calls f() and handles all OperationErrors. Intended use is to run the main program or one interactive statement. run_protected() handles details like forwarding exceptions to sys.excepthook(), catching SystemExit, printing a newline after sys.stdout if needed, etc. """try:# run itf(*fargs,**fkwds)# we arrive here if no exception is raised. stdout cosmetics...try:stdout=sys.stdoutsoftspace=stdout.softspaceexceptAttributeError:pass# Don't crash if user defined stdout doesn't have softspaceelse:ifsoftspace:stdout.write('\n')exceptSystemExit,e:handle_sys_exit(e)except:display_exception()returnFalsereturnTrue# successdefdisplay_exception():etype,evalue,etraceback=sys.exc_info()try:# extra debugging info in case the code below goes very wrongifDEBUGandhasattr(sys,'stderr'):s=getattr(etype,'__name__',repr(etype))print>>sys.stderr,"debug: exception-type: ",sprint>>sys.stderr,"debug: exception-value:",str(evalue)tbentry=etracebackiftbentry:whiletbentry.tb_next:tbentry=tbentry.tb_nextlineno=tbentry.tb_linenofilename=tbentry.tb_frame.f_code.co_filenameprint>>sys.stderr,"debug: exception-tb: %s:%d"%(filename,lineno)# set the sys.last_xxx attributessys.last_type=etypesys.last_value=evaluesys.last_traceback=etraceback# call sys.excepthookhook=getattr(sys,'excepthook',originalexcepthook)hook(etype,evalue,etraceback)return# doneexcept:try:stderr=sys.stderrexceptAttributeError:pass# too badelse:print>>stderr,'Error calling sys.excepthook:'originalexcepthook(*sys.exc_info())print>>stderrprint>>stderr,'Original exception was:'# we only get here if sys.excepthook didn't do its joboriginalexcepthook(etype,evalue,etraceback)# ____________________________________________________________# Option parsingdefprint_info(*args):try:options=sys.pypy_translation_infoexceptAttributeError:print>>sys.stderr,'no translation information found'else:optitems=options.items()optitems.sort()current=[]forkey,valueinoptitems:group=key.split('.')name=group.pop()n=0whilen<min(len(current),len(group))andcurrent[n]==group[n]:n+=1whilen<len(group):print'%s[%s]'%(' '*n,group[n])n+=1print'%s%s = %r'%(' '*n,name,value)current=groupraiseSystemExitdefprint_help(*args):print'usage: %s [options] [-c cmd|-m mod|file.py|-] [arg...]'%(sys.executable,)print__doc__.rstrip()if'pypyjit'insys.builtin_module_names:print" --jit OPTIONS advanced JIT options: try 'off' or 'help'"printraiseSystemExitdef_print_jit_help():try:importpypyjitexceptImportError:print>>sys.stderr,"No jit support in %s"%(sys.executable,)returnitems=pypyjit.defaults.items()items.sort()print'Advanced JIT options: a comma-separated list of OPTION=VALUE:'forkey,valueinitems:printprint' %s=N'%(key,)doc='%s (default %s)'%(pypyjit.PARAMETER_DOCS[key],value)whilelen(doc)>72:i=doc[:74].rfind(' ')ifi<0:i=doc.find(' ')ifi<0:i=len(doc)print' '+doc[:i]doc=doc[i+1:]print' '+docprintprint' off'print' turn off the JIT'print' help'print' print this page'defprint_version(*args):print>>sys.stderr,"Python",sys.versionraiseSystemExitdefset_jit_option(options,jitparam,*args):ifjitparam=='help':_print_jit_help()raiseSystemExitif'pypyjit'notinsys.builtin_module_names:print>>sys.stderr,("Warning: No jit support in %s"%(sys.executable,))else:importpypyjitpypyjit.set_param(jitparam)classCommandLineError(Exception):passdefprint_error(msg):print>>sys.stderr,msgprint>>sys.stderr,'usage: %s [options]'%(sys.executable,)print>>sys.stderr,'Try `%s -h` for more information.'%(sys.executable,)deffdopen(fd,mode,bufsize=-1):try:fdopen=file.fdopenexceptAttributeError:# only on top of CPython, running testsfromosimportfdopenreturnfdopen(fd,mode,bufsize)defset_unbuffered_io():sys.stdin=sys.__stdin__=fdopen(0,'rb',0)sys.stdout=sys.__stdout__=fdopen(1,'wb',0)sys.stderr=sys.__stderr__=fdopen(2,'wb',0)defset_fully_buffered_io():sys.stdout=sys.__stdout__=fdopen(1,'w')# ____________________________________________________________# Main entry pointdefwe_are_translated():# app-level, very different from pypy.rlib.objectmodel.we_are_translatedreturnhasattr(sys,'pypy_translation_info')if'nt'insys.builtin_module_names:IS_WINDOWS=Trueelse:IS_WINDOWS=Falsedefsetup_and_fix_paths(ignore_environment=False,**extra):importosnewpath=sys.path[:]delsys.path[:]# first prepend PYTHONPATHreadenv=notignore_environmentpath=readenvandos.getenv('PYTHONPATH')ifpath:sys.path.extend(path.split(os.pathsep))# then add again the original entries, ignoring duplicates_seen=set()fordirinnewpath:ifdirnotin_seen:sys.path.append(dir)_seen.add(dir)defset_stdio_encodings(ignore_environment):importosreadenv=notignore_environmentio_encoding=readenvandos.getenv("PYTHONIOENCODING")ifio_encoding:errors=Noneif":"inio_encoding:io_encoding,errors=io_encoding.split(":",1)set_io_encoding(io_encoding,io_encoding,errors,True)else:ifIS_WINDOWS:import__pypy__io_encoding,io_encoding_output=__pypy__.get_console_cp()else:io_encoding=io_encoding_output=sys.getfilesystemencoding()ifio_encoding:set_io_encoding(io_encoding,io_encoding_output,None,False)defset_io_encoding(io_encoding,io_encoding_output,errors,overridden):try:import_fileexceptImportError:ifsys.version_info<(2,7):return# HACK: while running on top of CPython, and make sure to import# CPython's ctypes (because at this point sys.path has already been# set to the pypy one)pypy_path=sys.pathtry:sys.path=sys.cpython_pathimportctypesfinally:sys.path=pypy_pathset_file_encoding=ctypes.pythonapi.PyFile_SetEncodingAndErrorsset_file_encoding.argtypes=[ctypes.py_object,ctypes.c_char_p,ctypes.c_char_p]else:set_file_encoding=_file.set_file_encodingforf,encodingin[(sys.stdin,io_encoding),(sys.stdout,io_encoding_output),(sys.stderr,io_encoding_output)]:ifisinstance(f,file)and(overriddenorf.isatty()):set_file_encoding(f,encoding,errors)# Order is significant!sys_flags=("debug","py3k_warning","division_warning","division_new","inspect","interactive","optimize","dont_write_bytecode","no_user_site","no_site","ignore_environment","tabcheck","verbose","unicode","bytes_warning","hash_randomization",)default_options=dict.fromkeys(sys_flags+("run_command","run_module","run_stdin","warnoptions","unbuffered"),0)PYTHON26=Truedefsimple_option(options,name,iterargv):options[name]+=1defdiv_option(options,div,iterargv):ifdiv=="warn":options["division_warning"]=1elifdiv=="warnall":options["division_warning"]=2elifdiv=="new":options["division_new"]=1elifdiv!="old":raiseCommandLineError("invalid division option: %r"%(div,))defc_option(options,runcmd,iterargv):options["run_command"]=runcmdreturn['-c']+list(iterargv)defm_option(options,runmodule,iterargv):options["run_module"]=Truereturn[runmodule]+list(iterargv)defW_option(options,warnoption,iterargv):options["warnoptions"].append(warnoption)defend_options(options,_,iterargv):returnlist(iterargv)cmdline_options={# simple options just increment the counter of the options listed above'd':(simple_option,'debug'),'i':(simple_option,'interactive'),'O':(simple_option,'optimize'),'S':(simple_option,'no_site'),'E':(simple_option,'ignore_environment'),'t':(simple_option,'tabcheck'),'v':(simple_option,'verbose'),'U':(simple_option,'unicode'),'u':(simple_option,'unbuffered'),# more complex options'Q':(div_option,Ellipsis),'c':(c_option,Ellipsis),'m':(m_option,Ellipsis),'W':(W_option,Ellipsis),'V':(print_version,None),'--version':(print_version,None),'--info':(print_info,None),'h':(print_help,None),'--help':(print_help,None),'--jit':(set_jit_option,Ellipsis),'--':(end_options,None),}ifPYTHON26:cmdline_options.update({'3':(simple_option,'py3k_warning'),'B':(simple_option,'dont_write_bytecode'),'s':(simple_option,'no_user_site'),'b':(simple_option,'bytes_warning'),'R':(simple_option,'hash_randomization'),})defhandle_argument(c,options,iterargv,iterarg=iter(())):function,funcarg=cmdline_options[c]## If needed, fill in the real argument by taking it from the command lineiffuncargisEllipsis:remaining=list(iterarg)ifremaining:funcarg=''.join(remaining)else:try:funcarg=iterargv.next()exceptStopIteration:iflen(c)==1:c='-'+craiseCommandLineError('Argument expected for the %r option'%c)#returnfunction(options,funcarg,iterargv)defparse_command_line(argv):importosoptions=default_options.copy()options['warnoptions']=[]#iterargv=iter(argv)argv=Noneforarginiterargv:## If the next argument isn't at least two characters long or# doesn't start with '-', stop processingiflen(arg)<2orarg[0]!='-':ifIS_WINDOWSandarg=='/?':# special caseprint_help()argv=[arg]+list(iterargv)# finishes processing## If the next argument is directly in cmdline_options, handle# it as a single argumentelifargincmdline_options:argv=handle_argument(arg,options,iterargv)## Else interpret the rest of the argument character by characterelse:iterarg=iter(arg)iterarg.next()# skip the '-'forciniterarg:ifcnotincmdline_options:raiseCommandLineError('Unknown option: -%s'%(c,))argv=handle_argument(c,options,iterargv,iterarg)ifnotargv:argv=['']options["run_stdin"]=Trueelifargv[0]=='-':options["run_stdin"]=True# don't change the list that sys.argv is bound to# (relevant in case of "reload(sys)")sys.argv[:]=argvifPYTHON26andnotoptions["ignore_environment"]:ifos.getenv('PYTHONNOUSERSITE'):options["no_user_site"]=1ifos.getenv('PYTHONDONTWRITEBYTECODE'):options["dont_write_bytecode"]=1if(options["interactive"]or(notoptions["ignore_environment"]andos.getenv('PYTHONINSPECT'))):options["inspect"]=1## We don't print the warning, because it offers no additional security## in CPython either (http://bugs.python.org/issue14621)## if (options["hash_randomization"] or os.getenv('PYTHONHASHSEED')):## print >> sys.stderr, (## "Warning: pypy does not implement hash randomization")ifPYTHON26andwe_are_translated():flags=[options[flag]forflaginsys_flags]sys.flags=type(sys.flags)(flags)sys.py3kwarning=bool(sys.flags.py3k_warning)sys.dont_write_bytecode=bool(sys.flags.dont_write_bytecode)ifsys.py3kwarning:print>>sys.stderr,("Warning: pypy does not implement py3k warnings")## if not we_are_translated():## for key in sorted(options):## print '%40s: %s' % (key, options[key])## print '%40s: %s' % ("sys.argv", sys.argv)returnoptionsdefrun_command_line(interactive,inspect,run_command,no_site,run_module,run_stdin,warnoptions,unbuffered,ignore_environment,**ignored):# with PyPy in top of CPython we can only have around 100 # but we need more in the translated PyPy for the compiler packageif'__pypy__'notinsys.builtin_module_names:sys.setrecursionlimit(5000)importosifunbuffered:set_unbuffered_io()elifnotsys.stdout.isatty():set_fully_buffered_io()mainmodule=type(sys)('__main__')sys.modules['__main__']=mainmoduleifnotno_site:try:importsiteexcept:print>>sys.stderr,"'import site' failed"set_stdio_encodings(ignore_environment)readenv=notignore_environmentpythonwarnings=readenvandos.getenv('PYTHONWARNINGS')ifpythonwarnings:warnoptions.extend(pythonwarnings.split(','))ifwarnoptions:sys.warnoptions[:]=warnoptionsfromwarningsimport_processoptions_processoptions(sys.warnoptions)# set up the Ctrl-C => KeyboardInterrupt signal handler, if the# signal module is availabletry:importsignalexceptImportError:passelse:signal.signal(signal.SIGINT,signal.default_int_handler)ifhasattr(signal,"SIGPIPE"):signal.signal(signal.SIGPIPE,signal.SIG_IGN)ifhasattr(signal,'SIGXFZ'):signal.signal(signal.SIGXFZ,signal.SIG_IGN)ifhasattr(signal,'SIGXFSZ'):signal.signal(signal.SIGXFSZ,signal.SIG_IGN)definspect_requested():# We get an interactive prompt in one of the following three cases:## * interactive=True, from the "-i" option# or# * inspect=True and stdin is a tty# or# * PYTHONINSPECT is set and stdin is a tty.#return(interactiveor((inspector(readenvandos.getenv('PYTHONINSPECT')))andsys.stdin.isatty()))success=Truetry:ifrun_command!=0:# handle the "-c" command# Put '' on sys.pathsys.path.insert(0,'')defrun_it():execrun_commandinmainmodule.__dict__success=run_toplevel(run_it)elifrun_module:# handle the "-m" command# '' on sys.path is required also heresys.path.insert(0,'')importrunpysuccess=run_toplevel(runpy._run_module_as_main,sys.argv[0])elifrun_stdin:# handle the case where no command/filename/module is specified# on the command-line.# update sys.path *after* loading site.py, in case there is a# "site.py" file in the script's directory. Only run this if we're# executing the interactive prompt, if we're running a script we# put it's directory on sys.pathsys.path.insert(0,'')ifinteractiveorsys.stdin.isatty():# If stdin is a tty or if "-i" is specified, we print# a banner and run $PYTHONSTARTUP.print_banner()python_startup=readenvandos.getenv('PYTHONSTARTUP')ifpython_startup:try:f=open(python_startup)startup=f.read()f.close()exceptIOError,e:print>>sys.stderr,"Could not open PYTHONSTARTUP"print>>sys.stderr,"IOError:",eelse:defrun_it():co_python_startup=compile(startup,python_startup,'exec')execco_python_startupinmainmodule.__dict__run_toplevel(run_it)# Then we need a prompt.inspect=Trueelse:# If not interactive, just read and execute stdin normally.defrun_it():co_stdin=compile(sys.stdin.read(),'<stdin>','exec')execco_stdininmainmodule.__dict__mainmodule.__file__='<stdin>'success=run_toplevel(run_it)else:# handle the common case where a filename is specified# on the command-line.filename=sys.argv[0]mainmodule.__file__=filenamesys.path.insert(0,sys.pypy_resolvedirof(filename))# assume it's a pyc file only if its name says so.# CPython goes to great lengths to detect other cases# of pyc file format, but I think it's ok not to care.importimpifIS_WINDOWS:filename=filename.lower()iffilename.endswith('.pyc')orfilename.endswith('.pyo'):args=(imp._run_compiled_module,'__main__',sys.argv[0],None,mainmodule)else:# maybe it's the name of a directory or a zip filefilename=sys.argv[0]importer=imp._getimporter(filename)ifnotisinstance(importer,imp.NullImporter):# yes. put the filename in sys.path[0] and import# the module __main__importrunpysys.path.insert(0,filename)args=(runpy._run_module_as_main,'__main__',False)else:# no. That's the normal path, "pypy stuff.py".args=(execfile,filename,mainmodule.__dict__)success=run_toplevel(*args)exceptSystemExit,e:status=e.codeifinspect_requested():display_exception()else:status=notsuccess# start a prompt if requestedifinspect_requested():inteactive=Falsetry:from_pypy_interactimportinteractive_consolesuccess=run_toplevel(interactive_console,mainmodule)exceptSystemExit,e:status=e.codeelse:status=notsuccessreturnstatusdefprint_banner():print'Python %s on %s'%(sys.version,sys.platform)print('Type "help", "copyright", "credits" or ''"license" for more information.')STDLIB_WARNING="""\debug: WARNING: Library path not found, using compiled-in sys.path.debug: WARNING: 'sys.prefix' will not be set.debug: WARNING: Make sure the pypy binary is kept inside its tree of files.debug: WARNING: It is ok to create a symlink to it from somewhere else."""defsetup_bootstrap_path(executable):""" Try to to as little as possible and to have the stdlib in sys.path. In particular, we cannot use any unicode at this point, because lots of unicode operations require to be able to import encodings. """# at this point, sys.path is set to the compiled-in one, based on the# location where pypy was compiled. This is set during the objspace# initialization by module.sys.state.State.setinitialpath.## Now, we try to find the absolute path of the executable and the stdlib# pathexecutable=sys.pypy_find_executable(executable)stdlib_path=sys.pypy_find_stdlib(executable)ifstdlib_pathisNone:print>>sys.stderr,STDLIB_WARNINGelse:sys.path[:]=stdlib_path# from this point on, we are free to use all the unicode stuff we want,# This is important for py3ksys.executable=executabledefentry_point(executable,argv):# note that before calling setup_bootstrap_path, we are limited because we# cannot import stdlib modules. In particular, we cannot use unicode# stuffs (because we need to be able to import encodings) and we cannot# import os, which is used a bit everywhere in app_main, but only imported# *after* setup_bootstrap_pathsetup_bootstrap_path(executable)try:cmdline=parse_command_line(argv)exceptCommandLineError,e:print_error(str(e))return2exceptSystemExit,e:returne.codeor0setup_and_fix_paths(**cmdline)returnrun_command_line(**cmdline)if__name__=='__main__':# obscure! try removing the following line, see how it crashes, and# guess why...ImStillAroundDontForgetMe=sys.modules['__main__']# debugging onlydefpypy_find_executable(s):importosreturnos.path.abspath(s)defpypy_find_stdlib(s):fromos.pathimportabspath,join,dirnameasdnthisfile=abspath(__file__)root=dn(dn(dn(dn(thisfile))))return[join(root,'lib-python','2.7'),join(root,'lib_pypy')]defpypy_resolvedirof(s):# we ignore the issue of symlinks; for tests, the executable is always# translator/goal/app_main.py anywayimportosreturnos.path.abspath(os.path.join(s,'..'))# add an emulator for these pypy-only or 2.7-only functions# (for test_pyc_commandline_argument)importimp,runpydef_run_compiled_module(modulename,filename,file,module):importosassertmodulename=='__main__'assertos.path.isfile(filename)assertfilename.endswith('.pyc')assertfileisNoneassertmodule.__name__=='__main__'print'in _run_compiled_module'def_getimporter(path):importos,impifos.path.isdir(path):returnNoneelse:returnimp.NullImporter(path)imp._run_compiled_module=_run_compiled_moduleimp._getimporter=_getimporterimportosreset=[]if'PYTHONINSPECT_'inos.environ:reset.append(('PYTHONINSPECT',os.environ.get('PYTHONINSPECT','')))os.environ['PYTHONINSPECT']=os.environ['PYTHONINSPECT_']if'PYTHONWARNINGS_'inos.environ:reset.append(('PYTHONWARNINGS',os.environ.get('PYTHONWARNINGS','')))os.environ['PYTHONWARNINGS']=os.environ['PYTHONWARNINGS_']delos# make sure that os is not available globally, because this is what# happens in "real life" outside the tests# no one should change to which lists sys.argv and sys.path are boundold_argv=sys.argvold_path=sys.pathsys.pypy_find_executable=pypy_find_executablesys.pypy_find_stdlib=pypy_find_stdlibsys.pypy_resolvedirof=pypy_resolvedirofsys.cpython_path=sys.path[:]try:sys.exit(int(entry_point(sys.argv[0],sys.argv[1:])))finally:# restore the normal prompt (which was changed by _pypy_interact), in# case we are dropping to CPython's promptsys.ps1='>>> 'sys.ps2='... 'importos;os.environ.update(reset)assertold_argvissys.argvassertold_pathissys.path