
    wBf;              
      T   d 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mZ ddlmZ ddlmZmZ ddlmZ ddlmZ ddlmZmZmZm Z  ddl!m"Z" ddl#m$Z$ ddl%m&Z&m'Z' erddlm(Z(  ee)      Z*d'dZ+g Z, ed      dddddddejZ                  d   f	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d(d       Z.ddejZ                  d   f	 	 	 	 	 	 	 	 	 d)dZ/d*dZ0d+dZ1d,d Z2	 d-	 	 	 	 	 	 	 d.d!Z3g f	 	 	 	 	 d/d"Z4d0d#Z5d1d$Z6	 	 	 	 d2	 	 	 	 	 	 	 	 	 d3d%Z7	 	 	 	 	 	 	 	 	 	 	 	 d4d&Z8y)5z%Tools for fetching the current index.    )annotations)chain)	getLogger)TYPE_CHECKING)
IndexedSet   )context)ThreadLimitedThreadPoolExecutortime_recorder)ChannelNotAllowedInvalidSpec)initialize_logging)Channelall_channel_urls)PackageType)	MatchSpec)
EMPTY_LINKPackageCacheRecordPackageRecordPrefixRecord   )PackageCacheData)
PrefixData)
SubdirDatamake_feature_record)Anyc                   t         j                  rxt        t        j                  d t         j                  D                    | D ]?  }t        |      j                  }t        fd|D              r-t        t        |             yy)z
    Check if the given channel URLs are allowed by the context's allowlist.

    :param channel_urls: A list of channel URLs to check against the allowlist.
    :raises ChannelNotAllowed: If any URL is not in the allowlist.
    c              3  F   K   | ]  }t        |      j                    y wN)r   	base_urls).0cs     0lib/python3.12/site-packages/conda/core/index.py	<genexpr>z"check_allowlist.<locals>.<genexpr>)   s       )*
$$ s   !c              3  &   K   | ]  }|v  
 y wr    )r!   this_urlallowlist_channel_urlss     r#   r$   z"check_allowlist.<locals>.<genexpr>/   s     Uhx#99Us   N)	r	   allowlist_channelstupler   from_iterabler   r    allr   )channel_urlsurl
these_urlsr(   s      @r#   check_allowlistr0       s|     !!!&  .5.H.H  "

   	6C //JU*UU'55	6 "    	get_indexr&   TNFc                N   t                t        j                  r|d}t        | |||      } t        j                          t        j                  |        t        |        t        | ||      }|rt        ||       |rt        |       t        j                  rt        |       |S )a"  
    Return the index of packages available on the channels

    If prepend=False, only the channels passed in as arguments are used.
    If platform=None, then the current platform is used.
    If prefix is supplied, then the packages installed in that prefix are added.

    :param channel_urls: Channels to include in the index.
    :param prepend: If False, only the channels passed in are used.
    :param platform: Target platform for the index.
    :param use_local: Whether to use local channels.
    :param use_cache: Whether to use cached index information.
    :param unknown: Include unknown packages.
    :param prefix: Path to environment prefix to include in the index.
    :param repodata_fn: Filename of the repodata file.
    :return: A dictionary representing the package index.
    T)	use_cacherepodata_fn)r   r	   offlinecalculate_channel_urlsLAST_CHANNEL_URLSclearextendr0   fetch_index_supplement_index_with_prefix_supplement_index_with_cachetrack_features_supplement_index_with_features)	r-   prependplatform	use_localr5   unknownprefixr6   indexs	            r#   r2   r2   6   s    8 7?),9UL\*L!	{SE%eV4$U+'.Lr1   c                   t         j                  dt        |       z          i }t               5 }fd}|j	                  ||       D ](  }|j                  d |j                         D               * 	 ddd       |S # 1 sw Y   |S xY w)a  
    Fetch the package index from the specified channels.

    :param channel_urls: A list of channel URLs to fetch the index from.
    :param use_cache: Whether to use the cached index data.
    :param index: An optional pre-existing index to update.
    :param repodata_fn: The name of the repodata file.
    :return: A dictionary representing the fetched or updated package index.
    zchannel_urls=c                0    t        t        |             S )N)r6   )r   r   )r.   r6   s    r#   <lambda>zfetch_index.<locals>.<lambda>z   s    *CLk+
 r1   c              3  $   K   | ]  }||f 
 y wr   r&   )r!   recs     r#   r$   zfetch_index.<locals>.<genexpr>~   s     @#s@s   N)logdebugreprr
   mapupdateiter_records)r-   r5   rF   r6   executorsubdir_instantiatorfs      `   r#   r<   r<   h   s     IIo\ 223E	(	* Ah
 1<@ 	AALL@q~~/?@@	A	A LA Ls   AA==Bc                r    t        j                  |      t        fd| j                         D              S )z
    Check if a distribution string matches any package in the index.

    :param index: The package index.
    :param dist_str: The distribution string to match against the index.
    :return: True if there is a match; False otherwise.
    c              3  @   K   | ]  }j                  |        y wr   )match)r!   prec
match_specs     r#   r$   z$dist_str_in_index.<locals>.<genexpr>   s     A$z%As   )r   from_dist_stranyvalues)rF   dist_strrY   s     @r#   dist_str_in_indexr^      s,     ((2JA%,,.AAAr1   c                R   |sJ t        |      j                         D ]  }|| v r|| |   }|j                  |j                  k(  r5|j                  d      xs t        }t        j                  |||      | |<   Z|j                  }|j                         |_        |`	|| |<   || |<    y)z
    Supplement the given index with information from the specified environment prefix.

    :param index: The package index to supplement.
    :param prefix: The path to the environment prefix.
    link)r`   N)
r   rQ   channelgetr   r   from_objectsr.   _Channel__canonical_name_PackageRecord__pkey)rF   rE   prefix_recordcurrent_recordr`   prefix_channels         r#   r=   r=      s     M6#F+88: 1E!"=1N%%)>)>> %((0>J'3'@'@"M(m$ "/!6!6:H:L:L:N7!6'4m$ $1E- =1r1   c                    t        j                         D ]*  }|| v r| |   }t        j                  ||      | |<   &|| |<   , y)zv
    Supplement the given index with packages from the cache.

    :param index: The package index to supplement.
    N)r   get_all_extracted_entriesr   rc   )rF   pcrecrg   s      r#   r>   r>      sK     ";;= !E>"5\N-::>5QE%L E%L!r1   c                r    t        t        j                  | |xs d|xs ddt        j                  dd| 	      S )a8  
    Create a virtual package record.

    :param name: The name of the virtual package.
    :param version: The version of the virtual package, defaults to "0".
    :param build_string: The build string of the virtual package, defaults to "0".
    :return: A PackageRecord representing the virtual package.
    0@ 12345678901234567890123456789012r   )	package_typenameversionbuild_stringra   subdirmd5build_numberfn)r   r   VIRTUAL_SYSTEMr	   rt   )rq   rr   rs   s      r#   _make_virtual_packagery      s?      //3!(S~~.
 
r1   c                b    t        t        j                  |      D ]  }t        |      }|| |<    y)z
    Supplement the given index with virtual feature records.

    :param index: The package index to supplement.
    :param features: A list of feature names to add to the index.
    N)r   r	   r?   r   )rF   featuresfeaturerK   s       r#   r@   r@      s3     //: !'*c
r1   c                    t         j                  j                         D ]5  }t        d|j                   |j
                  |j                        }|| |<   7 y)z
    Loads and populates virtual package records from conda plugins
    and adds them to the provided index, unless there is a naming
    conflict.

    :param index: The package index to supplement.
    __N)r	   plugin_managerget_virtual_packagesry   rq   rr   build)rF   packagerK   s      r#   _supplement_index_with_systemr      sL     ))>>@ #b$7'--Xc
r1   c                 P   ddl m} m} t        j                  j                  d      \  }}||v r|}n&|dk(  ry|j                         r| t        |         }nyt        j                         }|t        j                  k7  r|S ddl	}t        |j                  j                               S )z
    Determine the architecture specification name for the current environment.

    :return: The architecture name if available, otherwise None.
    r   )_arch_namesnon_x86_machines-zosNr   )base.contextr   r   r	   rt   splitisdigitint_native_subdirarchspec.cpustrcpuhost)r   r   target_plattarget_archmachinenative_subdirarchspecs          r#   get_archspec_namer      s     =&~~33C8K&&						c+./**,M&8<<$$&''r1   c                    |rdgt        |       z   } |r| t        j                  z  } ||dfnt        j                  }t	        | |      S )a}  
    Calculate the full list of channel URLs to use based on the given parameters.

    :param channel_urls: Initial list of channel URLs.
    :param prepend: Whether to prepend default channels to the list.
    :param platform: The target platform for the channels.
    :param use_local: Whether to include the local channel.
    :return: The calculated list of channel URLs.
    localnoarch)subdirs)listr	   channelsr   r   )r-   rA   rB   rC   r   s        r#   r8   r8     sM     y4#55(((&.&:x"GL'::r1   c                   t               }t               t               t               t               dfddfd}| r&t        |       j                         D ]
  } ||        |D ]
  } |        srۉrhj	                         }	j                  |	       t        |	      }t        j                  ||||      }
|
D ]
  } ||        |j                  |
       rhrij	                         }j                  |       t        |      }t        j                  ||||      }
|
D ]
  } ||        |j                  |
       rir؉r|D ci c]  }|| }}| t        ||        t        j                  s,dt        j                  v r%t        j                  j                  rt        |       t               }|j!                         D ],  }|j                  g |j"                  |j$                         . |j                  t        j"                         |D ]  }t'        |      }|||<    t)        |       |S c c}w )ae  
    Generate a reduced package index based on the given specifications.

    This function is useful for optimizing the solver by reducing the amount
    of data it needs to consider.

    :param prefix: Path to an environment prefix to include installed packages.
    :param channels: A list of channel names to include in the index.
    :param subdirs: A list of subdirectories to consider for each channel.
    :param specs: A list of MatchSpec objects to filter the packages.
    :param repodata_fn: Filename of the repodata file to use.
    :return: A dictionary representing the reduced package index.
    c                    | j                  d      }|r|vrj                  |       | j                  d      }|r|D ]  }|vsj                  |        yy)z
        Add a package name or track feature from a MatchSpec to the pending set.

        :param spec: The MatchSpec to process.
        rq   r?   N)get_raw_valueadd)specrq   r?   ftr_namecollected_namescollected_track_featurespending_namespending_track_featuress       r#   	push_specz$get_reduced_index.<locals>.push_specJ  sl     !!&)D/d#++,<=* 9#;;*..x89 r1   c                d   	 | j                   } t        | j                               |D ]
  } |        | j                  r$| j                  D ]  } t        |              yy# t        $ r<}t        j                  d| j	                         |j
                  d          Y d}~yd}~ww xY w)z
        Process a package record to collect its dependencies and features.

        :param record: The package record to process.
        z"Skipping %s due to InvalidSpec: %sinvalid_specNr?   )	combined_dependsr   rL   warning	record_id_kwargsr   rq   r?   )recordr   e_specr   r   s        r#   push_recordz&get_reduced_index.<locals>.push_recordY  s    	%66 	)FKK()% 	Ee	  "11 >)8<=> !  	KK4  "		.)
 	s   A* *	B/32B**B/)r   r   r6   r   rD   )r   r   returnNone)r   r   r   r   )r   setr   rQ   popr   r   r   	query_allrP   r=   r	   r7   _argparse_argsrD   r>   r\   r?   r{   r   r   )rE   r   r   specsr6   recordsr   
prefix_recr   rq   new_recordsr   feature_namerK   reduced_indexknown_featuresftr_strr   r   r   r   r   s                    @@@@@r#   get_reduced_indexr   0  sJ   ( lGeO"uEM U9 9>, $V,99; 	$J
#	$ $ 1 $$&D%T?D$..xkK & $F#$NN;'  %1557L$((6L9D$..xkK & $F#$NN;' % 1. *11#S#X1M1%mV<W+++0F0F0N0N
 	%]3 UN##% DB 2 2BS\\BCD'001! !!'* c! "-01 2s   !
I)r-   	list[str]r   r   )r-   
tuple[str]rA   boolrB   
str | NonerC   r   r5   r   rD   zbool | NonerE   r   r6   r   r   dict)
r-   r   r5   r   rF   zdict | Noner6   r   r   r   )rF   dict[Any, Any]r]   r   r   r   )rF   r   rE   r   r   r   )rF   r   r   r   )NN)rq   r   rr   r   rs   r   r   r   )rF   "dict[PackageRecord, PackageRecord]r{   r   r   r   )rF   r   r   r   )r   r   )r&   TNF)
r-   r   rA   r   rB   r   rC   r   r   r   )rE   r   r   r   r   r   r   zlist[MatchSpec]r6   r   r   r   )9__doc__
__future__r   	itertoolsr   loggingr   typingr   boltons.setutilsr   r   r	   	common.ior
   r   
exceptionsr   r   gateways.loggingr   models.channelr   r   models.enumsr   models.match_specr   models.recordsr   r   r   r   package_cache_datar   prefix_datar   subdir_datar   r   r   __name__rL   r0   r9   repodata_fnsr2   r<   r^   r=   r>   ry   r@   r   r   r8   r   r&   r1   r#   <module>r      s(   , "     ' " F 7 1 6 & ) X X 0 # 8 6&   {!++B/... . 	.
 . . . . 
. .f ++B/	  	
 
4	B'1T!" GK
"9C2 FH-9B	
(<  "	;;; ; 	;
 ;0ttt t 	t
 t 
tr1   