
    wBf$                    P   d Z ddlm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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 dd
lmZ ddl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%m&Z&m'Z'm(Z(m)Z)m*Z* ddl+m,Z, ddl-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z: erddl
m;Z; ddlm<Z< ddl-m=Z=  ej|                  e?      Z@ ej|                  d      ZA ej                  d      ZCdZDdZEdZFdZGd ZHd!ZI G d" d#e*      ZJ G d$ d%eK      ZL G d& d'ej                        ZN G d( d)eK      ZOd=d*ZP G d+ d,eN      ZQd- ZRed.        ZS G d/ d0e      ZT G d1 d2      ZU G d3 d4      ZV	  ej                  d5d67       d8 ZXefd:ZZd>d;Z[d< Z\y# eY$ r d9 ZXY w xY w)?zRepodata interface.    )annotationsN)UserDict)contextmanager)dirname)TYPE_CHECKING   )
CondaError)	stringify)CONDA_HOMEPAGE_URLREPODATA_FN)context)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                      e Zd ZdZy)RepodataIsEmptyz
    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____doc__     @lib/python3.12/site-packages/conda/gateways/repodata/__init__.pyr.   r.   K       r5   r.   c                      e Zd ZdZy)RepodataOnDiskzx
    Indicate that RepoInterface.repodata() successfully wrote repodata to disk,
    instead of returning a string.
    Nr/   r4   r5   r6   r9   r9   R   r7   r5   r9   c                      e Zd ZddZy)RepoInterfacec                     y)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.
        Nr4   )selfstates     r6   repodatazRepoInterface.repodata\   s     	r5   N)r>   dictreturnstr)r0   r1   r2   r?   r4   r5   r6   r;   r;   Y   s    r5   r;   c                      e Zd Zy)Response304ContentUnchangedN)r0   r1   r2   r4   r5   r6   rD   rD   e   s    r5   rD   c                     dt         j                  v r		 ddlm}  | S t         j                  r		 ddlm} |S t        S # t        $ r"}t        j                  d|        Y d }~Ed }~ww xY w# t        $ r Y t        S w xY w)Njlap   )JlapRepoInterfacezaCould not load the configured jlap repo interface. Is the required jsonpatch package installed?  )ZstdRepoInterface)
r   experimentaljlap.interfacerH   ImportErrorwarningswarnrepodata_use_zstrI   CondaRepoInterface)rH   erI   s      r6   get_repo_interfacerR   i   s    %%%	9$$ 	9$$   	MMAABE 	  		s&   ; A) 	A&A!!A&)	A:9A:c                  6    e Zd ZU dZded<   ded<   ddZd	dZy)
rP   zAProvides an interface for retrieving repodata data from channels.rB   _url_repodata_fnc                Z    t         j                  d       || _        |xs t        | _        y )NzUsing CondaRepoInterface)logdebugrT   r   rU   )r=   r+   repodata_fnkwargss       r6   __init__zCondaRepoInterface.__init__   s#    		,-	'6;r5   c                   t         j                  st        j                  dt               t        | j                        }i }|j                  }|j                  }|rt        |      |d<   |rt        |      |d<   | j                  }t        | j                  |      }t        | j                  |      5  t         j                  t         j                  f}|j                  |||j                   |      }	t"        j%                  t&        j(                        r t"        j+                  t-        |	d             |	j/                          d d d        	j0                  dk(  r
t3               |	j4                  }
d| j                  i}t7        |	d	|d
       t7        |	d|d       t7        |	d|d       |j9                          |j;                  |       |
S # 1 sw Y   xY w)NignorezIf-None-MatchzIf-Modified-Since)headersproxiestimeout   )content_max_leni0  rT   Etag_etagzLast-Modified_modzCache-Control_cache_control)r   
ssl_verifyrM   simplefilterr   r    rT   r)   r(   rB   rU   r   conda_http_errorsremote_connect_timeout_secsremote_read_timeout_secsgetr_   rW   isEnabledForloggingDEBUGrX   r
   raise_for_statusstatus_coderD   text_add_http_value_to_dictclearupdate)r=   r>   sessionr^   r)   last_modifiedfilenamer+   r`   responsejson_strsaved_fieldss               r6   r?   zCondaRepoInterface.repodata   s   !!!!(,BCdii(zz		'*4yGO$+.}+=G'($$tyy(+tyy(3 
	(3300G ")Wgoow "- "H .		)HcBC%%'
	( 3& .//== 		*&,H/<Po|5E	
 	\"?
	( 
	(s   2BGGN)r+   rB   rY   
str | NonerA   None)r>   RepodataStaterA   r|   )r0   r1   r2   r3   __annotations__r[   r?   r4   r5   r6   rP   rP      s    K I 7
0r5   rP   c                J    | j                   j                  |      }|r|||<   y y N)r^   rl   )resphttp_keyddict_keyvalues        r6   rs   rs      s'    LLX&E( r5   c              #  ~  K   	 d y# t         $ r t               t        $ r }dt        |      v rd}t	        |       d}~wt
        $ r5}	 ddl}t        d| d      # t        $ r t        d| d      w xY wd}~wt        t        t        f$ r'}t        |j                  dd      }|d	v r| j                  d
      sGt        j!                  d|| dz   |z          t#        t%        t'        |             ||j                        t(        j*                  rGt,        j/                  d|| dz   |z          t#        t%        t'        |             ||j                        t1        t%        t'        |             ||j                        |dk(  rt%        |       }|j2                  r+dj5                  |j2                  t7        t8        d            }nt(        j:                  j<                  | v rdt7        t8        d      z  }ngdt7        t8        d      z  }nS|d|cxk  rdk  rn nd}n@| j?                  d      rdtA        tC        |             z  }ndtA        tC        |             z  }tE        |t7        | |      |t        |j                  dd      t        |j                  dd      |j                  |      d}~ww xY ww)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: rq   )i  i  z/noarchz1Unable to retrieve repodata (response: %d) for %s/)ry   i  ay  The token '{}' given for the URL is invalid.

If this token was pulled from anaconda-client, you will need to use
anaconda-client to reauthenticate.

If you supplied this token to conda directly, 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 <{}>.
zdocs/config.htmla  The remote server has indicated you are using invalid credentials for this channel.

If the remote site is anaconda.org or follows the Anaconda Server API, you
will need to
    (a) remove the invalid token from your system with `anaconda logout`, optionally
        followed by collecting a new token with `anaconda login`, or
    (b) provide conda with a valid token directly.

Further configuration help can be found at <%s>.
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 <%s>.
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.

%s
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.
%s
reasonelapsed	caused_by)#r   r   r   rB   r   r   sslr   rL   r   r   r   getattrry   endswithrW   infor.   r   r   r   allow_non_channel_urls	stderrlogwarningr   tokenformatr   r   channel_aliaslocation
startswithr   reprr   )r+   rY   rQ   messager   rq   channelhelp_messages           r6   ri   ri      s    X
 l 
c!fG 'w// 	   3    	 3 	 	$ Y(<= q
ajj->*$<<	*G#I+
 &GCL)ZZ  11%%K#c	K/
 *-#!"  4-#!"  CclG}}  FMM/1CD   &&//36
  !#56
 7  !#56 7 $)Ac)AL ~~:;  DI   DI	  S+&AJJ$/AJJ	40JJ
 	
Sq
sM   J=	 J=J:?J:AA;A88A;;J:H"J55J::J=c                  0    e Zd ZdZeeeedZh dZ		 	 	 	 d	 	 	 d fdZ
edd       Zej                  d        Zedd       Zej                  d        Zedd	       Zej                  d
        ZddZddZddZddZd fdZd fdZd fdZ xZS )r~   z<Load/save info file that accompanies cached `repodata.json`.)re   rd   rf   rT   >   r(   r+   r)   r*   c                    t         |   |       t        j                  |      | _        t        j                  |      | _        || _        y r   )superr[   pathlibr#   cache_path_jsoncache_path_staterY   )r=   r   r   rY   r@   	__class__s        r6   r[   zRepodataState.__init__s  s=     	&||O< '-= >&r5   c                4    | j                  t              xs dS )z,
        Last-Modified header or ""
         )rl   LAST_MODIFIED_KEYr=   s    r6   r(   zRepodataState.mod      
 xx)*0b0r5   c                    |xs d| t         <   y Nr   )r   r=   r   s     r6   r(   zRepodataState.mod      "'+2r5   c                4    | j                  t              xs dS )z#
        Etag header or ""
        r   )rl   ETAG_KEYr   s    r6   r)   zRepodataState.etag  s    
 xx!'R'r5   c                    |xs d| t         <   y r   )r   r   s     r6   r)   zRepodataState.etag  s    "Xr5   c                4    | j                  t              xs dS )z,
        Cache-Control header or ""
        r   )rl   CACHE_CONTROL_KEYr   s    r6   r*   zRepodataState.cache_control  r   r5   c                    |xs d| t         <   y r   )r   r   s     r6   r*   zRepodataState.cache_control  r   r5   c                   d| }|| vry	 | |   }|d   }|j                  d      r|d d  d}t        j                  j                  |      }t        |d         }||fS # t        t
        t        f$ r:}t        j                  dt         d	|
       | j                  |       Y d }~nd }~ww xY wdt        j                  j                  t        j                  j                        fS )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	TypeErrorrW   rN   CACHE_STATE_SUFFIXpopnowtimezoneutc)r=   r   keyobjlast_checked_strr   r   rQ   s           r6   
has_formatzRepodataState.has_format  s     VHod?	s)C">2((-&6s&;%<F#C #,,::;KLLW&E<((*i0 	HH?@R?SSTU   HHSMM	 h''++x/@/@/D/D+EEEs   AA   B.40B))B.c                    d| }t         j                   j                  t         j                  j                        j	                         d t        d        dz   |d| |<   y )Nr   r   r   r   )r   r   )r   r   r   r   	isoformatlen)r=   r   r   r   s       r6   set_has_formatzRepodataState.set_has_format  sc    VHo$--11X5F5F5J5J1KUUW 3x=.  
S	r5   c                2    d| }| j                  |d       y)z2Remove 'has_{format}' instead of setting to False.r   N)r   )r=   r   r   s      r6   clear_has_formatzRepodataState.clear_has_format  s    VHodr5   c                    | j                  |      \  }}|du xs^ t        |t        j                        xrB t        j                  j                  t        j                  j
                        |z
  t        kD  S )z0Return True if named format should be attempted.Tr   )r   
isinstancer   r   r   r   CHECK_ALTERNATE_FORMAT_INTERVAL)r=   r   haswhens       r6   should_check_formatz!RepodataState.should_check_format  sj    OOF+	T4K .$ 1 12 .!!%%):):)>)>%?$F-.	
r5   c                Z    | j                   j                  ||      }t        |   |      S r   )_aliasedrl   r   __contains__r=   r   r   s     r6   r   zRepodataState.__contains__  s)    mmS)w#C((r5   c                    | j                   j                  ||      }|| j                  v r(t        |t              st
        j                  d|       d}t        | !  ||      S )Nz*Replaced non-str RepodataState[%s] with ""r   )	r   rl   _stringsr   rB   rW   rX   r   __setitem__)r=   r   itemr   s      r6   r   zRepodataState.__setitem__  sT    mmS)$--
4(=IIBCHDw"3--r5   c                Z    | j                   j                  ||      }t        |   |      S r   )r   rl   r   __getitem__r   s     r6   r   zRepodataState.__getitem__  s)    mmS)w"3''r5   )r   r   r   N)r   
Path | strr   r   rA   rB   )r   rB   rA   z%tuple[bool, datetime.datetime | None])r   rB   r   r   )r   rB   )r   rB   rA   r   )r   rB   rA   r   )r   rB   r   r$   rA   r}   )r   rB   rA   r$   )r0   r1   r2   r3   r   r   r   URL_KEYr   r   r[   propertyr(   setterr)   r*   r   r   r   r   r   r   r   __classcell__)r   s   @r6   r~   r~   e  s    F "+	H 7H ')')'#' %' 1 1 	ZZ. . ( ( 
[[% % 1 1 . .F>


).( (r5   r~   c                      e Zd ZdZd Zed        Zed        ZddddZd Z	dd	Z
dd
ZddZedd       Zd Zd Zy)RepodataCachez
    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.
    c                    t        j                  |      }|j                  | _        |j                  | _        || _        t        | j                  | j                  |      | _	        y)z~
        base: directory and filename prefix for cache, e.g. /cache/dir/abc123;
        writes /cache/dir/abc123.json
        N)
r   r#   parent	cache_dirnamerY   r~   r   r   r>   )r=   baserY   cache_path_bases       r6   r[   zRepodataCache.__init__  sS    
 ",,t,(//#((	&"  $"7"7

r5   c                    t        j                  | j                  | j                  t        j
                  rdndz   dz         S )N1r   .json)r   r#   r   r   r   use_only_tar_bz2r   s    r6   r   zRepodataCache.cache_path_json   s5    ||NNII 8 8bAGK
 	
r5   c                @    | j                   j                  t              S )z=Out-of-band etag and other state needed by the RepoInterface.)r   with_suffixr   r   s    r6   r   zRepodataCache.cache_path_state  s     ##//0BCCr5   F
state_onlyc               8   | j                  d      5 }t        j                  |j                               }|rd}n| j                  j                         }| j                  j                         }|j                  d      |j                  k(  r|j                  d      |j                  k(  s%|j                  t        dt        dt        dddi       | j                  j                          | j                  j                  |       d d d        |S # 1 sw Y   S xY w)Nzr+r   mtime_nssizer   )r"   jsonloadsreadr   	read_textstatrl   st_mtime_nsst_sizeru   r   r   r   r>   rt   )r=   r   
state_filer>   	json_data	json_stats         r6   loadzRepodataCache.load  s     YYt_ 	
 JJz01E 	 00::<	,,113I		*%)>)>>IIf%):)::  ")2)2	 JJJJ7	> ?	> s   C3DDc                z   	 | j                  d       | j                  S # t        t        j                  f$ r}t	        |t        j                        r8t
        j                  |j                  j                   d| j                          | j                  j                          Y d}~| j                  S d}~ww xY w)z^
        Update self.state without reading repodata.json.

        Return self.state.
        Tr   z	 loading N)r  FileNotFoundErrorr   JSONDecodeErrorr   rW   r   r   r0   r   r>   rt   )r=   rQ   s     r6   
load_statezRepodataCache.load_stateB  s    	III&
 zz	 "4#7#78 	!T112q{{334Id>S>S=TUVJJzz		s     B:A,B55B:c                   | j                   | j                   dt        j                  d      j	                          dz  }	 |j                  d      5 }|j                  |       ddd       | j                  |      	 |j                          S # 1 sw Y   +xY w# t        $ r Y S w xY w# 	 |j                          w # t        $ r Y w w xY wxY w)z<Write data to <repodata>.json cache path, synchronize state..r   z.tmpxN)
r   r   osurandomhexopenwritereplaceunlinkOSError)r=   data	temp_pathtemps       r6   savezRepodataCache.saveP  s    NN		{!BJJqM4E4E4G3H%MM	
	$ !

4 ! <<	*  "! !    " sZ   B* B%B* >BBB* 	B'&B'*C,B=<C=	C	CC		Cc                   | j                         5 }|j                  d       |j                          |j                         }|j                  | j
                  d<   |j                  | j
                  d<   t        j                         | j
                  d<   	 |j                  | j                         |j                  t        j                  t!        | j
                        d             ddd       y# t        $ r8 | j                  j                          |j                  | j                         Y w xY w# 1 sw Y   yxY w)z
        Rename path onto <repodata>.json 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.
        r   r   r   
refresh_nsr   indentN)r"   seektruncater  r  r>   r  timetime_nsrenamer   FileExistsErrorr  r  r   dumpsr@   )r=   r  r  r  s       r6   r  zRepodataCache.replace`  s    YY[ 	EJOOA!>>#D &*%5%5DJJz"!%DJJv'+||~DJJ|$7  !5!56 TZZTZZ(8CD	E 	E # 7$$++-  !5!567	E 	Es0   BD8C429D84>D52D84D55D88Ec                L   | j                         5 }|j                  d       |j                          |xs t        j                         | j
                  d<   |j                  t        j                  t        | j
                        d             ddd       y# 1 sw Y   yxY w)ze
        Update access time in cache info file to indicate a HTTP 304 Not Modified response.
        r   r  r   r  N)
r"   r  r   r!  r"  r>   r  r   r%  r@   )r=   r  r  s      r6   refreshzRepodataCache.refreshx  s{    
 YY[ 	EJOOA!'1'CT\\^DJJ|$TZZTZZ(8CD	E 	E 	Es   B BB#c              #     K   | j                   j                  |      5 }t        |      5  | ddd       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY ww)z
        Lock .info.json file. Hold lock while modifying related files.

        mode: "a+" then seek(0) to write/create; "r+" to read.
        N)r   r  r"   )r=   moder  s      r6   r"   zRepodataCache.lock  sT      ""''- 	T*=M 		 	 	 	 	 	s1   AAA A	A A		AAAc                .   t         j                  dkD  rt         j                  }n5t         j                  dk(  r t        | j                  j                        }nd}|dz  }t        j                         }| j                  j                  dd      }||z
  |kD  S )zo
        Compare state refresh_ns against cache control header and
        context.local_repodata_ttl.
        rG   r    ʚ;r  r   local_repodata_ttlget_cache_control_max_ager>   r*   r!  r"  rl   r=   max_ager   r'  s       r6   stalezRepodataCache.stale  s|    
 %%)00G''1,/

0H0HIGG5lln**..q1g((r5   c                4   t         j                  dkD  rt         j                  }n5t         j                  dk(  r t        | j                  j                        }nd}|dz  }t        j                         }| j                  j                  dd      }||z
  |z   dz  S )ze
        Return number of seconds until cache times out (<= 0 if already timed
        out).
        rG   r   r+  r  g    eAr,  r/  s       r6   r`   zRepodataCache.timeout  s    
 %%)00G''1,/

0H0HIGG5lln**..q1w')S00r5   Nr   )r  rB   )r  r#   )r   )za+)r0   r1   r2   r3   r[   r   r   r   r  r  r  r  r'  r   r"   r1  r`   r4   r5   r6   r   r     su    
 
 
 D D "' 'l E0
E  )"1r5   r   c                      e Zd ZU dZded<   ded<   ded<   ded<   ded	<   d
ed<   	 	 	 	 	 	 ddZddZddZed        Z	ed        Z
ed        Zedd       Zedd       ZddZddZy)RepodataFetcha  
    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   rB   rY   url_w_subdirurl_w_credentialsr$   repo_interface_clsc                   || _         || _        || _        | j                  j                  d      xs d| _        | j                  j                  d      xs d| _        || _        y )NF)with_credentialsr   T)r   r   rY   r+   r5  r6  r7  )r=   r   r   rY   r7  s        r6   r[   zRepodataFetch.__init__  sa      /& LL,,e,DJ!%!1!14!1!H!NB"4r5   c                   | j                         \  }}t        |t              r	 t        j                  |      |fS ||fS # t        j
                  $ r8}|j                  d    d|dt          dg|j                  dd |_         d}~ww xY w)z
        Retrieve parsed latest or latest-cached repodata as a dict; update
        cache.

        :return: (repodata contents, state including cache headers)
        r   z; got "N"rG   )fetch_latestr   rB   r   r   r
  argsERROR_SNIPPET_LENGTH)r=   parsedr>   rQ   s       r6   fetch_latest_parsedz!RepodataFetch.fetch_latest_parsed  s     ))+fc"zz&)500 5=  '' vvayk0E1E)F(GqIVVABZ s   A   B3BBc                D    | j                         \  }}| j                  |fS )z
        Retrieve latest or latest-cached repodata; update cache.

        :return: (pathlib.Path to uncompressed repodata contents, RepodataState)
        )r<  r   )r=   _r>   s      r6   fetch_latest_pathzRepodataFetch.fetch_latest_path  s'     $$&5##U**r5   c                :    | j                   dz   | j                  z   S )Nr   )r5  rY   r   s    r6   url_w_repodata_fnzRepodataFetch.url_w_repodata_fn  s      3&)9)999r5   c                .    | j                   j                  S r   )
repo_cacher   r   s    r6   r   zRepodataFetch.cache_path_json  s    ...r5   c                .    | j                   j                  S )zO
        Out-of-band etag and other state needed by the RepoInterface.
        )rG  r   r   s    r6   r   zRepodataFetch.cache_path_state  s    
 ///r5   c                B    t        | j                  | j                        S r   )r   r   rY   r   s    r6   rG  zRepodataFetch.repo_cache  s    T1143C3CDDr5   c                f    | j                  | j                  | j                  | j                        S )z8
        Changes as we mutate self.repodata_fn.
        )rY   cache)r7  r6  rY   rG  r   s    r6   _repozRepodataFetch._repo  s5    
 &&""((// ' 
 	
r5   c                   | j                   }|j                          |j                  j                         st        j                  d| j                  | j                         t        j                  s-t        j                  rX| j                  j                  d      s<t        j                  d| j                  | j                         i |j                  fS t        j                  r=t        j                  d| j                  | j                         | j                         }|S |j                         }|rt        j                  ri| j                  j                  d      sN|j                         }t        j                  d| j                  | j                  |       | j                         }|S t        j                  d| j                  | j                         	 	 | j                   }t#        |d      r|j%                  |j                        }n|j'                  |j                        }	 |t.        u rx| j                  j1                         }t3        |      |j                  d	<   | j                  j5                         }|j6                  }||j                  d
<   |j9                          nt;        |t<              r_| j                  j5                         }|j>                  |j                  d	<   |j6                  }||j                  d
<   |j9                          n;t;        |t@        tC        d      f      r|d}|jE                  |       n
J d|        ||j                  fS # t(        $ r | j*                  t,        k7  r d}Y [t.        $ r
 t.        }Y lw xY w# tF        $ rc}	|	jH                  tH        jJ                  tH        jL                  tH        jN                  fv r"tQ        | j                  |	jH                  |	       d}	~	ww xY w# tR        $ rE t        j                  d| j                         |j9                          | j                         }|cY S w xY w)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)*rG  r  r   existsrW   rX   rE  r   use_index_cacheoffliner5  r   r>   
read_cacher1  r`   rL  hasattrrN  r?   r.   rY   r   r9   r   r   r  r  r'  r   r@   r  rB   typer  r  errnoEACCESEPERMEROFSr   rD   )
r=   rK  _internal_stater1  r`   reporaw_repodatar  r   rQ   s
             r6   r<  zRepodataFetch.fetch_latest  s     $$++-II3&&$$
 &&(9(9(D(DY(O		V**(( KK  &&		O**(( #'//"3&&KKMEW__d6G6G6R6R7  --/		K**((	 #'//"3&&II4&&$$:	-.zz4!23#'#7#7#DL#'==#=L&>1 $(#7#7#A#A#CL*-l*;EKK'//446D#//H.6EKK
+MMOd3  //446D*.,,EKK'#//H.6EKK
+MMOsDJ.?@#+'+JJ|, @L"??5  ,,g # $##{2#! .-.P  77u||U[[%++FF*4+?+?TUVV	I + 	#IIQ&& MMO"oo/O""	#sR   AM% -D*N %NP NP NP 	P%APPAQQc                ,   t         j                  d| j                  | j                         | j                  }	 |j                         }||j                  fS # t        $ r3}t         j                  d| j                  |       d}t        |      d}~ww xY w)zS
        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)	rW   rX   rE  r   rG  r  r>   r   r	   )r=   rK  raw_repodata_strrQ   r   s        r6   rR  zRepodataFetch.read_cache  s    
 			+""  	
 
	&$zz|#U[[00 	& II68L8LaP$G W%%	&s   A 	B .BBN)r   r#   r   r   rY   rB   )rA   ztuple[dict, RepodataState])rA   ztuple[Path, RepodataState])rA   r   )rA   r;   )rA   z tuple[dict | str, RepodataState])rA   ztuple[str, RepodataState])r0   r1   r2   r3   r   r[   r@  rC  r   rE  r   r   rG  rL  r<  rR  r4   r5   r6   r4  r4    s     55 5 	5"!(+ : : / / 0 0 E E 
 
w-r&r5   r4  r5   Fusedforsecurityc                0    t        j                  | d      S )NFr^  hashlibmd5r  s    r6   _md5_not_for_securityre    s    {{477r5   c                ,    t        j                  |       S r   ra  rd  s    r6   re  re    s    {{4  r5   c                    | j                  d      s| dz  } |t        k7  r| |z  } t        | j                  d            }|j	                         d d  dS )Nr   zutf-8   r   )r   r   re  encode	hexdigest)r+   rY   rc  s      r6   cache_fn_urlrk    sY    <<s
 k!{


7 3
4Cmmobq!"%((r5   c                z    | xs d} t        j                  d|       }|rt        |j                         d         S dS )Nr   zmax-age=(\d+)r   )researchintgroups)cache_control_valuer0  s     r6   r.  r.    s=    -3ii(*=>G'.3w~~"#5A5r5   c                     t         j                  j                  t        j                         j
                  d      } t        |        | S )NrK  )r  pathjoinr   first_writablepkgs_dirr!   )r   s    r6   create_cache_dirrw    s4    -<<>GGQIi r5   )rA   ztype[RepoInterface])rq  r|   )]r3   
__future__r   abcr   rU  rb  r   rn   r  r   rm  r!  rM   collectionsr   
contextlibr   os.pathr   typingr   r   r	   auxlib.logzr
   base.constantsr   r   base.contextr   
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%   	getLoggerr0   rW   r   	timedeltar   r   r   r   r   r   r>  r.   	Exceptionr9   ABCr;   rD   rR   rP   rs   ri   r~   r   r4  rc  re  r   rk  r.  rw  r4   r5   r6   <module>r     s    " 
      	  	     %     $ = # 1 7  &   - $ %g!G/0	 #5("4"4!"<   # 
!   / Y 	CGG 		) 	.> >B Z
 Z
zB(H B(JD1 D1Nm& m&`	!GKKU+8 #. )65  !!!s   6F F%$F%