
    si                        S r SSKJ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rSSKrSSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJrJr  SSKJr  SSKJr  SSK J!r!J"r"  SSK#J$r$  SSK%J&r&J'r'J(r(J)r)J*r*J+r+  SSK,J-r-  SSK.J/r/J0r0J1r1J2r2J3r3J4r4J5r5  SSK6J7r7  SSK8J9r9  SSK:J;r;  \(       a  SSK	J<r<  SSKJ=r=  SSK.J>r>  \R~                  " \@5      rA\R~                  " S5      rB\R                  " SS9rDSrESrFSrGS rHS!rIS"rJ " S# S$\+5      rK " S% S&\L5      rM " S' S(\R                  5      rO " S) S*\L5      rPS:S+ jrQ " S, S-\O5      rRS. rS\S/ 5       rT " S0 S1\5      rU " S2 S35      rV " S4 S55      rWS6 rX\4S7 jrYS;S8 jrZS9 r[g)<zRepodata interface.    )annotationsN)UserDict)contextmanager)dirname)TYPE_CHECKING   )
CondaError)	stringify)CONDA_HOMEPAGE_URLREPODATA_FN)context)json)join_urlmaybe_unquote)PackageCacheData)CondaDependencyErrorCondaHTTPErrorCondaSSLErrorNotWritableError
ProxyErrorUnavailableInvalidChannel)Channel   )ChunkedEncodingErrorConnectionError	HTTPErrorInsecureRequestWarningInvalidSchemaRequestsProxyErrorSSLError)get_session)mkdir_p_sudo_safe)lock)Path)Any)Responsezconda.stderrlog   )daysmodetagcache_controlurlz
.info.json    c                      \ rS rSrSrSrg)RepodataIsEmptyK   z
Subclass used to determine when empty repodata should be cached, e.g. for a
channel that doesn't provide current_repodata.json
 N__name__
__module____qualname____firstlineno____doc____static_attributes__r1       @lib/python3.13/site-packages/conda/gateways/repodata/__init__.pyr/   r/   K       r9   r/   c                      \ rS rSrSrSrg)RepodataOnDiskR   zl
Indicate that RepoInterface.repodata() successfully wrote repodata to disk,
instead of returning a string.
r1   Nr2   r1   r9   r:   r=   r=   R   r;   r9   r=   c                      \ rS rSrSS jrSrg)RepoInterfaceY   c                    g)z
Given a mutable state dictionary with information about the cache,
return repodata.json (or current_repodata.json) as a str. This function
also updates state, which is expected to be saved by the caller.
Nr1   )selfstates     r:   repodataRepoInterface.repodataZ   s     	r9   r1   N)rD   dictreturnstr)r3   r4   r5   r6   rE   r8   r1   r9   r:   r@   r@   Y   s    r9   r@   c                      \ rS rSrSrg)Response304ContentUnchangedc   r1   N)r3   r4   r5   r6   r8   r1   r9   r:   rK   rK   c   s    r9   rK   c                    S[         R                  ;   a	   SSKJn   U $ [         R                  (       a	   SSKJn  U$ [        $ ! [         a#  n[
        R                  " SU 35         S nANLS nAff = f! [         a     [        $ f = f)Njlap   )JlapRepoInterfacezaCould not load the configured jlap repo interface. Is the required jsonpatch package installed?  )ZstdRepoInterface)
r   experimentaljlap.interfacerP   ImportErrorwarningswarnrepodata_use_zstrQ   CondaRepoInterface)rP   erQ   s      r:   get_repo_interfacerZ   g   s    %%%	9$$ 	9$$   	MMAABE 	  		s(   A A2 
A/A**A/2
BBc                  F    \ rS rSr% SrS\S'    S\S'    S
S jrSS jrSrg	)rX   ~   zAProvides an interface for retrieving repodata data from channels.rI   _url_repodata_fnc                b    [         R                  S5        Xl        U=(       d    [        U l        g )NzUsing CondaRepoInterface)logdebugr]   r   r^   )rC   r,   repodata_fnkwargss       r:   __init__CondaRepoInterface.__init__   s!    		,-	'6;r9   c                   [         R                  (       d  [        R                  " S[        5        [        U R                  5      n0 nUR                  nUR                  nU(       a  [        U5      US'   U(       a  [        U5      US'   U R                  n[        U R                  U5      n[        U R                  U5         [         R                  [         R                  4nUR                  XsUR                   US9n	["        R%                  [&        R(                  5      (       a  ["        R+                  [-        U	SS95        U	R/                  5         S S S 5        W	R0                  S:X  a
  [3        5       eU	R4                  n
SU R                  0n[7        U	S	US
5        [7        U	SUS5        [7        U	SUS5        UR9                  5         UR;                  U5        U
$ ! , (       d  f       N= f)NignorezIf-None-MatchzIf-Modified-Since)headersproxiestimeout   )content_max_leni0  r]   Etag_etagzLast-Modified_modzCache-Control_cache_control)r   
ssl_verifyrU   simplefilterr   r!   r]   r*   r)   rI   r^   r   conda_http_errorsremote_connect_timeout_secsremote_read_timeout_secsgetri   r`   isEnabledForloggingDEBUGra   r
   raise_for_statusstatus_coderK   text_add_http_value_to_dictclearupdate)rC   rD   sessionrh   r*   last_modifiedfilenamer,   rj   responsejson_strsaved_fieldss               r:   rE   CondaRepoInterface.repodata   s   !!!!(,BCdii(zz		'*4yGO$+.}+=G'($$tyy(+tyy(33300G ")goow "- "H ..		)HcBC%%' 4 3& .//== 		*&,H/<Po|5E	
 	\"? 43s   BG
G*)r^   r]   N)r,   rI   rb   
str | NonerH   None)rD   RepodataStaterH   r   )	r3   r4   r5   r6   r7   __annotations__rd   rE   r8   r1   r9   r:   rX   rX   ~   s     K
I_7
0r9   rX   c                R    U R                   R                  U5      nU(       a  XBU'   g g N)rh   rv   )resphttp_keyddict_keyvalues        r:   r}   r}      s%    LLX&E( r9   c              #    #     Sv   g! [          a    [        5       e[         a"  nS[        U5      ;   a  Sn[	        U5      ee SnAf[
         a6  n SSKn[        SU S35      e! [         a    [        SU S35      ef = fSnAf[        [        [        4 Ga  n[        UR                  SS5      nUS	:X  a  U R                  S
5      (       dD  [        R!                  SUU S-   U-   5        [#        [%        ['        U 5      5      UUR                  S9e[(        R*                  (       aD  [,        R/                  SUU S-   U-   5        [#        [%        ['        U 5      5      UUR                  S9e[1        [%        ['        U 5      5      UUR                  S9eUS:X  a  [%        U 5      nUR2                  (       a!  SR5                  [7        [8        S5      5      nGO\[(        R:                  R<                  U ;   a!  SR5                  [7        [8        S5      5      nGOSR5                  [7        [8        S5      5      nOUS:X  a  [%        U 5      nUR2                  (       a   SR5                  [7        [8        S5      5      nO[(        R:                  R<                  U ;   a   SR5                  [7        [8        S5      5      nO}SR5                  [7        [8        S5      5      nO]Ub  SUs=::  a  S:  a  O  OSnOGU R?                  S5      (       a  S[A        [C        U 5      5       S3nOS[A        [C        U 5      5       S3n[E        U[7        X5      U[        UR                  SS5      [        UR                  SS5      UR                  US9eSnAff = f7f) zHUse in a with: statement to translate requests exceptions to conda ones.NSOCKSa   Requests has identified that your current working environment is configured
to use a SOCKS proxy, but pysocks is not installed.  To proceed, remove your
proxy configuration, run `conda install pysocks`, and then you can re-enable
your proxy configuration.
r   zTEncountered an SSL error. Most likely a certificate verification issue.

Exception: 
zuOpenSSL appears to be unavailable on this machine. OpenSSL is required to
download and install packages.

Exception: r{   i  z/noarchz1Unable to retrieve repodata (response: %d) for %s/)r   i  aK  The token given for the URL has insufficient permissions to access this resource.

You may not have the required permissions to access this channel or package.
Consider requesting access from the channel owner.

Use `conda config --show` to view your configuration's current state.
Further configuration help can be found at <{}>.
zdocs/config.htmla  The remote server has indicated you do not have permission to access this resource.

This may mean:
  (a) You are not authenticated. Check if authentication is required for this channel
      and verify your credentials are correctly configured.
  (b) You do not have access to this private channel or package. Contact the
      channel owner to request access.

Further configuration help can be found at <{}>.
a}  You do not have permission to access this resource.

This may indicate:
  - The channel requires authentication. Check your credentials.
  - You do not have access to this private channel or package.

You will need to modify your conda configuration to proceed.
Use `conda config --show` to view your configuration's current state.
Further configuration help can be found at <{}>.
i  zThe token given for the URL is invalid.

You will need to adjust your conda configuration to proceed.

Use `conda config --show` to view your configuration's current state.
Further configuration help can be found at <{}>.
a  The remote server has indicated you are using invalid credentials for this channel.

You may need to:
  (a) Remove or update the invalid token from your configuration, or
  (b) Provide conda with a valid token directly.

Further configuration help can be found at <{}>.
zThe credentials you have provided for this URL are invalid.

You will need to modify your conda configuration to proceed.
Use `conda config --show` to view your configuration's current state.
Further configuration help can be found at <{}>.
i  iX  aR  A remote server error occurred when trying to retrieve this URL.

A 500-type error (e.g. 500, 501, 502, 503, etc.) indicates the server failed to
fulfill a valid request.  The problem may be spurious, and will resolve itself if you
try your request again.  If the problem persists, consider notifying the maintainer
of the remote server.
zhttps://repo.anaconda.com/a  An HTTP error occurred when trying to retrieve this URL.
HTTP errors are often intermittent, and a simple retry will get you on your way.

If your current network has https://repo.anaconda.com blocked, please file
a support request with your network engineering team.

zAn HTTP error occurred when trying to retrieve this URL.
HTTP errors are often intermittent, and a simple retry will get you on your way.
reasonelapsed	caused_by)#r   r   r   rI   r   r    sslr   rT   r   r   r   getattrr   endswithr`   infor/   r   r   r   allow_non_channel_urls	stderrlogwarningr   tokenformatr   r   channel_aliaslocation
startswithr   reprr   )r,   rb   rY   messager   r{   channelhelp_messages           r:   rs   rs      s    t
 l 
c!fG 'w// 	   3    	 3 	 	$ Y(<= M
ajj->#<<	**G#I+
 &GCL)ZZ  11%%K#c	K/
 *-#!"  4-#!"  CclG}}  F8&(:;<  &&//36
  F8&(:;< 
  F8&(:;<  CclG}}  F8&(:;<  &&//36  F8&(:;<   F8&(:;<  $)Ac)AL ~~:;;$ tCy   $ tCy    S&AJJ$/AJJ	40JJ
 	
KM
sO   N	 NNANA$B$A>>BNK"M<<NNc                  X  ^  \ rS rSrSr\\\\S.r	1 Skr
    S   SU 4S jjjr\SS j5       r\R                  S 5       r\SS j5       r\R                  S	 5       r\SS
 j5       r\R                  S 5       rSS jrSS jrSS jrSS jrSU 4S jjrSU 4S jjrSU 4S jjrSrU =r$ )r   i  z<Load/save info file that accompanies cached `repodata.json`.)ro   rn   rp   r]   >   r)   r,   r*   r+   c                   > [         TU ]  U5        [        R                  " U5      U l        [        R                  " U5      U l        X0l        g r   )superrd   pathlibr$   cache_path_jsoncache_path_staterb   )rC   r   r   rb   rG   	__class__s        r:   rd   RepodataState.__init__  s;     	&||O< '-= >&r9   c                >    U R                  [        5      =(       d    S$ )z
Last-Modified header or ""
 )rv   LAST_MODIFIED_KEYrC   s    r:   r)   RepodataState.mod      
 xx)*0b0r9   c                (    U=(       d    SU [         '   g Nr   )r   rC   r   s     r:   r)   r         "'+2r9   c                >    U R                  [        5      =(       d    S$ )z
Etag header or ""
r   )rv   ETAG_KEYr   s    r:   r*   RepodataState.etag  s    
 xx!'R'r9   c                (    U=(       d    SU [         '   g r   )r   r   s     r:   r*   r     s    "Xr9   c                >    U R                  [        5      =(       d    S$ )z
Cache-Control header or ""
r   )rv   CACHE_CONTROL_KEYr   s    r:   r+   RepodataState.cache_control  r   r9   c                (    U=(       d    SU [         '   g r   )r   r   s     r:   r+   r     r   r9   c                   SU 3nX ;  a  g X   nUS   nUR                  S5      (       a  US S  S3n[        R                  R                  U5      n[        US   5      nXe4$ ! [        [
        [        4 a7  n[        R                  S[         S	3US
9  U R                  U5         S nAOS nAff = fS[        R                  R                  [        R                  R                  S94$ )Nhas_)TNlast_checkedZ+00:00r   z-error parsing `has_` object from `<cache key>`)exc_infoFtz)r   datetimefromisoformatboolKeyError
ValueError	TypeErrorr`   r   CACHE_STATE_SUFFIXpopnowtimezoneutc)rC   r   keyobjlast_checked_strr   r   rY   s           r:   
has_formatRepodataState.has_format  s     VHo?	)C">2((--&6s&;%<F#C #,,::;KLLW&E((*i0 	KK?@R?SSTU   HHSMM	 h''++x/@/@/D/D+EEEs   AA$ $B09-B++B0c                    SU 3n[         R                   R                  [         R                  R                  S9R	                  5       S [        S5      *  S-   US.X'   g )Nr   r   r   r   )r   r   )r   r   r   r   	isoformatlen)rC   r   r   r   s       r:   set_has_formatRepodataState.set_has_format  sa    VHo$--11X5F5F5J5J1KUUW 3x=.  
	r9   c                2    SU 3nU R                  US5        g)z2Remove 'has_{format}' instead of setting to False.r   N)r   )rC   r   r   s      r:   clear_has_formatRepodataState.clear_has_format  s    VHodr9   c                    U R                  U5      u  p#USL =(       d`    [        U[        R                  5      =(       a?    [        R                  R                  [        R                  R
                  S9U-
  [        :  $ )z0Return True if named format should be attempted.Tr   )r   
isinstancer   r   r   r   CHECK_ALTERNATE_FORMAT_INTERVAL)rC   r   haswhens       r:   should_check_format!RepodataState.should_check_format  sh    OOF+	4K .$ 1 12 .!!%%):):)>)>%?$F-.	
r9   c                X   > U R                   R                  X5      n[        TU ]  U5      $ r   )_aliasedrv   r   __contains__rC   r   r   s     r:   r   RepodataState.__contains__  s'    mm)w#C((r9   c                   > U R                   R                  X5      nXR                  ;   a-  [        U[        5      (       d  [
        R                  SU5        Sn[        TU ]!  X5      $ )Nz*Replaced non-str RepodataState[%s] with ""r   )	r   rv   _stringsr   rI   r`   ra   r   __setitem__)rC   r   itemr   s      r:   r   RepodataState.__setitem__  sQ    mm)--
4(=(=IIBCHDw"3--r9   c                X   > U R                   R                  X5      n[        TU ]  U5      $ r   )r   rv   r   __getitem__r   s     r:   r   RepodataState.__getitem__  s'    mm)w"3''r9   )r   r   rb   )r   r   r   N)r   
Path | strr   r   )rH   rI   )r   rI   rH   z%tuple[bool, datetime.datetime | None])r   rI   r   r   )r   rI   )r   rI   rH   r   )r   rI   rH   r   )r   rI   r   r%   rH   r   )r   rI   rH   r%   )r3   r4   r5   r6   r7   r   r   r   URL_KEYr   r   rd   propertyr)   setterr*   r+   r   r   r   r   r   r   r   r8   __classcell__)r   s   @r:   r   r     s    F "+	H 7H ')')'#' %' ' 1 1 	ZZ. . ( ( 
[[% % 1 1 . .F>


).( (r9   r   c                      \ rS rSrSrS r\S 5       r\S 5       r\S 5       r	SSS.SS	 jjr
SS
 jrSS jrSSS jjrSS jr\SS j5       rS rS rSrg)RepodataCachei  z
Handle caching for a single repodata.json + repodata.info.json
(<hex-string>*.json inside `dir`)

Avoid race conditions while loading, saving repodata.json and cache state.

Also support bytes as in repodata_shards.msgpack.zst
c                    [         R                  " U5      nUR                  U l        UR                  U l        X l        [        U R                  U R                  U5      U l	        g)zf
base: directory and filename prefix for cache, e.g. /cache/dir/abc123;
writes /cache/dir/abc123.json
N)
r   r$   parent	cache_dirnamerb   r   r   r   rD   )rC   baserb   cache_path_bases       r:   rd   RepodataCache.__init__  sQ    
 ",,t,(//#((	&"  $"7"7

r9   c                    [         R                  " U R                  U R                  [        R
                  (       a  SOS-   S-   5      $ )N1r   .jsonr   r$   r  r  r   use_only_tar_bz2r   s    r:   r   RepodataCache.cache_path_json  s5    ||NNII 8 8bAGK
 	
r9   c                    [         R                  " U R                  U R                  [        R
                  (       a  SOS-   S-   5      $ )Nr	  r   z.msgpack.zstr  r   s    r:   cache_path_shardsRepodataCache.cache_path_shards#  s5    ||NNII 8 8bANR
 	
r9   c                @    U R                   R                  [        5      $ )z=Out-of-band etag and other state needed by the RepoInterface.)r   with_suffixr   r   s    r:   r   RepodataCache.cache_path_state*  s     ##//0BCCr9   F
state_onlybinaryc                  U R                  S5       n[        R                  " UR                  5       5      nU(       a  U R                  OU R
                  nU(       a  U(       a  SOSnO(U(       a  UR                  5       nOUR                  5       nUR                  5       nUR                  S5      UR                  :X  a  UR                  S5      UR                  :X  d%  UR                  [        S[        S[        SSS05        U R                   R#                  5         U R                   R                  U5        S S S 5        U$ ! , (       d  f       W$ = f)Nzr+r9   r   mtime_nssizer   )r#   r   loadsreadr  r   
read_bytes	read_textstatrv   st_mtime_nsst_sizer   r   r   r   rD   r~   )rC   r  r  
state_filerD   
cache_path	json_data	json_stats           r:   loadRepodataCache.load/  s    YYt_
 JJz01E39//t?S?SJ #)Cr	 * 5 5 7I * 4 4 6I")I		*%)>)>>IIf%):)::  ")2)2	 JJJJe$C F G _F s   D'E
Ec                    U R                  SUS9  U R                  $ ! [        [        R                  4 a  n[	        U[        R                  5      (       a8  [
        R                  UR                  R                   SU R                   35        U R                  R                  5          SnAU R                  $ SnAff = f)zA
Update self.state without reading repodata.

Return self.state.
Tr  z	 loading N)r%  FileNotFoundErrorr   JSONDecodeErrorr   r`   r   r   r3   r   rD   r~   )rC   r  rY   s      r:   
load_stateRepodataCache.load_state\  s    	IIfI5
 zz	 "4#7#78 	!T1122q{{334Id>S>S=TUVJJzz		s    B>A1B99B>c                   U R                   U R                   S[        R                  " S5      R	                  5        S3-  n[        U[        5      (       a  SnU R                  nOSnU R                  n UR                  U5       nUR                  U5        SSS5        U R                  X$5       UR                  5         $ ! , (       d  f       N0= f! [         a     $ f = f!  UR                  5         f ! [         a     f f = f= f)z?Write data to <repodata> cache path, by calling self.replace()..r   z.tmpbxxN)r  r  osurandomhexr   bytesr  r   openwritereplaceunlinkOSError)rC   data	temp_pathmodetargettemps         r:   saveRepodataCache.savej  s    NN		{!BJJqM4E4E4G3H%MM	dE""D++FD))F
	%

4  & <<	2  " &%    " sZ   5C# CC# 1C
CC# 
C C #D%C65D6
D DDDNc                t   Uc  U R                   nU R                  5        nUR                  S5        UR                  5         UR	                  5       nUR
                  U R                  S'   UR                  U R                  S'   [        R                  " 5       U R                  S'    UR                  U5        UR                  [        R                  " [!        U R                  5      SS95        SSS5        g! [         a$    UR                  5         UR                  U5         Nmf = f! , (       d  f       g= f)z
Rename path onto <repodata> path, synchronize state.

Relies on path's mtime not changing on move. `temp_path` should be
adjacent to `self.cache_path_json` to be on the same filesystem.
Nr   r  r  
refresh_nsr   indent)r   r#   seektruncater  r  rD   r   timetime_nsrenameFileExistsErrorr7  r5  r   dumpsrG   )rC   r:  r<  r!  r  s        r:   r6  RepodataCache.replace  s     >))FYY[JOOA!>>#D%)%5%5DJJz"!%DJJv'+||~DJJ|$)  (
 TZZTZZ(8CD [ # )  () [s0   BD)'C887D)8+D&#D)%D&&D))
D7c                ^   U R                  5        nUR                  S5        UR                  5         U=(       d    [        R                  " 5       U R
                  S'   UR                  [        R                  " [        U R
                  5      SS95        SSS5        g! , (       d  f       g= f)zU
Update access time in cache info file to indicate a HTTP 304 Not Modified response.
r   rA  r   rB  N)
r#   rD  rE  rF  rG  rD   r5  r   rJ  rG   )rC   rA  r!  s      r:   refreshRepodataCache.refresh  sl    
 YY[JOOA!'1'CT\\^DJJ|$TZZTZZ(8CD [[s   BB
B,c              #     #    U R                   R                  U5       n[        U5         Uv   SSS5        SSS5        g! , (       d  f       N= f! , (       d  f       g= f7f)zx
Lock .info.json file. Hold lock while modifying related files.

mode: "a+" then seek(0) to write/create; "r+" to read.
N)r   r4  r#   )rC   r;  r!  s      r:   r#   RepodataCache.lock  sC      ""''-T*=M >N--=M=M--s1   A"AA A	A" 
A	
A
AA"c                2   [         R                  S:  a  [         R                  nO6[         R                  S:X  a   [        U R                  R                  5      nOSnUS-  n[
        R                  " 5       nU R                  R                  SS5      nX#-
  U:  $ )zW
Compare state refresh_ns against cache control header and
context.local_repodata_ttl.
rO   r    ʚ;rA  r   local_repodata_ttlget_cache_control_max_agerD   r+   rF  rG  rv   rC   max_ager   rM  s       r:   staleRepodataCache.stale  sz    
 %%)00G''1,/

0H0HIGG5lln**..q1((r9   c                8   [         R                  S:  a  [         R                  nO6[         R                  S:X  a   [        U R                  R                  5      nOSnUS-  n[
        R                  " 5       nU R                  R                  SS5      nX#-
  U-   S-  $ )zM
Return number of seconds until cache times out (<= 0 if already timed
out).
rO   r   rR  rA  g    eArS  rV  s       r:   rj   RepodataCache.timeout  s    
 %%)00G''1,/

0H0HIGG5lln**..q1')S00r9   )r  r  rb   rD   )rH   str | bytes)F)r9  r\  r   )r:  r$   )r   )za+)r3   r4   r5   r6   r7   rd   r   r   r  r   r%  r*  r>  r6  rM  r   r#   rX  rj   r8   r1   r9   r:   r   r     s    
 
 
 
 
 D D "'u +Z,E4
E  )"1r9   r   c                      \ rS rSr% SrS\S'   S\S'   S\S'   S\S	'   S\S
'   S\S'         SS jrSS jrSS jr\	S 5       r
\	S 5       r\	S 5       r\	SS j5       r\	SS j5       rSS jrSS jrSrg) RepodataFetchi  z
Combine RepodataCache and RepoInterface to provide subdir_data.SubdirData()
with what it needs.

Provide a variety of formats since some ``RepoInterface`` have to
``json.loads(...)`` anyway, and some clients don't need the Python data
structure at all.
r$   r  r   r   rI   rb   url_w_subdirurl_w_credentialsr%   repo_interface_clsc                   Xl         X l        X0l        U R                  R                  SS9=(       d    SU l        U R                  R                  SS9=(       d    SU l        X@l        g )NF)with_credentialsr   T)r  r   rb   r,   r_  r`  ra  )rC   r  r   rb   ra  s        r:   rd   RepodataFetch.__init__  sY      /& LL,,e,DJ!%!1!14!1!H!NB"4r9   c                &   U R                  5       u  p[        U[        5      (       a   [        R                  " U5      U4$ X4$ ! [        R
                   a8  nUR                  S    SUS[          S3/UR                  SS Q7Ul        e SnAff = f)z
Retrieve parsed latest or latest-cached repodata as a dict; update
cache.

:return: (repodata contents, state including cache headers)
r   z; got "N"rO   )fetch_latestr   rI   r   r  r)  argsERROR_SNIPPET_LENGTH)rC   parsedrD   rY   s       r:   fetch_latest_parsed!RepodataFetch.fetch_latest_parsed  s     ))+fc""zz&)500 =  '' vvayk0E1E)F(GqIVVABZ s   A B3BBc                B    U R                  5       u  pU R                  U4$ )z
Retrieve latest or latest-cached repodata; update cache.

:return: (pathlib.Path to uncompressed repodata contents, RepodataState)
)rg  r   )rC   _rD   s      r:   fetch_latest_pathRepodataFetch.fetch_latest_path	  s%     $$&##U**r9   c                :    U R                   S-   U R                  -   $ )Nr   )r_  rb   r   s    r:   url_w_repodata_fnRepodataFetch.url_w_repodata_fn  s      3&)9)999r9   c                .    U R                   R                  $ r   )
repo_cacher   r   s    r:   r   RepodataFetch.cache_path_json  s    ...r9   c                .    U R                   R                  $ )z?
Out-of-band etag and other state needed by the RepoInterface.
)ru  r   r   s    r:   r   RepodataFetch.cache_path_state  s    
 ///r9   c                B    [        U R                  U R                  5      $ r   )r   r  rb   r   s    r:   ru  RepodataFetch.repo_cache!  s    T1143C3CDDr9   c                `    U R                  U R                  U R                  U R                  S9$ )z(
Changes as we mutate self.repodata_fn.
)rb   cache)ra  r`  rb   ru  r   s    r:   _repoRepodataFetch._repo%  s5    
 &&""((// ' 
 	
r9   c                8	   U R                   nUR                  5         UR                  R                  5       (       d  [        R                  SU R                  U R                  5        [        R                  (       d5  [        R                  (       aY  U R                  R                  S5      (       d9  [        R                  SU R                  U R                  5        0 UR                  4$ GO[        R                  (       a=  [        R                  SU R                  U R                  5        U R                  5       nU$ UR                  5       nU(       a  [        R                  (       an  U R                  R                  S5      (       dN  UR                  5       n[        R                  SU R                  U R                  U5        U R                  5       nU$ [        R                  SU R                  U R                  5          U R                   n[#        US5      (       a  UR%                  UR                  5      nOUR'                  UR                  5      n  U[.        L ax  U R                  R1                  5       nU R                  R3                  5       nUR4                  UR                  S	'   UR6                  nXR                  S
'   UR9                  5         O[;        U[<        5      (       a^  U R                  R3                  5       nUR4                  UR                  S	'   UR6                  nXR                  S
'   UR9                  5         OE[;        U[>        [A        S5      45      (       a  Uc  SnURC                  U5        O[E        SU 35      eXaR                  4$ ! [(         a    U R*                  [,        :w  a  e Sn GNk[.         a
    [.        n GN}f = f! [F         ab  n	U	RH                  [H        RJ                  [H        RL                  [H        RN                  4;   a  [Q        U R                  U	RH                  U	S9ee Sn	A	ff = f! [R         aE    [        R                  SU R                  5        UR9                  5         U R                  5       nUs $ f = f)z
Return up-to-date repodata and cache information. Fetch repodata from
remote if cache has expired; return cached data if cache has not
expired; return stale cached data or dummy data if in offline mode.
z!No local cache found for %s at %szfile://z@Using cached data for %s at %s forced. Returning empty repodata.z9Using cached repodata for %s at %s because use_cache=Truez5Using cached repodata for %s at %s. Timeout in %d secz"Local cache timed out for %s at %srepodata_parsedNr  r  z{}zUnreachable r   z?304 NOT MODIFIED for '%s'. Updating mtime and loading from disk)*ru  r*  r   existsr`   ra   rr  r   use_index_cacheoffliner_  r   rD   
read_cacherX  rj   r}  hasattrr  rE   r/   rb   r   r=   r  r  r   r  rM  r   rG   rI   typer>  RuntimeErrorr8  errnoEACCESEPERMEROFSr   rK   )
rC   r|  _internal_staterX  rj   reporaw_repodatar  r  rY   s
             r:   rg  RepodataFetch.fetch_latest0  s     $$++--II3&&$$
 &&(9(9(D(DY(O(O		V**(( KK  &&		O**(( #'//"3&&KKMEW__d6G6G6R6R7 7  --/		K**((	 #'//"3&&II4&&$$9	-.zz4!233#'#7#7#DL#'==#=L&>1 $(#7#7#A#A#CL//446D*.,,EKK'#//H.6KK
+MMOd33  //446D*.,,EKK'#//H.6KK
+MMOsDJ.?@@#+'+JJ|,&l^'DEE  ,,e # $##{2#! .-.N  77u||U[[%++FF*4+?+?TUVV	G + 	#IIQ&& MMO"oo/O""	#sv   8N! =Q
 >N! Q
 B O A2O 6O O !!OQ
 OQ
 OQ
 
Q%AQQ
ARRc                ,   [         R                  SU R                  U R                  5        U R                  n UR                  5       nX!R                  4$ ! [         a3  n[         R                  SU R                  U5        Sn[        U5      eSnAff = f)zC
Read repodata from disk, without trying to fetch a fresh version.
zLoading raw json for %s at %szError for cache path: '%s'
%rzAn error occurred when loading cached repodata.  Executing
`conda clean --index-cache` will remove cached repodata files
so they can be downloaded again.N)	r`   ra   rr  r   ru  r%  rD   r   r	   )rC   r|  raw_repodata_strrY   r   s        r:   r  RepodataFetch.read_cache  s    
 			+""  	
 
	&$zz|#[[00 	& II68L8LaP$G W%%	&s   A 
B .BB)r  r   ra  rb   r`  r_  N)r  r$   r   r   rb   rI   )rH   ztuple[dict, RepodataState])rH   ztuple[Path, RepodataState])rH   r   )rH   r@   )rH   z tuple[dict | str, RepodataState])rH   ztuple[str, RepodataState])r3   r4   r5   r6   r7   r   rd   rk  ro  r   rr  r   r   ru  r}  rg  r  r8   r1   r9   r:   r^  r^    s     55 5 	5"!(+ : : / / 0 0 E E 
 
v-p&r9   r^  c                ,    [         R                  " U SS9$ )NF)usedforsecurity)hashlibmd5)r9  s    r:   _md5_not_for_securityr    s    ;;tU33r9   c                    U R                  S5      (       d  U S-  n U[        :w  a  X-  n [        U R                  S5      5      nUR	                  5       S S  S3$ )Nr   zutf-8   r
  )r   r   r  encode	hexdigest)r,   rb   r  s      r:   cache_fn_urlr    sZ    <<s
 k!


7 3
4Cmmobq!"%((r9   c                    U =(       d    Sn [         R                  " SU 5      nU(       a  [        UR                  5       S   5      $ S$ )Nr   zmax-age=(\d+)r   )researchintgroups)cache_control_valuerW  s     r:   rU  rU    s=    -3ii(*=>G'.3w~~"#5A5r9   c                     [         R                  R                  [        R                  " 5       R
                  S5      n [        U 5        U $ )Nr|  )r0  pathjoinr   first_writablepkgs_dirr"   )r  s    r:   create_cache_dirr    s4    -<<>GGQIi r9   )rH   ztype[RepoInterface])r  r   )\r7   
__future__r   abcr   r  r  rx   r0  r   r  rF  rU   collectionsr   
contextlibr   os.pathr   typingr   r   r	   auxlib.logzr
   base.constantsr   r   base.contextr   common.serializer   
common.urlr   r   core.package_cache_datar   
exceptionsr   r   r   r   r   r   models.channelr   
connectionr   r   r   r   r   r   r    connection.sessionr!   diskr"   	disk.lockr#   r$   r%   r&   	getLoggerr3   r`   r   	timedeltar   r   r   r   r   r   ri  r/   	Exceptionr=   ABCr@   rK   rZ   rX   r}   rs   r   r   r^  r  r  rU  r  r1   r9   r:   <module>r     s    " 
     	  	     %     $ = # $ 1 7  &   - $ %!/0	 #+"4"4!"<   # 
!   / Y CGG 	) 	.> >B v
 v
rB(H B(JL1 L1^l& l&^4 #. )6r9   