3 \.@sdZddlZddlZddlZddlZddlmZmZddgZ Gddde Z Gdd d e Z d d d Z d!d d ZefddZGdddeZd"ddZd#ddZefddZddZd$ddZedkreejdkredejdnejd=eejddS)%aZrunpy.py - locating and running Python code using the module namespace Provides support for locating and running Python scripts using the Python module namespace instead of the native filesystem. This allows Python code to play nicely with non-filesystem based PEP 302 importers when locating support scripts as well as when importing modules. N) read_code get_importer run_modulerun_pathc@s(eZdZdZddZddZddZdS) _TempModulezCTemporarily replace a module in sys.modules with an empty namespacecCs||_tj||_g|_dS)N)mod_nametypes ModuleTypemodule _saved_module)selfrr /usr/lib64/python3.6/runpy.py__init__s z_TempModule.__init__c CsB|j}y|jjtj|Wntk r0YnX|jtj|<|S)N)rr appendsysmodulesKeyErrorr )r rr r r __enter__s z_TempModule.__enter__cGs.|jr|jdtj|j<n tj|j=g|_dS)Nr)r rrr)r argsr r r__exit__'s z_TempModule.__exit__N)__name__ __module__ __qualname____doc__rrrr r r rrs rc@s$eZdZddZddZddZdS)_ModifiedArgv0cCs||_t|_|_dS)N)valueobject _saved_value _sentinel)r rr r rr/sz_ModifiedArgv0.__init__cCs0|j|jk rtdtjd|_|jtjd<dS)NzAlready preserving saved valuer)rr RuntimeErrorrargvr)r r r rr3s  z_ModifiedArgv0.__enter__cGs|j|_|jtjd<dS)Nr)rrrrr!)r rr r rr9sz_ModifiedArgv0.__exit__N)rrrrrrr r r rr.src Csn|dk r|j||dkr(d}|}d} n |j}|j}|j} |dkrH|j}|j||| d|||dt|||S)z)Helper to run code in nominated namespaceN)r__file__ __cached__r __loader__ __package____spec__)updateloaderorigincachedparentexec) codeZ run_globals init_globalsrmod_specpkg_name script_namer(fnamer*r r r _run_code>s(  r3c Cs^|dkr |n|j}t|6}t|"|jj}t|||||||WdQRXWdQRX|jS)z5Helper to run code in new namespace with sys modifiedN)r)rrr __dict__r3copy) r-r.rr/r0r1r2 temp_module mod_globalsr r r_run_module_codeXs  r8c ;Cs4|jdr|d|jd\}}}|ry t|WnJtk r|}z.|jdksj|j|krl|j|jd rlWYdd}~XnXtjj|}|dk rt|d rddl m }dj ||d}|t |yt jj|}WnJttttfk r} z$d}||j |t| j| | WYdd} ~ XnX|dkr6|d ||jdk r|d ksX|jd r`|d y|d } t| |S|k r}z$|tjkr|d||fWYdd}~XnX|j} | dkr|d|y| j|} Wn2tk r}z|t ||WYdd}~XnX| dkr*|d|||| fS)N.z#Relative module names not supported__path__r)warnz{mod_name!r} found in sys.modules after import of package {pkg_name!r}, but prior to execution of {mod_name!r}; this may result in unpredictable behaviour)rr0z:Error while finding module specification for {!r} ({}: {})zNo module named %s__main__z .__main__z%Cannot use package as __main__ modulez%s; %r is a package and cannot zbe directly executedz0%r is a namespace package and cannot be executedzNo code object available for %sz3%s; %r is a package and cannot be directly executed) startswith rpartition __import__ ImportErrornamerrgethasattrwarningsr;formatRuntimeWarning importlibutil find_specAttributeError TypeError ValueErrortypersubmodule_search_locationsendswith_get_module_detailsr(get_code) rerrorr0_eZexistingr;msgspecZexZ pkg_main_namer(r-r r rrPfsZ      ,          rPc@seZdZdZdS)_ErrorzBError that _run_module_as_main() should report without a tracebackN)rrrrr r r rrWsrWTcCsy0|s|dkr t|t\}}}ntt\}}}Wn:tk rj}zdtj|f}tj|WYdd}~XnXtjdj}|r|jtj d<t ||dd|S)aRuns the designated module in the __main__ namespace Note that the executed module will have full access to the __main__ namespace. If this is not desirable, the run_module() function should be used to run the module code in a fresh namespace. At the very least, these variables in __main__ will be overwritten: __name__ __file__ __cached__ __loader__ __package__ r<z%s: %sNr) rPrW_get_main_module_detailsr executableexitrr4r)r!r3)rZ alter_argvr/r-excrUZ main_globalsr r r_run_module_as_mains   r\FcCs@t|\}}}|dkr|}|r,t||||St|i|||SdS)znExecute a module's code without importing it Returns the resulting top level namespace dictionary N)rPr8r3)rr.run_nameZ alter_sysr/r-r r rrs cCs~d}tj|}tj|=zVyt|Stk rh}z,|t|krV|d|tjdf|WYdd}~XnXWd|tj|<XdS)Nr<zcan't find %r module in %rr)rrrPr@strpath)rRZ main_nameZ saved_mainr[r r rrXs  rXcCsTt|d}t|}WdQRX|dkrLt|d}t|j|d}WdQRX||fS)Nrbr,)openrcompileread)r]r2fr-r r r_get_code_from_files   rec Cs|dkr d}|jdd}t|}d}t|jdkrFt|jdkrFd}t|tdsX|rxt||\}}t|||||d Stj j d|zRt \}} }t |4} t | | jj} t|| ||| |jSQRXWdQRXWdytj j|Wntk rYnXXdS) a_Execute code located at the specified filesystem location Returns the resulting top level namespace dictionary The file path may refer directly to a Python script (i.e. one that could be directly executed with execfile) or else it may refer to a zipfile or directory containing a top level __main__.py script. Nz r9rFZimpZ NullImporterT)r0r1)r>rrMrr isinstancerer8rr_insertrXrrr r4r3r5removerL) Z path_namer.r]r0ZimporterZis_NullImporterr-r2rr/r6r7r r rrs0     "r<z!No module specified for execution)file)NNNNN)NNNNN)T)NNF)NN)rrZimportlib.machineryrGimportlib.utilrZpkgutilrr__all__rrrr3r8r@rP ExceptionrWr\rrXrerrlenr!printstderrr r r rs6  :    1