
    דiCA                     *   S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SKr	S SK
JrJrJr  S SKJrJrJrJr  S SKJr  S SKJrJrJrJrJrJrJrJrJrJr  S SK J!r!J"r"J#r#J$r$J%r%  S SK&J'r'J(r(J)r)J*r*  S SK+J,r,J-r-  \R\                  S	:H  r/\R`                  " \15      r2S
r3S r4S r5 " S S\5      r6S r7S r8S$S jr9S r:S r;S r<S%S jr=\==r>=r?r@S rAS rB " S S5      rC\ R                  S 5       rES rF S&S jrGS rHS'S jrIS rJS  rKS(S! jrLS(S" jrMS# rNg))    N)ExecutorProcessPoolExecutorThreadPoolExecutor)EACCESENOENTEPERMEROFS)chain)
abspathbasenamedirnameisdirisfileislinkjoinlexistsnormpathsplit)S_IEXECS_IMODES_ISDIRS_ISREGS_IWRITE)STDOUTCalledProcessErrorcheck_outputlist2cmdline)NamedTemporaryFilemkdtempwin32z.c~c                     SSK Jn  U" U 5      $ )Nr   )find_executable)distutils.spawnr"   )
executabler"   s     <lib/python3.13/site-packages/conda_package_handling/utils.pywhichr&   "   s    /:&&    c                     [         R                  " U 5      R                  n[        U5      (       a/  [         R                  " U [        U5      [        -  [        -  5        g[        U5      (       d  [        U 5      (       a(  [         R                  " U [        U5      [        -  5        g[        R                  SU 5        g! [         a{  n[        USS 5      nU[        4;   a  [        R                  SU 5        e U[        [         ["        4;   a  [        R                  SX5         S nAg[        R%                  SX5        e S nAff = f)Nz path cannot be made writable: %sTerrnoz,tried to make writable, but didn't exist: %sz%tried make writable but failed: %s
%rFz!Error making path writable: %s
%r)oslstatst_moder   chmodr   r   r   r   r   logdebug	Exceptiongetattrr   r   r   r	   warn)pathmodeeenos       r%   make_writabler7   (   s    xx~%%4==HHT74=83g=>
 	 T]]fTllHHT74=834  II8$? 
a$'6)IIDdKVUE**II>HHH94C
s,   AC  !AC  )C   
E
AE )E  Ec                       \ rS rSrS rSrg)DummyExecutor?   c              '   D   #    U H  nU H  nU" U5      v   M     M     g 7fN )selffunc	iterablesiterablethings        r%   mapDummyExecutor.map@   s#     !H!5k! " "s    r=   N)__name__
__module____qualname____firstlineno__rC   __static_attributes__r=   r'   r%   r9   r9   ?   s    "r'   r9   c                 4    U S:X  a
  [        5       $ [        U S9$ )N   max_workers)r9   r   )	processess    r%   get_executorrO   F   s    '1n=?\2ER[2\\r'   c                    [        U 5      (       aT  [        R                  " U 5       H9  u  pn[        R                  " X245       H  n  [        [        X5      5        M     M;     g  [        U 5        g !    M3  = f!    g = fr<   )r   r*   walkr
   from_iterabler7   r   )r3   rootdirsfiless       r%   recursive_make_writablerV   J   sm     T{{!#D++UM:!$t"23 ; "/	$		s   A2&A: 2A7:A>c                   ^ U(       d  [         (       a  SOSnUS:X  a  [        U 5      $ / nU  HK  mST;   a  SnO(ST;   a  SnO[        U4S jS 5       5      (       d  SnOSnUR                  UT-   U-   5        MM     SR	                  U5      $ )	Ncmd.exebash"'c              3   ,   >#    U  H	  oT;   v   M     g 7fr<   r=   ).0_args     r%   	<genexpr>"quote_for_shell.<locals>.<genexpr>n   s     7;ac;s   ) 
 rb   )on_winr   anyappendr   )	argumentsshellquotedquoter_   s       @r%   quote_for_shellrl   \   s    #V		I&&  Ccz7;777MM%#+-.  xxr'   c           
         [        U 5      n [        (       a   [        SU  S3S[        S9nO [        R"                  " S5        [%        S5      nU(       a^  ['        S5      (       aN   [        USSS[)        [        R*                  " 5       S5      S-   U S-   /[        S9n[,        R.                  " S5        [,        R.                  " U 5        g !    S n[	        SSS9 nUR                  S[        U /5       S	35        UR                  S
5        UR                  S[        U /5       S	35        UR                  S5        UR                  nS S S 5        O! , (       d  f       O= f[        U5       nUR                  5       nX;   d   e S S S 5        O! , (       d  f       O= f[        R                  S   nSn	[        USSU/SS S S U	S9n GN! [         aP  n
U
R                  S:w  a  [        R                  SU  SW 35        e [        R!                  SW 35         S n
A
 GNjS n
A
ff = f= f!    GN= f! [         a    [        R!                  SW 35         GNf = f)Nz
RD /S /Q "z" > NUL 2> NULT)ri   stderr.batF)suffixdeletezRD /S rc   zchcp 65001
zEXIT 0
COMSPECi   z/dz/c)ri   stdoutrn   stdincreationflags   zRemoving folder z# the fast way failed.  Output was: z8removing dir contents the fast way failed.  Output was: z.emptyrsyncz-az--forcez--delete/rn   )r   re   r   r   r   writerl   nameopenreadr*   environr   
returncoder.   errorr/   makedirsr&   r   r   getcwdshutilrmtree)r3   argskwargsoutr{   
batch_filecontentscontentcomspecCREATE_NO_WINDOWr5   rw   s               r%   r   r   v   s4   D>Dv.	` D6@U[\CL	KK! gU8__\"!"RYY[(3c9s
 "
 MM(#
MM${#	`"`'veD
$$votf.E-Fb%IJ$$^4$$votf.E-Fb%IJ$$Z0%??D EDD $Z8&mmoG?*?  ZZ **Y/#-  #dD$/"2 & `<<1$II 06YZ]Y^_`II XY\X]^__`	$ & \		TUXTYZ[\s~   C
 H( &7H0 
H%GA-E	G
E	G+F	G
F	.G
H"AHH%H""H%(H-0"IIc                 h    [        U 5        [        R                  " U 5        g! [         Ga     [        R                  " X S-   5         g! [         GaW    [
        (       Ga#  [        SS9 n[        US5       nUR                  S5        UR                  S5        UR                  S5        SSS5        O! , (       d  f       O= f[        U 5      u  p4U S-   nS	n[        U5      (       a,  UR                  S
   SU 3-   nUS	-  n[        U5      (       a  M,  Sn [        SSUUU[        U5      /[        S9nO4! [         a'    [         R#                  SR%                  X5      5         Of = fSSS5        O! , (       d  f       O= f[         R#                  SR%                  U 5      5          gf = ff = f)zIf files are in use, especially on windows, we can't remove them.
The fallback path is to rename them (but keep their folder the same),
which maintains the file handle validity.  See comments at:
https://serverfault.com/a/503769
z.conda_trashro   )rp   wz@pushd "%1"
z@REM Rename src to destz@ren "%2" "%3" > NUL 2> NUL")NrK   r   z.conda_trash_z	< empty >rX   z/Cry   z6renaming file path {} to trash failed.  Output was: {}znCould not remove or rename {}.  Please remove this file manually (you may need to reboot to free file handles))r7   r*   unlinkOSErrorrenamere   r   r|   rz   r   r   splitextr   r   r   r   r.   r2   format)r3   trash_scriptf_dirname_fndest_fncounterr   s           r%   unlink_or_rename_to_trashr      s   -d
		$ *)	IId>12 '	v (v6,lC0A0 9: ?@ 100
 %*$KMH"^3GG //")"2"21"5-y8Q"Q1 !// &C* ) $ , ( # ( 1 $*
 . T[[ $3 766@ HH;;A6$<I'	*s   !$ F1A F-+E484B5	,	E45
C?AE4E4D76E47.E(	%E4'E(	(E4+	F-4
F>+F-)F1,F--F1c                     [        U 5      n[        U5      (       aa  [        R                  " U5      (       dE  [	        U5        [        U5      n[        U5      (       a  [        R                  " U5      (       d  MC  g g g g r<   )r   r   r*   listdirrmdir)r3   parent_paths     r%   remove_empty_parent_pathsr      sZ    $-K


RZZ%<%<kk* 

RZZ%<%<
%<
r'   c                    [        U 5         [        U 5      n [        U 5      (       a  [        U 5      (       d  [	        U 5        O2[        U 5      (       a  [        U 5        O[        R                  SU 5        [        U 5      (       a  [        R                  SU 5        g [        U 5      (       a  [        U 5        U(       a  [        U 5        g! [        U 5      (       a  [        R                  SU 5           gf = f)z
Completely delete path
max_retries is the number of times to retry on failure. The default is 5. This only applies
to deleting a directory.
If removing path fails and trash is True, files will be moved to the trash directory.
z0rm_rf failed. Not a link, file, or directory: %szrm_rf failed for %sFT)rV   r   r   r   r   r   r   r.   r/   infodelete_trashr   )r3   clean_empty_parentsr   kws       r%   rm_rfr     s     D!t};;vd||$KT]]%d+IIH$O4==HH*D1  T{{T!$' 4==HH*D1 s   A)C (C76C7c           	         U (       d  [         R                  n S1n[        R                  " U SS9 H  u  p#nU Vs/ s H  oUU;  d  M
  UPM     snUS S & U Hq  n[        R                  " US5      (       d%  [        R                  " US[
        -   5      (       d  MD  [        X&5      n [        R                  " U5        [        U5        Ms     M     g s  snf ! [         a,  n[        R                  SXR                  U5         S nAM  S nAff = f)NenvsTtopdownz*.conda_trash**z%r errno %d
Cannot unlink %s.)sysprefixr*   rQ   fnmatchCONDA_TEMP_EXTENSIONr   r   r   r   r.   r/   r)   )	r   excluderS   rT   rU   dfnfilenamer5   s	            r%   r   r   "  s    hGWWVT:E"7dw&61d7QBr#344C..9 9  >VIIh'-h7  ;7  VII>77HUUVs#   	CC%!C
D
!DD
c                     [        U 5      (       d  g  [        U 5        [        R                  " U SS9 H#  u  pnU H  n[	        [        X5      5        M     M%     g !    NA= f)NFr   )r   r   r*   rQ   r   r   )dirpathrS   rT   rU   r   s        r%   r   r   4  sV    >>w  WWWe<EA%d4m4  =s   A Ac                   t    \ rS rSrSrSrSrSS\R                  " 5       4S jr	S r
S	 rS\4S
 jrS rS rSrg)TemporaryDirectoryiD  a  Create and return a temporary directory.  This has the same
behavior as mkdtemp but can be used as a context manager.  For
example:

    with TemporaryDirectory() as tmpdir:
        ...

Upon exiting the context, the directory and everything contained
in it are removed.
NFrd   z.cph_tmpc                 &    [        XU5      U l        g r<   )r   r{   )r>   rp   r   dirs       r%   __init__TemporaryDirectory.__init__T  s    FC0	r'   c                 R    SU R                   R                   SU R                  < S3$ )N<rb   >)	__class__rE   r{   r>   s    r%   __repr__TemporaryDirectory.__repr__W  s&    4>>**+1TYYM;;r'   c                     U R                   $ r<   )r{   r   s    r%   	__enter__TemporaryDirectory.__enter__Z  s    yyr'   c                 H   U R                   (       ak  U R                  (       dY   [        U R                   5        SU l        U(       a4  UR                  (       a"  UR                  " SU < 3UR                  5        g g g g g !   UR                  " SU R                   -  5         Nh= f)NzConda-package-handling says: "I tried to clean up, but I could not.  There is a mess in %s that you might want to clean up yourself.  Sorry..."TzImplicitly cleaning up )r{   _closedr   r2   ResourceWarning)r>   _warn	_warningss      r%   cleanupTemporaryDirectory.cleanup]  s    99T\\dii   DL-dX6-- (u *9<>BiiHs   A> >!B!c                 $    U R                  5         g r<   r   )r>   excvaluetbs       r%   __exit__TemporaryDirectory.__exit__n  s    r'   c                 "    U R                  SS9  g )NT)r   r   r   s    r%   __del__TemporaryDirectory.__del__q  s    4 r'   )r   r{   )rE   rF   rG   rH   __doc__r{   r   r*   r   r   r   r   r   r   r   r   rI   r=   r'   r%   r   r   D  sE    	 DG  1< "Y "!r'   r   c              #      #    [         R                  " 5       n [         R                  " U 5        S v   [         R                  " U5        g ! [         R                  " U5        f = f7fr<   )r*   r   chdir)destcurdirs     r%   	tmp_chdirr   v  s;     YY[F

s   A%A
 A%
A""A%c                 f    [        U [        5      (       d  [        U S5      (       d
  U b  U /n U $ / n U $ )N__iter__)
isinstancestrhasattr)r_   s    r%   ensure_listr     s:    #s73
#;#;?%C J CJr'   c           	         U HD  n[         R                  " U5      n[        U 5      [        [        UR                  U 5      5      -
  n MF     U  Vs/ s H  n[
        R                  R                  [
        R                  R                  X5      5      (       dC  [
        R                  R                  [
        R                  R                  X5      5      (       a  M  UPM     sn$ s  snf )zIRemove things like the .git directory from the list of files to be copied)
recompilesetfiltermatchr*   r3   r   r   r   )
files_listr   filter_patternspatternrr   s         r%   filter_filesr     s     #JJw_s6!'':+F'GG
 #
 A 	rww||F.//rww}}RWW\\RXE\7]	 	
  s   BC"C"c                     [        U USS9$ )N)zinfo[\\/]index\.jsonzinfo[\\/]fileszinfo[\\/]paths\.jsonzinfo[\\/]about\.jsonzinfo[\\/]has_prefixzinfo[\\/]hash_input_fileszinfo[\\/]hash_input\.jsonzinfo[\\/]run_exports\.yamlzinfo[\\/]run_exports\.jsonzinfo[\\/]gitzinfo[\\/]recipe[\\/].*zinfo[\\/]recipe_log.jsonzinfo[\\/]recipe.tarzinfo[\\/]test[\\/].*zinfo[\\/]LICENSE.*zinfo[\\/]requireszinfo[\\/]metazinfo[\\/]platformzinfo[\\/]no_linkzinfo[\\/]link\.jsonzinfo[\\/]icon\.png)r   )r   )r   r   s     r%   filter_info_filesr     s    
 r'   c                    ^ ^ [        [        U5      nU(       d  [        SU 35      eU" 5       n[        UU 4S jS5       H  nUR	                  U5        M     UR                  5       $ )NzUnrecognized hash algorithm: c                  &   > TR                  T 5      $ r<   )r}   )
buffersizefds   r%   <lambda>_checksum.<locals>.<lambda>  s    bggj1r'   r'   )r1   hashlib
ValueErroriterupdate	hexdigest)r   	algorithmr   	hash_implblocks   ` `  r%   	_checksumr     s[    +I8DEEK	137 8  r'   c                     [        U S5      $ )Nsha256r   r   s    r%   sha256_checksumr    s    R""r'   c                     [        U S5      $ )Nmd5r   r  s    r%   md5_checksumr    s    Rr'   c                 h    [        U S5       n[        X1U5      sSSS5        $ ! , (       d  f       g= f)z9
Calculate a checksum for a filename (not an open file).
rbN)r|   r   )r   r   r   r   s       r%   checksumr    s#     
b$2
3 
s   #
1c           
          [        [        U5      S9 nU Vs/ s H  oCR                  [        XU5      PM     nnSSS5        W Vs/ s H  ofR	                  5       PM     sn$ s  snf ! , (       d  f       N3= fs  snf )z:
Calculate multiple checksums for a filename in parallel.
rL   N)r   lensubmitr  result)r   
algorithmsr   r5   r   resultsr  s          r%   	checksumsr    sf     
J	8AR\]R\Y88HbZ@R\] 
9 +22'MMO'22 ^ 
9	8 3s!   A' A"A'A8"A''
A5c                 >    SU l         SU l        SU l        SU l        U $ )z$
Remove user id, name from tarinfo.
r   rd   )uidunamegidgname)tarinfos    r%   anonymize_tarinfor    s%    
 GKGMGKGMNr'   r<   )F))z(.*[\\\\/])?\.git[\\\\/].*z(.*[\\\\/])?\.git$z(.*)?\.DS_Store.*z.*\.la$zconda-meta.*)i   )i   )O
contextlibr   r   loggingr*   r   r   r   warningsr   concurrent.futuresr   r   r   r)   r   r   r   r	   	itertoolsr
   os.pathr   r   r   r   r   r   r   r   r   r   statr   r   r   r   r   
subprocessr   r   r   r   tempfiler   r   platformre   	getLoggerrE   r.   r   r&   r7   r9   rO   rV   rl   r   r   r   r   try_rmdir_all_emptymove_to_trashmove_path_to_trashr   r   r   contextmanagerr   r   r   r   r   r  r  r  r  r  r=   r'   r%   <module>r&     s&       	 	  
  P P . .    > = M M 0		 ! '."H "]$ 4L^3l+8 <A @  @m&8V$5 /! /!d  0<!# 43	r'   