U
    adn5                  	   @   s   d Z ddlZddlZddlZddlZddlZddlmZ dddgZ	ddd	Z
dddZdd ZdddZdddZdd Zedkree  Zee dS )a  Module/script to byte-compile all .py files to .pyc files.

When called as a script with arguments, this compiles the directories
given as arguments recursively; the -l option prevents it from
recursing into directories.

Without arguments, if compiles all modules on sys.path, without
recursing into subdirectories.  (Even though it should do so for
packages -- for now, you'll have to deal with packages separately.)

See module py_compile for details of the actual byte-compilation.
    N)partialcompile_dircompile_filecompile_path
   c                 c   s  |dk rt | tjrt| } |s0td|  zt| }W n. tk
rl   |dk rdtd|  g }Y nX |  |D ]}|dkrqztj	
| |}|d k	rtj	
||}nd }tj	|s||fV  qz|dkrz|tjkrz|tjkrztj	|rztj	|szt|||d |dE d H  qzd S )N   zListing {!r}...zCan't list {!r}__pycache__r      )ddir	maxlevelsquiet)
isinstanceosPathLikefspathprintformatlistdirOSErrorsortpathjoinisdircurdirpardirislink	_walk_dir)dirr
   r   r   namesnamefullnamedfile r"    /usr/lib/python3.8/compileall.pyr      s:    



 r   Fr	   c
                 C   s   d}
|dk rt d|dkrFzddlm}
 W n tk
rD   d}Y nX t| |||d}d}|dkr|
dk	r|ppd}|
|d0}|tt||||||	d	|}t|dd
}W 5 Q R X n(|D ]"\}}t	||||||||	sd}q|S )a  Byte-compile all modules in the given directory tree.

    Arguments (only dir is required):

    dir:       the directory to byte-compile
    maxlevels: maximum recursion level (default 10)
    ddir:      the directory that will be prepended to the path to the
               file as it is compiled into each byte-code file.
    force:     if True, force compilation, even if timestamps are up-to-date
    quiet:     full output with False or 0, errors only with 1,
               no output with 2
    legacy:    if True, produce legacy pyc paths instead of PEP 3147 paths
    optimize:  optimization level or -1 for level of the interpreter
    workers:   maximum number of parallel workers
    invalidation_mode: how the up-to-dateness of the pyc will be checked
    Nr   z%workers must be greater or equal to 0r	   )ProcessPoolExecutor)r   r   r
   T)Zmax_workers)forcerxr   legacyoptimizeinvalidation_mode)defaultF)

ValueErrorZconcurrent.futuresr%   ImportErrorr   mapr   _compile_file_tupleminr   )r   r   r
   r&   r'   r   r(   r)   workersr*   r%   Zfiles_and_ddirssuccessZexecutorZresultsfiler!   r"   r"   r#   r   2   sF    
     c                 K   s   | \}}t ||f|S )z-Needs to be toplevel for ProcessPoolExecutor.)r   )Zfile_and_dfilekwargsr3   r!   r"   r"   r#   r/   e   s    r/   c              
   C   s  d}|dk r"t | tjr"t| } tj| }	|dk	rFtj||	}
nd}
|dk	rd|| }|rd|S tj| r|r| d }nB|dkr|dkr|nd}t	j
j| |d}nt	j
| }tj|}|	dd	 |	d	d  }}|d
kr|s\zXtt| j}tdt	j
jd|}t|d}|d}W 5 Q R X ||krB|W S W n tk
rZ   Y nX |sptd|  ztj| ||
d||d}W n tjk
r } zjd}|dkr| W Y RS |rtd|  ntddd |jjtjjdd}| tjj}t| W 5 d}~X Y n t!t"tfk
r } zRd}|dkrJ| W Y :S |r`td|  ntddd t|j#j$d | W 5 d}~X Y nX |dkrd}|S )aT  Byte-compile one file.

    Arguments (only fullname is required):

    fullname:  the file to byte-compile
    ddir:      if given, the directory name compiled in to the
               byte-code file.
    force:     if True, force compilation, even if timestamps are up-to-date
    quiet:     full output with False or 0, errors only with 1,
               no output with 2
    legacy:    if True, produce legacy pyc paths instead of PEP 3147 paths
    optimize:  optimization level or -1 for level of the interpreter
    invalidation_mode: how the up-to-dateness of the pyc will be checked
    Tr   Ncr   r	    )optimizationz.pyz<4sllrb   zCompiling {!r}...)r)   r*   Fz*** Error compiling {!r}...z*** )endbackslashreplace)errors:)%r   r   r   r   r   basenamer   searchisfile	importlibutilcache_from_sourcedirnameintstatst_mtimestructZpackMAGIC_NUMBERopenreadr   r   r   
py_compilecompilePyCompileErrormsgencodesysstdoutencodingdecodeSyntaxErrorUnicodeError	__class____name__)r    r
   r&   r'   r   r(   r)   r*   r2   r   r!   ZmocfileZoptZ	cache_dirheadtailmtimeZexpectZchandleZactualokerrrP   er"   r"   r#   r   j   s    


 
 



$
c           	      C   sT   d}t jD ]D}|r|tjkr2| r2|dk rNtd q
|oLt||d|||||d}q
|S )a  Byte-compile all module on sys.path.

    Arguments (all optional):

    skip_curdir: if true, skip current directory (default True)
    maxlevels:   max recursion level (default 0)
    force: as for compile_dir() (default False)
    quiet: as for compile_dir() (default 0)
    legacy: as for compile_dir() (default False)
    optimize: as for compile_dir() (default -1)
    invalidation_mode: as for compiler_dir()
    Tr   zSkipping current directoryN)r   r(   r)   r*   )rR   r   r   r   r   r   )	Zskip_curdirr   r&   r   r(   r)   r*   r2   r   r"   r"   r#   r      s     


c                  C   s  ddl } | jdd}|jdddddd	d
 |jdtddd |jddddd |jdddddd |jddddd |jdddddd  |jd!d"d#dd$d  |jd%d&d'd(d) |jd*d+d,d-d. |jd/d0d1td2d3 d4d5 tjD }|jd6t|d7d8 | }|j}|j	r$ddl
}||j	|_	|jdk	r8|j}n|j}|jrzF|jd9krZtjnt|j }|D ]}||  qjW 5 Q R X W n4 tk
r   |jd:k rtd;|j Y d<S X |jr|jd9d= }	tj|	 }
nd}
d>}z|rl|D ]h}tj|r6t||j|j |j	|j|j!|
d?sbd<}n,t"|||j|j |j	|j|j!|j#|
d@	sd<}q|W S t$|j!|j |j|
dAW S W n, t%k
r   |jd:k rtdB Y d<S X d>S )CzScript main program.r   Nz1Utilities to support installing Python libraries.)Zdescriptionz-lZstore_constr   r   z!don't recurse into subdirectories)actionZconstr+   desthelpz-r	recursionzhcontrol the maximum recursion level. if `-l` and `-r` options are specified, then `-r` takes precedence.)typerb   rc   z-f
store_truer&   z/force rebuild even if timestamps are up to date)ra   rb   rc   z-qcountr   zIoutput only error messages; -qq will suppress the error messages as well.)ra   rb   r+   rc   z-br(   z0use legacy (pre-PEP3147) compiled file locationsz-dZDESTDIRr
   zdirectory to prepend to file paths for use in compile-time tracebacks and in runtime tracebacks in cases where the source file is unavailable)metavarrb   r+   rc   z-xZREGEXPr'   zskip files matching the regular expression; the regexp is searched for in the full path of each file considered for compilationz-iZFILEflistzzadd all the files and directories listed in FILE to the list considered for compilation; if "-", names are read from stdin)rh   rb   rc   compile_destzFILE|DIR*zrzero or more file and directory names to compile; if no arguments given, defaults to the equivalent of -l sys.path)rh   nargsrc   z-jz	--workersr	   zRun compileall concurrently)r+   re   rc   c                 S   s   g | ]}|j  d dqS )_-)r   lowerreplace).0moder"   r"   r#   
<listcomp>	  s   zmain.<locals>.<listcomp>z--invalidation-modezset .pyc invalidation mode; defaults to "checked-hash" if the SOURCE_DATE_EPOCH environment variable is set, and "timestamp" otherwise.)choicesrc   rn   r   zError reading file list {}Frm   T)r*   )r1   r*   )r(   r&   r   r*   z
[interrupted])&argparseArgumentParseradd_argumentrF   rM   PycInvalidationModesorted
parse_argsrj   r'   rerN   rd   r   ri   rR   stdinrK   appendstripr   r   r   r   r*   rp   upperr   r   rA   r   r
   r&   r(   r   r1   r   KeyboardInterrupt)ru   parserZinvalidation_modesargsZcompile_destsr{   r   flineZivl_moder*   r2   rb   r"   r"   r#   main   s    
 





   
   
r   __main__)Nr   r   )	r   NFNr   Fr$   r	   N)NFNr   Fr$   N)r	   r   Fr   Fr$   N)__doc__r   rR   importlib.utilrB   rM   rI   	functoolsr   __all__r   r   r/   r   r   r   rY   rF   Zexit_statusexitr"   r"   r"   r#   <module>   s<   

         
3     
V     
"i