o
    DDic                  $   @   s  U 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ZddlZddl	Z	ddl
mZmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZ dd	lm Z  dd
l!m"Z"m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6 dd dZ7e8e9d< dee8 dedefddZ:de0ddfddZ;dddee8 d e<dee8 fd!d"Z=dd#d$e8d%e8d&e>d'ee8 de8f
d(d)Z?de7dd*dd+d,e%de8d-e<d.e8d/e<dee8 d0ee8 dee8 fd1d2Z@ed3d4G d5d6 d6ZAed3d4G d7d8 d8ZBd9e8d'e8d:ee8eCf d;ee6 de'f
d<d=ZDd>ee%ee% f d9e8d'e8d?ee8eCf d@ee8eCf d;ee6 de%fdAdBZEd'e8dCeBdeeAeFf fdDdEZGd>ee%ee% f d'e8dCeBd?ee8eCf dFeee8eCf  d;ee6 deAfdGdHZHG dIdJ dJZIdKeAdLeIdMe<dNe<dOe<dPe<ddfdQdRZJed3d4G dSdT dTZKddde7dd*ddddd*ddddUd,ee%ee% f dVee8 dWee> dMee> d-e<d.e8d/e<dee8 dNe<dOe<dPe<dXe<dYee8 d0ee8 d9ee8 dFeee8eCf  deKf"dZd[ZLdS )\z'
Provides helpers for CLI interaction.
    N)as_completedExecutor)deepcopy)	dataclass)	cpu_count)Path)	AnyStrCallablecastDictListOptionalSequenceTypeUnion)warn)parse_modulePartialParserConfig)Codemod)CodemodContext)DummyExecutor)SkipFile
SkipReasontransform_moduleTransformExitTransformFailureTransformResultTransformSkipTransformSuccess)calculate_module_and_package)FullRepoManagerz@gen erated_DEFAULT_GENERATED_CODE_MARKERformatter_argscodereturnc                 C   sF   t | dkr
tdt|t}tttj| || |rddS ddS )zg
    Given a code string, run an external formatter on the code and return new
    formatted code.
    r   z6No formatter configured but code formatting requested.Nutf-8)inputuniversal_newlinesencoding)len	Exception
isinstancebytesr
   r   
subprocesscheck_output)r$   r%   work_with_bytes r2   L/var/www/Datamplify/venv/lib/python3.10/site-packages/libcst/codemod/_cli.pyinvoke_formatter.   s   
r4   resultc                 C   sj   | j D ]}td| tjd qt| tr3| j}t|tjr)t|j	
dtjd t| jtjd d S d S )Nz	WARNING: filer'   )warning_messagesprintsysstderrr-   r   errorr/   CalledProcessErroroutputdecodetraceback_str)r5   warningr<   r2   r2   r3   print_execution_resultF   s   

rB   Finclude_stubsfiles_or_dirsrD   c                   s\   g }| D ]%}t j|r|| qt j|r)| fddt|dD  qt|S )a5  
    Given a list of files or directories (can be intermingled), return a list of
    all python files that exist at those locations. If ``include_stubs`` is ``True``,
    this will include ``.py`` and ``.pyi`` stub files. If it is ``False``, only
    ``.py`` files will be included in the returned list.
    c                 3   sB    | ]}t |rt|d s rt|drt|V  qdS )pypyiN)r   is_filestrendswith).0prC   r2   r3   	<genexpr>_   s    
zgather_files.<locals>.<genexpr>z*.py*)	ospathisfileappendisdirextendr   rglobsorted)rE   rD   retfdr2   rC   r3   gather_filesQ   s   	rX   filenameoldcodenewcodecontextrZ   c                C   s\   | |krdS |rt j| d|d||d|d}nt j| d|dd|d}d|S )a  
    Given two strings representing a module before and after a codemod, produce
    a unified diff of the changes with ``context`` lines of context. Optionally,
    assign the ``filename`` to the change, and if it is not available, assume
    that the change was performed on stdin/stdout. If no change is detected,
    return an empty string instead of returning an empty unified diff. This is
    comparable to revision control software which only shows differences for
    files that have changed.
    r!   
)fromfiletofilelinetermn)ra   rb   )difflibunified_diffsplitjoin)r[   r\   r]   rZ   	difflinesr2   r2   r3   	diff_codej   s   	
rh   r2   )include_generatedgenerated_code_markerformat_coder$   python_version	transformri   rj   rk   rl   c          
   
   C   s   |s||v rt dtjd |S t| ||d}t|tttfr dn|j}|durO|rOzt	||}W n t
yN }	 zd}t|	t |jd}W Y d}	~	nd}	~	ww t| |S )a#  
    Given an instantiated codemod and a string representing a module, transform that
    code by executing the transform, optionally invoking the formatter and finally
    printing any generated warnings to stderr. If the code includes the generated
    marker at any spot and ``include_generated`` is not set to ``True``, the code
    will not be modified. If ``format_code`` is set to ``False`` or the instantiated
    codemod does not modify the code, the code will not be formatted.  If a
    ``python_version`` is provided, then we will parse the module using
    this version. Otherwise, we will use the version of the currently executing python
    binary.

    In all cases a module will be returned. Whether it is changed depends on the
    input parameters as well as the codemod itself.
    zMWARNING: Code is generated and we are set to ignore generated code, skipping!r6   rl   Nr<   r@   r8   )r9   r:   r;   r   r-   r   r   r   r%   r4   r,   	traceback
format_excr8   rB   )
rm   r%   ri   rj   rk   r$   rl   r5   
maybe_codeexr2   r2   r3   exec_transform_with_prettyprint   s2   rt   T)frozenc                   @   s&   e Zd ZU eed< eed< eed< dS )ExecutionResultrZ   changedtransform_resultN)__name__
__module____qualname__rI   __annotations__boolr   r2   r2   r2   r3   rv      s   
 rv   c                   @   s   e Zd ZU dZee ed< dZeed< dZ	ee ed< e
Zeed< dZeed< dZee ed	< dZee ed
< dZee ed< dS )ExecutionConfigr2   blacklist_patternsFrk   r$   rj   ri   Nrl   	repo_rootrd   )ry   rz   r{   r   r   rI   r|   rk   r}   r$   r#   rj   ri   rl   r   r   rd   intr2   r2   r2   r3   r~      s   
 r~   r   scratchrepo_managerc              
   C   st   zt | |}|j}|j}W n# ty0 } ztd| d| tjd d }d }W Y d }~nd }~ww t|||||dS )Nz$Failed to determine module name for : r6   )r   rZ   full_module_namefull_package_namemetadata_manager)r   namepackage
ValueErrorr9   r:   r;   r   )r   rZ   r   r   module_name_and_packagemod_namepkg_namers   r2   r2   r3   _prepare_context   s"   

r   transformeroriginal_scratchcodemod_kwargsc                 C   s>   t | tr| ddt||i |i|S t||t||| _| S )Nr]   r2   )r-   typer   r   r]   )r   r   rZ   r   r   r   r2   r2   r3   _instantiate_transformer   s   
r   configc              	   C   s   |j D ]}t|| rt| dttjd| ddd  S qt| d}| }W d    n1 s2w   Y  |j	sN|j
d|v rNt| dttjdddS |S )	NFzBlacklisted by pattern .)skip_reasonskip_descriptionrZ   rw   rx   rbr'   zGenerated file.)r   re	fullmatchrv   r   r   BLACKLISTEDopenreadri   rj   encode	GENERATED)rZ   r   patternfpr[   r2   r2   r3   _check_for_skip  s4   




r   codemod_argsc                 C   s  g }zt ||}t|tr|W S t| |jpd|||pi |}z(t||jd ur.tt|jdnt d}	|	|	}
|
j
}|
j}||jj W n) tyo } z||jj t|dttjt||ddW  Y d }~W S d }~ww |jr}||kr}t|j|}||k}|jrt|||||j|d}n|rt|d}|| W d    n1 sw   Y  d	}t||t||d
dW S  ty   t|dt|dd Y S  ty } zt|dt|t ! |ddW  Y d }~S d }~ww )Nr   rn   r   F)r   r   r8   r   rY   wbr!   )r8   r%   )r8   ro   )"r   r-   rv   r   r   r   rl   r   rI   r   r.   r*   rS   r]   warningsr   r   r   OTHERrk   r4   r$   rd   rh   r?   r   writer   KeyboardInterruptr   r,   r   rp   rq   )r   rZ   r   r   r   r   r   r[   transformer_instance
input_treeoutput_treer\   r*   rs   rw   r   r2   r2   r3   _execute_transform&  s   






r   c                   @   s   e Zd ZU dZeed< dededdfddZd	eddfd
dZ	de
eef defddZdedededefddZdddZdS )Progressz[2KERASE_CURRENT_LINEenabledtotalr&   Nc                C   s2   || _ || _tt| jd d | _t | _d S )Nd      )r   r   r+   rI   pretty_precisiontime
started_at)selfr   r   r2   r2   r3   __init__  s   zProgress.__init__finishedc                 C   s   | j sd S | j| }dt|t| j  }tt | j d}t| j | | d|d| j	 dd| 
||| d| d	d	tjd
 d S )Ng      Y@r    r   fz% complete, z estimated for z files to go...r!   endr7   )r   r   floatmaxr   r   r9   r   _human_secondsr   estimate_completionr:   r;   )r   r   leftpercentelapsed_timer2   r2   r3   r9     s   
<
zProgress.printsecondsc                 C   sh   t |d\}}t |d\}}|dkr |dd|dd|ddS |dkr.|dd|ddS |ddS )	zt
        This returns a string which is a human-ish readable elapsed time such
        as 30.42s or 10m 31s
        <   r   z.0fzh z02.0fzm sz02.2f)divmod)r   r   minuteshoursr2   r2   r3   r     s   zProgress._human_secondselapsed_secondsfiles_finished
files_leftc                 C   s.   |dks|dkr
dS || }|| }|  |S )zp
        Computes a really basic estimated completion given a number of
        operations still to do.
        r   z[calculating])r   )r   r   r   r   fpsestimated_seconds_leftr2   r2   r3   r     s
   
zProgress.estimate_completionc                 C   s    | j sd S t| jdtjd d S )Nr!   r   )r   r9   r   r:   r;   )r   r2   r2   r3   clear  s   zProgress.clear)r&   N)ry   rz   r{   r   rI   r|   r}   r   r   r9   r   r   r   r   r   r2   r2   r2   r3   r     s   
 	
r   exec_resultprogressrd   show_successeshide_generatedhide_blacklistedc                C   sJ  | j }| j}t|trB|jtju r|s>|jtju r|s@|  t	d| t
jd t| t	d| d|j dt
jd d S d S d S t|trf|  t	d| t
jd t| t	d| dt
jd d S t|tr|sp|jr|  t	d| t
jd t| t	d| |jrdnd t
jd |r|jrt	|j d S d S d S d S )	NzCodemodding r6   zSkipped codemodding r   r^   zFailed to codemod zSuccessfully codemodded z with warnings
)rZ   rx   r-   r   r   r   r   r   r   r9   r:   r;   rB   r   r   r   r8   r%   )r   r   rd   r   r   r   rZ   r5   r2   r2   r3   _print_parallel_result  sD   	


	


r   c                   @   s2   e Zd ZU dZeed< eed< eed< eed< dS )ParallelTransformResulta  
    The result of running
    :func:`~libcst.codemod.parallel_exec_transform_with_prettyprint` against
    a series of files. This is a simple summary, with counts for number of
    successfully codemodded files, number of files that we failed to codemod,
    number of warnings generated when running the codemod across the files, and
    the number of files that we skipped when running the codemod.
    	successesfailuresr   skipsN)ry   rz   r{   __doc__r   r|   r2   r2   r2   r3   r     s   
 
r   )jobsrd   ri   rj   rk   r$   r   r   r   hide_progressr   rl   r   r   filesr   r   r   c             
      s  t trtdtdd tdd |D }t|}t| |d}d}t|dur)|nt t|| d	 | }|d	k r>t	d
|dkrJt
dddddS d|duritj|}tdtjd t||   tdtjd t||||||||d|d	ks|d	krd	}t}n4ttddd  rddlm} tj||d}td|durt|dnt d nddlm} tj||d}d}d}d}d}t trtjj ni | oza fdd|D }t!|D ]H}|" }t#||t$|||	|
d ||| |  t |j%t&r|d	7 }nt |j%t'r|d	7 }nt |j%t(t)fr)|d	7 }|t|j%j*7 }qW |+  n|+  w W d   n	1 sHw   Y  t
||||dS )aD  
    Given a list of files and a codemod we should apply to them, fork and apply the
    codemod in parallel to all of the files, including any configured formatter. The
    ``jobs`` parameter controls the maximum number of in-flight transforms, and needs to
    be at least 1. If not included, the number of jobs will automatically be set to the
    number of CPU cores. If ``unified_diff`` is set to a number, changes to files will
    be printed to stdout with ``unified_diff`` lines of context. If it is set to
    ``None`` or left out, files themselves will be updated with changes and formatting.
    If a ``python_version`` is provided, then we will parse each source file using this
    version. Otherwise, we will use the version of the currently executing python
    binary.

    A progress indicator as well as any generated warnings will be printed to stderr. To
    supress the interactive progress indicator, set ``hide_progress`` to ``True``. Files
    that include the generated code marker will be skipped unless the
    ``include_generated`` parameter is set to ``True``. Similarly, files that match a
    supplied blacklist of regex patterns will be skipped. Warnings for skipping both
    blacklisted and generated files will be printed to stderr along with warnings
    generated by the codemod unless ``hide_blacklisted`` and ``hide_generated`` are set
    to ``True``. Files that were successfully codemodded will not be printed to stderr
    unless ``show_successes`` is set to ``True``.

    We take a :class:`~libcst.codemod._codemod.Codemod` class, or an instantiated
    :class:`~libcst.codemod._codemod.Codemod`. In the former case, the codemod will be
    instantiated for each file, with ``codemod_args`` passed in to the constructor.
    Passing an already instantiated :class:`~libcst.codemod._codemod.Codemod` is
    deprecated, because it leads to sharing of the
    :class:`~libcst.codemod._codemod.Codemod` instance across files, which is a common
    source of hard-to-track-down bugs when the :class:`~libcst.codemod._codemod.Codemod`
    tracks its state on the instance.
    zPassing transformer instances to `parallel_exec_transform_with_prettyprint` is deprecated and will break in a future version. Please pass the transformer class instead.   )
stacklevelc                 S   s   h | ]}t j|qS r2   )rN   rO   abspath)rK   r   r2   r2   r3   	<setcomp>H  s    z;parallel_exec_transform_with_prettyprint.<locals>.<setcomp>)r   r      Nr   z&Must have at least one job to process!r   )r   r   r   r   z!Calculating full-repo metadata...r6   zExecuting codemod...)r   rd   ri   rj   rk   r$   r   rl   _is_gil_enabledc                   S   s   dS )NTr2   r2   r2   r2   r3   <lambda>z  s    z:parallel_exec_transform_with_prettyprint.<locals>.<lambda>)ProcessPoolExecutor)max_workersr!   rn   r   )ThreadPoolExecutorc                    s$   g | ]}j t| d qS ))r   rZ   r   r   r   r   )submitr   )rK   rZ   r   r   executorr   r   rm   r2   r3   
<listcomp>  s    
z<parallel_exec_transform_with_prettyprint.<locals>.<listcomp>)rd   r   r   r   ),r-   r   r   DeprecationWarningrU   r+   r   minr   r,   r   rN   rO   r   r9   r:   r;   r    get_inherited_dependenciesresolve_cacher~   r   getattrconcurrent.futuresr   	functoolspartialr   r   r   r   r]   r   r   r5   r   r}   rx   r   r   r   r   r8   r   )rm   r   r   rd   ri   rj   rk   r$   r   r   r   r   r   rl   r   r   r   r   	chunksize	pool_implr   r   r   r   r   r   futuresfuturer5   r2   r   r3   (parallel_exec_transform_with_prettyprint
  s   
3

	



)r   )Mr   rc   r   os.pathrN   r   r/   r:   r   rp   r   r   r   copyr   dataclassesr   multiprocessingr   pathlibr   typingr   r	   r
   r   r   r   r   r   r   r   r   libcstr   r   libcst.codemod._codemodr   libcst.codemod._contextr   libcst.codemod._dummy_poolr   libcst.codemod._runnerr   r   r   r   r   r   r   r   libcst.helpersr   libcst.metadatar    r#   rI   r|   r4   rB   r}   rX   r   rh   rt   rv   r~   objectr   r   r.   r   r   r   r   r   r   r2   r2   r2   r3   <module>   sv  ,(


$	
:	






!

`>
0	
