
    wBfMT                    .   d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZmZ 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& ddl'm(Z) ddl*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2m3Z3 ddl4m5Z5 ddl6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z= ddl6m>Z? ddl@mAZAmBZB ddlCmDZD ddlEmFZF erddl6mGZGmHZH  eeI      ZJdZKdZLd ZM e/d!d"d#$      d.d%       Z> G d& d'eN      ZO G d( d)e      ZP G d* d+eO,      ZQd- ZRy)/z,Tools for managing a subdir's repodata.json.    )annotationsN)UserListdefaultdict)partial)chain)	getLogger)existsjoinsplitext)Path)time)TYPE_CHECKING)
IndexedSet)getmtimeisfile   )dals)CONDA_PACKAGE_EXTENSION_V1REPODATA_FN)context)DummyExecutorThreadLimitedThreadPoolExecutordashlist)groupby_to_dict)url_to_path)join_url)
deprecated)ChannelErrorCondaUpgradeErrorUnavailableInvalidChannel)rm_rf)CACHE_STATE_SUFFIXCondaRepoInterfaceRepodataFetchRepodataStatecache_fn_urlcreate_cache_dirget_repo_interface)get_cache_control_max_age)Channelall_channel_urls)	MatchSpec)PackageRecord)RepodataCacheRepoInterface   s4   "(_etag|_mod|_cache_control)":[ ]?"(.*?[^\\])"[,}\s]z24.3z24.9z@Use `conda.gateways.repodata.get_cache_control_max_age` instead.)addendumc                    t        |       S N)_get_cache_control_max_age)cache_control_values    6lib/python3.12/site-packages/conda/core/subdir_data.pyr)   r)   9   s     &&9::    c                  "     e Zd Zef fd	Z xZS )SubdirDataTypec                .   |j                   sJ |j                  rJ t        |      t        u sJ t	               }|xs t
        }|j                  d      |f}|t        j                  v rvt        j                  |   }|d   r\|d   j                  d      rH|j                         }|r8t        |dz   |z         }t        |      r|j                  t        |      k\  r|S |S t        	| =  ||t!                     }||_        |t        j                  |<   |S )NTwith_credentialsr   file:///)r/   )subdirpackage_filenametyper*   r   r   url
SubdirData_cache_
startswithr   r	   _mtimer   super__call__r(   )
clschannelrepodata_fnnow	cache_keycache_entrychannel_url	file_pathsubdir_data_instance	__class__s
            r6   rH   zSubdirDataType.__call__C   s   ~~~++++G}'''f!0[KKK6C	
***$,,Y7K|	! 7 7	 B%kkm +K#,=,K LIi([-?-?8ICV-V**""$w/[0B0D  0  
 '*#(<
9%##r7   )__name__
__module____qualname__r   rH   __classcell__)rR   s   @r6   r9   r9   B   s    +6 $ $r7   r9   c                      e Zd ZdZd Zy)PackageRecordListz&Lazily convert dicts to PackageRecord.c                    t        |t              r| j                  | j                  |         S | j                  |   }t        |t              st	        di |}|| j                  |<   |S )N )
isinstanceslicerR   datar-   )selfirecords      r6   __getitem__zPackageRecordList.__getitem___   sY    a>>$))A,//YYq\Ffm4&00%		!Mr7   N)rS   rT   rU   __doc__ra   rZ   r7   r6   rX   rX   \   s
    0r7   rX   c                  .   e Zd Zi Zedd       Zeddefd       Zd Z	ee
fdZedd       Zedd       Zedd       Zd	 Zed
        Zed        Zed        Zed        Zed        Zd Zd Zd Zd Zd ZddZd ZddZ	 d	 d dZdd!dZdd"dZ y)#rC   c                    |rI| j                   j                         D ci c]  \  }}|d   j                  d      r|| c}}| _         y | j                   j                          y c c}}w )Nr   r=   )rD   itemsrE   clear)rI   exclude_filekvs       r6   clear_cached_local_channel_dataz*SubdirData.clear_cached_local_channel_datam   sY     !$!2!2!4AAaDOOI<V1CK KK	s
   A'A'Nc           	         ddl m} t                |t        j                  }|t        j
                  }t        ||      }t        j                  r[t        d |      }|j                  dd      }|rt        j                  dt        |             t        |j                  dd            } ||        fd	}t        j                  st        j                  dk(  rt         nt#        t$        t        j                  
      }	 |	       5 }
t'        t)        j*                  |
j-                  ||                  }d d d        |S # 1 sw Y   S xY w)N   )check_allowlist)subdirsc                $    | j                  d      S )Nr=   )rE   )rB   s    r6   <lambda>z&SubdirData.query_all.<locals>.<lambda>   s    s~~i/H r7   FrZ   z>Ignoring the following channel urls because mode is offline.%sTc                `    t        t        t        |             j                              S )N)rK   )tuplerC   r*   query)rB   package_ref_or_match_specrK   s    r6   subdir_queryz*SubdirData.query_all.<locals>.subdir_query   s,    73<[AGG- r7   )max_workers)indexrm   r'   r   channelsrn   r+   offlinegroupbygetloginfor   r   debugrepodata_threadsr   r   r   rr   r   from_iterablemap)rt   rx   rn   rK   rm   channel_urlsgrouped_urlsignored_urlsru   Executorexecutorresults   `  `        r6   	query_allzSubdirData.query_allx   s    	+ 	''H?ooG''B??"#H,WL'++E26LT\* &l&6&6tR&@AL%	 }} 8 8A = /W=U=U 	 Z 	8##HLL|$LMF	 		 s   /EEc              #    K   | j                   s| j                          |}t        |t              rt	        |      }t        |t              r{|j                  d      r>|j                  d      }| j                  |      D ]  }|j                  |      s|  y | j                         D ]  }|j                  |      s|  y t        |t              sJ | j                  |j                        D ]  }||k(  s	|  y w)Nname)_loadedloadr[   strr,   get_exact_value_iter_records_by_namematchiter_recordsr-   r   )r^   rt   parampackage_nameprecs        r6   rs   zSubdirData.query   s     ||IIK)eS!e$EeY'$$V,$44V< 66|D #D{{4("
# !--/ #D{{4("
# e]333225::> 5=Js   BD+D <D=Dc                   |j                   sJ |j                  r|j                         }|d= t        di |}|| _        | j                  j                  d      xs d| _        | j                  j                  d      xs d| _        | j                  | _        | j                  | _	        || _
        || _        d| _        d | _        y )Nr@   Fr;    TrZ   )r?   r@   dumpr*   rJ   rB   url_w_subdirurl_w_credentials	_base_url_base_url_w_credentialsrK   r/   r   _key_mgr)r^   rJ   rK   r/   partss        r6   __init__zSubdirData.__init__   s     ~~~##LLNE()&&G LL,,e,DJ!%!1!14!1!H!NB**'+'='=$&*r7   c                .    | j                   j                  S )z8
        Changes as we mutate self.repodata_fn.
        )
repo_fetch_repor^   s    r6   r   zSubdirData._repo   s    
 $$$r7   c                .    | j                   j                  S r3   )r   
repo_cacher   s    r6   r   zSubdirData.repo_cache   s    )))r7   c                    t        t        | j                        | j                  | j                  | j
                        S )z
        Object to get repodata. Not cached since self.repodata_fn is mutable.

        Replaces self._repo & self.repo_cache.
        )repo_interface_cls)r$   r   cache_path_baserJ   rK   r/   r   s    r6   r   zSubdirData.repo_fetch   s8     %%&LL#11	
 	
r7   c                4    d| _         | j                          | S )NF)r   r   r   s    r6   reloadzSubdirData.reload   s    		r7   c           	     ~    t        t               t        t        | j                  | j
                              d         S )Nr   )r
   r'   r   r&   r   rK   r   s    r6   r   zSubdirData.cache_path_base   s5    \$"8"8$:J:JKLQO
 	
r7   c                :    | j                   dz   | j                  z   S )Nr>   )r   rK   r   s    r6   url_w_repodata_fnzSubdirData.url_w_repodata_fn   s      3&)9)999r7   c                \    t        | j                  t        j                  rdndz   dz         S )N1r   z.json)r   r   r   use_only_tar_bz2r   s    r6   cache_path_jsonzSubdirData.cache_path_json   s,      7+C+CCLwV
 	
r7   c                d    t        | j                  t        j                  rdndz   t        z         S )z=Out-of-band etag and other state needed by the RepoInterface.r   r   )r   r   r   r   r"   r   s    r6   cache_path_statezSubdirData.cache_path_state  s4       ..sB8 !
 	
r7   c                T    | j                   t        j                  rdz   dz   S dz   dz   S )Nr   r   z.q)r   r   r   r   s    r6   cache_path_picklezSubdirData.cache_path_pickle
  s/    ##g.F.FsORVVVBORVVVr7   c                v   | j                         }|j                  dd      t        kD  r!t        t	        d      | j
                  z        |j                  d| j                        | _        |j                  d| j                        | _	        || _
        |d   | _        |d   | _        |d   | _        d	| _        | S )
Nrepodata_versionr   
                The current version of conda is too old to read repodata from

                    %s

                (This version only supports repodata_version 1 and 2.)
                Please update conda to use this channel.
                base_urlbase_url_w_credentials_package_records_names_index_track_features_indexT)_loadr{   MAX_REPODATA_VERSIONr   r   r   r   r   r   r   _internal_stater   r   r   r   )r^   r   s     r6   r   zSubdirData.load  s    **,1158LL#	 ((
)  ),,Z9J9JK'6':':$d&<&<(
$  / /0B C+N;%45L%M"r7   c                d    | j                   s| j                          t        | j                        S r3   )r   r   iterr   r   s    r6   r   zSubdirData.iter_records*  s#    ||IIKD))**r7   c              #  V   K   | j                   |   D ]  }| j                  |     y wr3   )r   r   )r^   r   r_   s      r6   r   z SubdirData._iter_records_by_name1  s1     ""4( 	+A''**	+s   ')c                    	 | j                   }|j                         \  }}| j                  ||      S # t        $ r2 | j                  t
        k7  rt
        | _        | j                         cY S  w xY w)z
        Try to load repodata. If e.g. we are downloading
        `current_repodata.json`, fall back to `repodata.json` when the former is
        unavailable.
        )r   fetch_latest_parsed_process_raw_repodatar    rK   r   r   )r^   fetcherrepodatastates       r6   r   zSubdirData._load5  si    		ooG%99;OHe--h>>( 	;.#. zz|#	s   03 7A.,A.c                \   	 t         j                  d| j                  | j                         t	        | j                  d      5 }t        j                  | j                  |t
        j                         d d d        y # 1 sw Y   y xY w# t        $ r t         j                  dd       Y y w xY w)Nz!Saving pickled state for %s at %swbz Failed to dump pickled repodata.Texc_info)
r|   r~   r   r   openpickler   r   HIGHEST_PROTOCOL	Exception)r^   fhs     r6   
_pickle_mezSubdirData._pickle_meF  s    		III3&&&&
 d,,d3 OrD00"f6M6MNO O O 	III84IH	Is0   AB 0A<3B <BB B  B+*B+c                    | j                  |      }|r|S | j                  j                         \  }}| j                  ||      }| j                  |u sJ | j                          |S r3   )_read_pickledr   
read_cache_process_raw_repodata_strr   r   )r^   r   _pickled_stateraw_repodata_strr   s        r6   _read_local_repodatazSubdirData._read_local_repodataR  sj    ++E2!!"&//"<"<">%889I5Q##666r7   c              #    K   d|j                  d      | j                  f d|j                  d      | j                  j                  f d|j                  d      t        j
                  f d|j                  d      |f d|j                  d      |f d|j                  d      t        f d|j                  d      | j                  f yw)	z/Throw away the pickle if these don't all match._url	_schannel_add_pip_mod_etag_pickle_versionfnN)r{   r   rJ   canonical_namer   add_pip_as_python_dependencyREPODATA_PICKLE_VERSIONrK   )r^   pickled_statemodetags       r6   _pickle_valid_checkszSubdirData._pickle_valid_checks_  s     m''/1G1GGG=,,[94<<;V;VVVj)00
 	

 m''/44}((1477/0#
 	

 M%%d+T-=-===s   CCc           	         t        t              s-t         j                   j                   j                        t         j                        rt         j                        sy 	 t         j                        r t        j                  d j                         t         j                  d      5 }t        j                  |      d d d         fdfd}t         |             s;t        j                  d	 j                   j                  t!                             y S # 1 sw Y   bxY w# t        $ r/ t        j                  dd       t         j                         Y y w xY w)
Ndictzfound pickle file %srbz Failed to load pickled repodata.Tr   c                 R    j                   j                  j                        S r3   )r   r   r   )r   r^   r   s   r6   checksz(SubdirData._read_pickled.<locals>.checks  s     ,,^UYY

SSr7   c               3  <   K           D ]  \  } }}||k(    y wr3   rZ   )_leftrightr   s      r6   _check_pickled_validz6SubdirData._read_pickled.<locals>._check_pickled_valid  s(     "(( $4em#$s   z.Pickle load validation failed for %s at %s. %r)r[   r%   r   r   rK   r   r   r|   r~   r   r   r   r   r!   allr   rr   )r^   r   r   r   r   r   s   ``  @@r6   r   zSubdirData._read_pickledq  s/   %/!$$%%  	E d,,-VD<P<P5Q	d,,-		0$2H2HId,,d3 1r!'R1	T	$ ')*II@&&$$fh	 /1 1 	II84IH$(()	s+   .AD< 9D0D< 0D95D< <5E43E4c                Z    t        j                  |xs d      }| j                  ||      S )zKState contains information that was previously in-band in raw_repodata_str.z{})r   )jsonloadsr   )r^   r   r   json_objs       r6   r   z$SubdirData._process_raw_repodata_str  s.     ::.6$7))(%)@@r7   c                .   t        |t              s-t        | j                  | j                  | j                  |      }|j                  di       j                  d      xs | j                  j                  }|| j                  j                  k(  sJ t        j                  }| j                  j                  }t               x| _        }t        t              x| _        }t        t              x| _        }| j#                  |d      }	| j#                  |d      }
i d| j                  d| j$                  d	| j&                  d
|	d|
d| j(                  d| j                  d|d|d|d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|dt*        d|d|j                  dd      i}|d   t,        kD  r!t/        t1        d      | j$                  z        |j                  di       j                  d      | j                  |j                  di       j                  d      ||d}|j                  di       t        j2                  ri n|j                  di       }t4        }t7        j9                               |j9                         D ch c]
  }|d d  |z    c}z
  }|j;                         dffd!|D        dffD ]  \  }}|D ]  \  }}|rD|j=                  d"d#      }|v r.|   j                  d$      |d%<   |   j                  d&      |d'<   |r0|d(   d)k(  r(|d*   j?                  d+      r|d,   jA                  d-       |jC                  |       |j                  d.d      d/kD  rtD        jG                  d0|d.   |d1          ||d<   tI        |
|      |d1<   |jA                  |       tK        |      d/z
  }||d(      jA                  |         || _&        |S c c}w )2Nr   r}   r?   Fr;   TrJ   r   r   r   r   r   r   r   r   r   r   r   _cache_controlr   r   r   r   r   r   r   archplatform)r   rJ   r   schannelr?   packageszpackages.condaic              3  ,   K   | ]  }||   f  y wr3   rZ   ).0rh   legacy_packagess     r6   	<genexpr>z3SubdirData._process_raw_repodata.<locals>.<genexpr>  s     E!q/!$%Es   z.condaz.tar.bz2md5legacy_bz2_md5sizelegacy_bz2_sizer   pythonversion)z2.z3.dependspiprecord_versionrl   z"Ignoring record_version %d from %srB   )'r[   r%   r   r   rK   r{   rJ   r?   r   r   r   rX   r   r   listr   r   _get_base_urlr   r   r   r   r   r   r   r   r   setkeysre   replacerE   appendupdater|   r~   r   lenr   )r^   r   r   r?   add_pipr   r   r   r   r   r   r   meta_in_commonconda_packages_tar_bz2rh   use_these_legacy_keysgroupcopy_legacy_md5r   r}   counterpartrecord_indexr  s                          @r6   r   z SubdirData._process_raw_repodata  s   %/!$$%%  	E fb)--h7N4<<;N;N,,,,,66<<..3D3FF 0+6t+<<L=H=NN"%:%%h%G!%!3!3Ht!3!T
t||
D--
  !7!7
 	

 %&<
 t33
 $""
  0
 L
 $%:
 UYYw'
 EIIf%
 eii(89
 EIIf%
 
  6!
" #
$ 		*<a @%
( -.1EE#	 ##
$  LL,008|| VR044Z@ 
 #,,z26**B=Mr0R 	 . #O$8$8$: ;'5':':'<?
"#AcrFX?
 !

 !!#T*E/DEuM'
 !	@"E? " @D""$**Xz"BK"o51@1M1Q1QRW1X-.2A+2N2R2R"3./ V0Y22<@O**51N+88,a014II<-.U
   T
&'=rBU ''-"#34q8T&\*11,?;@	!	@F  /Q?
s   :Pc                l   |j                  di       j                  d      }|r	 t        |      j                         }|r| j                  | j                  k7  r| j
                  j                         }dD ]E  }|j                  |      rt	        d| j                   d	      |j                  |      }|sA|||<   G t        di |j                  d
      S |S |r| j                  S | j                  S # t        $ r6}t	        d| j
                  j                   d| j                   d      |d}~ww xY w)a  
        In repodata_version=1, .tar.bz2 and .conda artifacts are assumed to
        be colocated next to repodata.json, in the same server and directory.

        In repodata_version=2, repodata.json files can define a 'base_url' field
        to override that default assumption. See CEP-15 for more details.

        This method deals with both cases and returns the appropriate value.
        r}   r   zSubdir for z	 at url 'z' has invalid 'base_url'N)authtoken'z9' has 'base_url' with credentials. This is not supported.Tr;   rZ   )
r{   r*   r   
ValueErrorr   rJ   r   r   r   rB   )	r^   r   r<   maybe_base_urlbase_url_partsexcchannel_partskeychannel_credss	            r6   r  zSubdirData._get_base_url  sT    "fb155jA!(!8!=!=!?  D$:$:d>O>O$O !% 1 1 3, <C%))#.* 1 12 35 5  %2$5$5c$:M$.;s+< 0044d4KK!!)))   /  "!$,,"="=!>iHYHYGZ [- - s   C4 4	D3=1D..D3)T)returnr/   )r(  r.   )r(  r$   )r   r%   r3   )r   RepodataState | None)r   r   r   r)  )r   r   r<   boolr(  r   )!rS   rT   rU   rD   classmethodrj   staticmethodr   r   rs   r#   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  rZ   r7   r6   rC   rC   j   s:   G    ,0$K+ +Z. $/>P, % % * * 
 

 
 
 : : 
 

 
 
 W W8++"
I>$'X '+A $Am^%!r7   rC   )	metaclassc                R    d| z  }t        |dddt        j                  d| fd|	      S )Nz%s@0@ 12345678901234567890123456789012r   )	r   r  buildrJ   r?   r  track_featuresbuild_numberr   )r-   r   r?   )feature_namepkg_names     r6   make_feature_recordr8  :  s:    |#H~~.$
 
r7   )r5   r   r(  int)Srb   
__future__r   r   r   collectionsr   r   	functoolsr   	itertoolsr   loggingr   os.pathr	   r
   r   pathlibr   r   typingr   boltons.setutilsr   genericpathr   r   
auxlib.ishr   base.constantsr   r   base.contextr   	common.ior   r   r   common.iteratorsr   rz   common.pathr   
common.urlr   deprecationsr   
exceptionsr   r   r    gateways.disk.deleter!   gateways.repodatar"   r#   r$   r%   r&   r'   r(   r)   r4   models.channelr*   r+   models.match_specr,   models.recordsr-   r.   r/   rS   r|   r   r   REPODATA_HEADER_RErA   r9   rX   rC   r8  rZ   r7   r6   <module>rS     s    3 "   -    * *     ' (  D " P P 9 % ! % S S (   7 ) *@  O  

O
;
;$T $4 M!> M!`r7   