a
    aRc                     @   s  d Z ddlZddlZddl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 ddlmZ dd	lmZ d
dlmZmZmZ d
dlmZmZmZmZ d
dl m!Z!m"Z"m#Z# d
dlm$Z$m%Z% d
dl&m'Z( d
dl&m)Z* d
dl+m,Z,m-Z-m.Z. G dd deZ/de-dddfe0ee0 e.ee e1ee1ef ee0dddZ2dde-ddfe0ee1ef ee0 e.ee e1ee1dddZ3de-ddddfeeee0 e.ee e1ee1ef e1ee1d
ddZ4dde-ddfeee1ef ee0 e.ee e1ee1dd d!Z5de-dddfee0ef ee1ef e.ee e1ee0 ee1d"d#d$Z6e%ed%d&d'Z7ej8ee d(d)d*Z9ej8ee0ef e%ee d+d,d-Z:de-ddddddfee0ef ee0 e.ee e1e1ee1ef e1ee ee1d.d/d0Z;e-dddfe0e.ee ee1e/f e1eeej< d1d2d3Z=e-ddddfee.ee ee1e/f e1eee0  eeej< d4d5d6Z>e-dddfee0ef e.ee ee1e/f e1eeej< d7d8d9Z?e-dddfeee0ef  e.ee ee1e/f e1eeej< d:d;d<Z@de-fee e.ee.d=d>d?ZAdS )@)	ImportKeycheck_code_string
check_filecheck_streamfind_imports_in_codefind_imports_in_filefind_imports_in_pathsfind_imports_in_streamplace_moduleplace_module_with_reasonsort_code_string	sort_filesort_stream    N)EnumStringIO)chain)Path)AnyIteratorOptionalSetTextIOUnioncast)warn)core   )filesidentifyio)ExistingSyntaxErrorsFileSkipCommentFileSkipSettingIntroducedSyntaxErrors)$ask_whether_to_apply_changes_to_filecreate_terminal_printershow_unified_diff)EmptyFile)module)module_with_reason)CYTHON_EXTENSIONSDEFAULT_CONFIGConfigc                   @   s    e Zd ZdZdZdZdZdZdS )r   a  Defines how to key an individual import, generally for deduping.

    Import keys are defined from less to more specific:

    from x.y import z as a
    ______| |        |    |
       |    |        |    |
    PACKAGE |        |    |
    ________|        |    |
          |          |    |
        MODULE       |    |
    _________________|    |
              |           |
           ATTRIBUTE      |
    ______________________|
                  |
                ALIAS
    r            N)__name__
__module____qualname____doc__PACKAGEMODULE	ATTRIBUTEALIAS r:   r:   (lib/python3.9/site-packages/isort/api.pyr   +   s
   r   F)code	extensionconfig	file_pathdisregard_skip	show_diffconfig_kwargsreturnc           	   	   K   sJ   t | }t  }tf ||d|}t|||||||d |d | S )a  Sorts any imports within the provided code string, returning a new string with them sorted.

    - **code**: The string of code with imports that need to be sorted.
    - **extension**: The file extension that contains imports. Defaults to filename extension or py.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
    - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
    TextIO stream is provided results will be written to it, otherwise no diff will be computed.
    - ****config_kwargs**: Any config modifications.
    pathr>   )r=   r>   r?   r@   rA   r   )r   _configr   seekread)	r<   r=   r>   r?   r@   rA   rB   input_streamoutput_streamr:   r:   r;   r   E   s    	
r   )r<   rA   r=   r>   r?   r@   rB   rC   c                 K   s,   t f ||d|}tt| |||||dS )a2  Checks the order, format, and categorization of imports within the provided code string.
    Returns `True` if everything is correct, otherwise `False`.

    - **code**: The string of code with imports that need to be sorted.
    - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
    TextIO stream is provided results will be written to it, otherwise no diff will be computed.
    - **extension**: The file extension that contains imports. Defaults to filename extension or py.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
    - ****config_kwargs**: Any config modifications.
    rD   rA   r=   r>   r?   r@   )rF   r   r   )r<   rA   r=   r>   r?   r@   rB   r:   r:   r;   r   i   s    r   T)
rI   rJ   r=   r>   r?   r@   rA   raise_on_skiprB   rC   c              
   K   s  |p|r|j dpd}|rt }	t|  }
tf |
|	|||||d|}|	d |
d t|
 |	 ||du r||ntt||j	d |S t
f ||d|}t|pd}|s|r||rt||}|jrLz|  }t||d	dd
 W n> ty2   |tvrt|n|jr.t| d Y n0 t|} | sLt }ztj| ||||d}W n ty   t|Y n0 |jr|d z"t| |d	dd
 |d W n> ty   |tvrt|n|jrt| d Y n0 ||kr||  |S )a  Sorts any imports within the provided code stream, outputs to the provided output stream.
     Returns `True` if anything is modified from the original input stream, otherwise `False`.

    - **input_stream**: The stream of code with imports that need to be sorted.
    - **output_stream**: The stream where sorted imports should be written to.
    - **extension**: The file extension that contains imports. Defaults to filename extension or py.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
    - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
    TextIO stream is provided results will be written to it, otherwise no diff will be computed.
    - ****config_kwargs**: Any config modifications.
    .py)rI   rJ   r=   r>   r?   r@   rL   r   TZ
file_inputZfile_outputr?   outputcolor_outputrD   zPassed in contentexecr   z< Python AST errors found but ignored due to Cython extension)r=   r>   rL   )suffixlstripr   rH   r   rG   r'   r   r   rQ   rF   strZ
is_skippedr#   ZatomiccompileSyntaxErrorr,   r!   verboser   readabler   Zprocessr"   r$   write)rI   rJ   r=   r>   r?   r@   rA   rL   rB   Z_output_streamZ_input_streamchangedZcontent_sourceZ_internal_outputZfile_contentr:   r:   r;   r      s    












r   )rI   rA   r=   r>   r?   r@   rB   rC   c                 K   s   t f ||d|}|r$t|  } t| t||||d}t|j|j|jd}|st|j	rp|j
sp||pfd d dS ||p~d d |rt }	| d |  }
tt|
|	||||d |	d t|
|	 ||du rd	ntt||jd
 dS )aE  Checks any imports within the provided code stream, returning `False` if any unsorted or
    incorrectly imports are found or `True` if no problems are identified.

    - **input_stream**: The stream of code with imports that need to be sorted.
    - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
    TextIO stream is provided results will be written to it, otherwise no diff will be computed.
    - **extension**: The file extension that contains imports. Defaults to filename extension or py.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
    - ****config_kwargs**: Any config modifications.
    rD   )rI   rJ   r=   r>   r?   r@   )Zcolorerrorsuccess z Everything Looks Good!Tz1 Imports are incorrectly sorted and/or formatted.r   NrO   F)rF   r   rH   r   r(   r&   rQ   Zformat_errorZformat_successrX   Zonly_modifiedr]   r\   rG   r'   r   r   )rI   rA   r=   r>   r?   r@   rB   r[   ZprinterrJ   Zfile_contentsr:   r:   r;   r      sP    

r   )filenamerA   r>   r?   r@   r=   rB   rC   c              	   K   sT   t j| 4}t|jf||||p$|j|d|W  d   S 1 sF0    Y  dS )a)  Checks any imports within the provided file, returning `False` if any unsorted or
    incorrectly imports are found or `True` if no problems are identified.

    - **filename**: The name or Path of the file to check.
    - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
    TextIO stream is provided results will be written to it, otherwise no diff will be computed.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
    - **extension**: The file extension that contains imports. Defaults to filename extension or py.
    - ****config_kwargs**: Any config modifications.
    rK   N)r    r)   rH   r   streamrE   )r_   rA   r>   r?   r@   r=   rB   source_filer:   r:   r;   r   1  s    r   )ra   rC   c                 C   s   | j | j jd S )Nz.isorted)rE   with_suffixrS   )ra   r:   r:   r;   	_tmp_fileR  s    rc   )rC   c                   c   s   t d dV  d S )N)newliner   r:   r:   r:   r;    _in_memory_output_stream_contextV  s    re   )r_   ra   rC   c                 c   sP   t |}|jd|jdd"}t| | |V  W d    n1 sB0    Y  d S )Nzw+r^   )encodingrd   )rc   openrf   shutilcopymode)r_   ra   tmp_filerJ   r:   r:   r;   _file_output_stream_context[  s    rk   )r_   r=   r>   r?   r@   ask_to_applyrA   write_to_stdoutrP   rB   rC   c	                 K   s\  t j| 8}
|p|
j}tf ||d|	}d}z|rVt|
jtj||||d}n|du rzz|j	rrt
 }n
t| |
}|@}t|
j|||||d}|d |r|s|r^|
jd t|
j | ||du rdntt||jd |s|r^tt|
js^W d   W z|j	s4t|
}|  W n tyJ   Y n0 W W d   dS |
j  |j	r|d |
jd}t|| W d   n1 s0    Y  W d   n1 s0    Y  |r|j	st|
}||
j |jstd	|
j  W z|j	s*t|
}|  W n ty@   Y n0 n4z|j	s^t|
}|  W n tyt   Y n0 0 ntt|
j|||||d}|r|r|
jd |d t|
j | ||du rdntt||jd |
j  W nB ty   t| d
 Y n" ty2   t| d Y n0 |W  d   S 1 sN0    Y  dS )a:  Sorts and formats any groups of imports imports within the provided file or Path.
     Returns `True` if the file has been changed, otherwise `False`.

    - **filename**: The name or Path of the file to format.
    - **extension**: The file extension that contains imports. Defaults to filename extension or py.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
    - **ask_to_apply**: If `True`, prompt before applying any changes.
    - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
    TextIO stream is provided results will be written to it, otherwise no diff will be computed.
    - **write_to_stdout**: If `True`, write to stdout instead of the input file.
    - **output**: If a TextIO is provided, results will be written there rather than replacing
    the original file content.
    - ****config_kwargs**: Any config modifications.
    rD   F)rI   rJ   r>   r?   r@   r=   Nr   TrO   wzFixing z- unable to sort due to existing syntax errorsz5 unable to sort as isort introduces new syntax errors) r    r)   rH   rE   rF   r   r`   sysstdoutZoverwrite_in_placere   rk   rG   r'   r   r   rQ   r%   rU   rc   unlinkFileNotFoundErrorcloserg   rh   copyfileobjreplacequietprintr!   r   r$   )r_   r=   r>   r?   r@   rl   rA   rm   rP   rB   ra   Zactual_file_pathr[   Zoutput_stream_contextrJ   rj   Zfsr:   r:   r;   r   c  s    

	


	

L

r   )r<   r>   r?   uniquetop_onlyrB   rC   c                 k   s(   t f t| ||||d|E dH  dS )a  Finds and returns all imports within the provided code string.

    - **code**: The string of code with imports that need to be sorted.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **unique**: If True, only the first instance of an import is returned.
    - **top_only**: If True, only return imports that occur before the first function or class.
    - ****config_kwargs**: Any config modifications.
    rI   r>   r?   rx   ry   N)r   r   )r<   r>   r?   rx   ry   rB   r:   r:   r;   r     s    r   )rI   r>   r?   rx   ry   _seenrB   rC   c                 k   s   t f d|i|}tj| |||d}|s2|E dH  |du r@t n|}|D ]}	|dtjfv rd|	 }
nJ|tjkr|	j d|	j	 }
n,|tj
kr|	j}
n|tjkr|	jdd }
|
rH|
|vrH||
 |	V  qHdS )af  Finds and returns all imports within the provided code stream.

    - **input_stream**: The stream of code with imports that need to be sorted.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **unique**: If True, only the first instance of an import is returned.
    - **top_only**: If True, only return imports that occur before the first function or class.
    - **_seen**: An optional set of imports already seen. Generally meant only for internal use.
    - ****config_kwargs**: Any config modifications.
    r>   )r>   r?   ry   NTrM   r   )rF   r   Zimportssetr   r9   Z	statementr8   r*   Z	attributer7   r6   splitadd)rI   r>   r?   rx   ry   r{   rB   Zidentified_importsseenZidentified_importkeyr:   r:   r;   r     s&    





r   )r_   r>   r?   rx   ry   rB   rC   c              	   k   sX   t j| 8}tf |j||p |j||d|E dH  W d   n1 sJ0    Y  dS )ac  Finds and returns all imports within the provided source file.

    - **filename**: The name or Path of the file to look for imports in.
    - **extension**: The file extension that contains imports. Defaults to filename extension or py.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **unique**: If True, only the first instance of an import is returned.
    - **top_only**: If True, only return imports that occur before the first function or class.
    - ****config_kwargs**: Any config modifications.
    rz   N)r    r)   rH   r   r`   rE   )r_   r>   r?   rx   ry   rB   ra   r:   r:   r;   r   '  s    r   )pathsr>   r?   rx   ry   rB   rC   c                 +   sX   t f d i| rt ndt fddttt|  g g D  E dH  dS )aj  Finds and returns all imports within the provided source paths.

    - **paths**: A collection of paths to recursively look for imports within.
    - **extension**: The file extension that contains imports. Defaults to filename extension or py.
    - **config**: The config object to use when sorting imports.
    - **file_path**: The disk location where the code string was pulled from.
    - **unique**: If True, only the first instance of an import is returned.
    - **top_only**: If True, only return imports that occur before the first function or class.
    - ****config_kwargs**: Any config modifications.
    r>   Nc                 3   s    | ]}t | d V  qdS ))rx   r>   ry   r{   N)r   ).0	file_namer>   r   ry   rx   r:   r;   	<genexpr>Y  s   
z(find_imports_in_paths.<locals>.<genexpr>)rF   r|   r   r   findmaprU   )r   r>   r?   rx   ry   rB   r:   r   r;   r   D  s    r   )rE   r>   rB   rC   c                 K   sJ   | r$|t u r$d|vr$d|vr$| |d< |rF|t ur8tdtf i |}|S )NZsettings_pathZsettings_fileziYou can either specify custom configuration options using kwargs or passing in a Config object. Not Both!)r-   
ValueErrorr.   )rE   r>   rB   r:   r:   r;   rF   b  s    rF   )B__all__
contextlibrh   ro   enumr   r    r   	itertoolsr   pathlibr   typingr   r   r   r   r   r   r   warningsr   Zisortr   r^   r   r   
exceptionsr!   r"   r#   r$   formatr%   r&   r'   r(   r)   Zplacer*   r	   r+   r
   Zsettingsr,   r-   r.   r   rU   boolr   r   r   r   r   rc   contextmanagerre   rk   r   ZImportr   r   r   r   rF   r:   r:   r:   r;   <module>   sl  $
&
#
g
E

! 	

 


,



