
    si7N                    *   S r SSKJ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  \(       a  SSKJr  SSKJr  S	SKJr  \
" \5      rSS jr\" 5          " S S5      r\" 5       r " S S5      r        SS jr " S S5      rg)z
Configuration file manipulation utilities for conda.

This module provides classes and functions for working with conda configuration
files (.condarc), including reading, writing, and validating configuration keys.
    )annotationsN)Sequence)cached_property)	getLogger)Path)TYPE_CHECKING   )DEFAULT_CONDARC_FILENAME)Callable)Any)Configurationc                 v    SSK Jn   SSKJnJnJnJnJnJn  S nUUUUUU4 H  nU R                  X5        M     g)a6  Register YAML representers for conda enum types.

This function registers custom YAML representers for all conda enum types
to ensure they are serialized as strings rather than complex objects.

This is called once at module load time to ensure representers are available
before any YAML serialization occurs.
r   )RoundTripRepresenterr	   )ChannelPriorityDepsModifierPathConflictSafetyChecksSatSolverChoiceUpdateModifierc                6    U R                  [        U5      5      $ N)represent_strstr)dumperdatas     1lib/python3.13/site-packages/conda/cli/condarc.pyenum_representer5_register_enum_representers.<locals>.enum_representer3   s    ##CI..    N)
ruamel.yaml.representerr   base.constantsr   r   r   r   r   r   add_representer)	r   r   r   r   r   r   r   r   
enum_classs	            r   _register_enum_representersr$      sF     = /
 	
 	,,ZJr   c                  0    \ rS rSrSrS rS rS rS rSr	g)	_MissingSentinelF   zSentinel value to indicate a missing configuration key.

This is used by ConfigurationFile.get_key() to distinguish between a key that
doesn't exist and a key that exists but has a None value.
c                    g)Nz	<MISSING> selfs    r   __repr___MissingSentinel.__repr__M   s    r   c                    g)NFr)   r*   s    r   __bool___MissingSentinel.__bool__P   s    r   c                "    [        U[        5      $ r   )
isinstancer&   )r+   others     r   __eq___MissingSentinel.__eq__S   s    %!122r   c                     [        [        5      $ r   )hashr&   r*   s    r   __hash___MissingSentinel.__hash__V   s    $%%r   r)   N)
__name__
__module____qualname____firstlineno____doc__r,   r/   r4   r8   __static_attributes__r)   r   r   r&   r&   F   s    3&r   r&   c                  r    \ rS rSrSrS
S jr\SS j5       r\SS j5       r\SS j5       r	\SS j5       r
Srg	)ParameterTypeGroups]   aY  
Groups configuration parameters by their parameter type.

Organizes configuration parameters from a Configuration instance into sequence
and map parameters, handling both regular and plugin parameters separately.

This is primarily used by ConfigurationFile to efficiently determine which operations
are valid for different configuration keys.
c                   ^ SSK Jn  U" U4S jTR                  5       5      U l        [	        TS5      (       a+  U" U4S jTR
                  R                  5       5      U l        g0 U l        g)z
Initialize ParameterTypeGroups by grouping parameters by type.

:param context: Configuration instance containing configuration parameters.
r	   )groupby_to_dictc                ,   > TR                  U 5      S   $ Nparameter_type)describe_parameterpcontexts    r   <lambda>.ParameterTypeGroups.__init__.<locals>.<lambda>q   s    g0034DEr   pluginsc                @   > TR                   R                  U 5      S   $ rF   )rN   rH   rI   s    r   rL   rM   x   s    '//<<Q?@PQr   N)common.iteratorsrD   list_parameters_grouped_parameterhasattrrN   _plugin_grouped_parameters)r+   rK   groupbys    ` r   __init__ParameterTypeGroups.__init__h   s^     	B")E##%#
 7I&&.5Q//1/D+
 /1D+r   c                :    U R                   R                  S/ 5      $ )z!List of sequence parameter names.sequencerR   getr*   s    r   sequence_parameters'ParameterTypeGroups.sequence_parameters~   s     &&**:r::r   c                :    U R                   R                  S/ 5      $ )z(List of plugin sequence parameter names.rY   rT   r[   r*   s    r   plugin_sequence_parameters.ParameterTypeGroups.plugin_sequence_parameters   s     ..22:rBBr   c                :    U R                   R                  S/ 5      $ )zList of map parameter names.maprZ   r*   s    r   map_parameters"ParameterTypeGroups.map_parameters   s     &&**5"55r   c                :    U R                   R                  S/ 5      $ )z#List of plugin map parameter names.rc   r_   r*   s    r   plugin_map_parameters)ParameterTypeGroups.plugin_map_parameters   s     ..225"==r   )rR   rT   N)rK   r   returnNone)ri   z	list[str])r:   r;   r<   r=   r>   rV   r   r\   r`   rd   rg   r?   r)   r   r   rA   rA   ]   s^    1, ; ; C C 6 6 > >r   rA   c                l   SSK Jn  SSKJn  UR	                  SS9n[        US5      (       a  UR                  R	                  5       nO/ n[        U 5      [        U5      -
  n[        U5      [        U5      -
  nU(       d  U(       a*  U V	s1 s H  n	SU	 3iM
     nn	Xx-  n
U" SU" U
5       35      eg	s  sn	f )
a  
Validate that provided parameters exist in the configuration context.

Compares the provided parameters with the available parameters in the context
and raises an error if any are invalid.

:param parameters: Regular parameter names to validate.
:param plugin_parameters: Plugin parameter names to validate.
:param context: Configuration instance containing available parameters.
:raises ArgumentError: If any provided parameters are not valid.
r	   )dashlist)ArgumentErrorT)aliasesrN   zplugins.z"Invalid configuration parameters: N)	common.iorl   
exceptionsrm   rQ   rS   rN   set)
parametersplugin_parametersrK   rl   rm   	all_namesall_plugin_names
not_paramsnot_plugin_paramsnameerror_paramss              r   validate_provided_parametersrz      s      %*'''5I w	"""??::<Z3y>1J-.5E1FF&;LM;L4xv.;LM!50,1G0HI
 	
 'Ms   
B1c                     \ rS rSrSr    S         SS jjr\ S   SS jj5       r\ S   SS jj5       r\  S     SS jj5       r	SS jr
SS	 jr\S S
 j5       r\R                  S!S j5       r\S"S j5       r\S#S j5       r\S$S j5       rSS%S jjrSS&S jjrS'S jrS(S)S jjr    S*S jrS+S jrS+S jrS,S jrSrg)-ConfigurationFile   a  
Represents and manipulates a conda configuration (.condarc) file.

Provides methods to read, write, and modify configuration files while
validating keys and maintaining proper structure.

Can be used as a context manager for atomic edits:

    with ConfigurationFile.from_user_condarc() as config:
        config.set_key("channels", ["conda-forge"])
        config.add("channels", "defaults")
    # File is automatically written when exiting the context
Nc                X    Xl         X0l        X l        S U l        U=(       d    S U l        g )Nc                    g r   r)   msgs    r   rL   ,ConfigurationFile.__init__.<locals>.<lambda>   s    tr   )_path_content_context_context_paramswarning_handler)r+   pathrK   contentr   s        r   rV   ConfigurationFile.__init__   s)     
;?.D3Cr   c                    SSK Jn  U " X!S9$ )z
Create a ConfigurationFile instance for the default user .condarc file.

:param context: Optional Configuration instance. If None, uses the global context.
:returns: ConfigurationFile instance configured for the user's .condarc file.
r	   )user_rc_pathr   rK   )base.contextr   )clsrK   r   s      r   from_user_condarc#ConfigurationFile.from_user_condarc   s     	066r   c                    SSK Jn  U " X!S9$ )z
Create a ConfigurationFile instance for the system .condarc file.

:param context: Optional Configuration instance. If None, uses the global context.
:returns: ConfigurationFile instance configured for the system .condarc file.
r	   )sys_rc_pathr   )r   r   )r   rK   r   s      r   from_system_condarc%ConfigurationFile.from_system_condarc   s     	/55r   c                    Uc.  [         R                  R                  S[        R                  5      nU " [        U5      [        -  US9$ )a  
Create a ConfigurationFile instance for an environment-specific .condarc file.

Environment-specific .condarc files are located at `{prefix}/.condarc` and allow
per-environment configuration overrides.

:param prefix: Path to the conda environment. If None, uses $CONDA_PREFIX or sys.prefix.
:param context: Optional Configuration instance. If None, uses the global context.
:returns: ConfigurationFile instance configured for the environment's .condarc file.
CONDA_PREFIXr   )osenvironr[   sysprefixr   r
   )r   r   rK   s      r   from_env_condarc"ConfigurationFile.from_env_condarc   s8      >ZZ^^NCJJ?FV'??QQr   c                    U $ )zEnter the context manager.r)   r*   s    r   	__enter__ConfigurationFile.__enter__  s    r   c                ,    Uc  U R                  5         gg)zDExit the context manager and write changes if no exception occurred.N)write)r+   exc_typeexc_valexc_tbs       r   __exit__ConfigurationFile.__exit__  s    JJL r   c                J    U R                   c  [        S5      eU R                   $ )z
Get the path to the configuration file.

:returns: Path to the configuration file.
:raises AttributeError: If path has not been set.
z(Configuration file path has not been set)r   AttributeErrorr*   s    r   r   ConfigurationFile.path  s$     :: !KLLzzr   c                    Xl         g)zW
Set the path to the configuration file.

:param path: Path to the configuration file.
N)r   )r+   r   s     r   r   r     s	     
r   c                L    U R                   c  SSKJn  Xl         U R                   $ )z
Get the context instance.

If no context was provided during initialization, falls back to the global
conda context singleton. This lazy import is necessary to avoid circular
dependencies at module load time.

:returns: Configuration instance.
r	   )rK   )r   r   rK   )r+   rK   s     r   rK   ConfigurationFile.context'  s"     ==  /#M}}r   c                h    U R                   c  [        U R                  5      U l         U R                   $ r   )r   rA   rK   r*   s    r   context_params ConfigurationFile.context_params;  s+    '#6t||#DD ###r   c                T    U R                   c  U R                  5         U R                   $ )zu
Get the configuration content, reading from file if needed.

:returns: Dictionary containing configuration content.
)r   readr*   s    r   r   ConfigurationFile.contentA  s!     == IIK}}r   c                    SSK Jn  [        U=(       d    U R                  5      n UR	                  US9=(       d    0 U l        U R
                  $ ! [         a    0 U l         U R
                  $ f = f)z
Read configuration content from file.

:param path: Optional path to read from. If None, uses the instance path.
:returns: Dictionary containing configuration content.
r	   yamlr   )common.serializer   r   r   r   r   FileNotFoundError)r+   r   r   s      r   r   ConfigurationFile.readM  sd     	,D&DJJ'	 II4I06BDM }} ! 	DM}}	s   A A.-A.c                    SSK Jn  SSKJn  [	        U=(       d    U R
                  5      n UR                  U R                  US9  g! [         a  nU" SU SU< 35      eSnAff = f)z
Write configuration content to file.

:param path: Optional path to write to. If None, uses the instance path.
:raises CondaError: If the file cannot be written.
r	   )
CondaErrorr   r   z Cannot write to condarc file at z
Caused by N)	 r   r   r   r   r   r   r   OSError)r+   r   r   r   es        r   r   ConfigurationFile.write_  sd     	"+$,$**-	YJJt||$J/ 	Y?v\RSQVWXX	Ys   A 
A%A  A%c                   UR                  S5      tp#US:X  aV  [        U5      S:  aG  [        U R                  S5      (       a,  US   U R                  R                  R                  5       ;   a  gX R                  R                  5       ;  aB  [        U R                  R                  U5      5      nU(       d  U R                  SU< 35        U$ g)z
Check if a configuration key is valid.

:param key: Configuration key to check.
:returns: True if the key is valid, False otherwise.
.rN   r   TzUnknown key: )	splitlenrS   rK   rN   rQ   boolname_for_aliasr   )r+   keyfirstrestexistss        r   
key_existsConfigurationFile.key_existso  s     yy~ YD	Ai00Q4<<//??AA4466$,,55e<=F$$}SG%<=Mr   c                   SSK JnJn  SU;   a  UR                  SS5      OUS4u  pXR                  R
                  ;   a  U R                  R                  U/ 5      nOUS:X  aF  X`R                  R                  ;   a-  U R                  R                  S0 5      R                  U/ 5      nOXR                  R                  ;   a-  U R                  R                  U0 5      R                  U/ 5      nORXR                  R                  ;   a-  U R                  R                  S0 5      R                  U0 5      nOU" SU S35      e[        U[        5      (       a  [        U[        5      (       a3  U R                  U   R                  R                  nU" S	U< S
U S35      eX';   a  U(       a  SOSn	Ub  US-   U-   OUn
SU SU
 SU	 3nUc)  U Vs/ s H  oU:w  d  M
  UPM     sn=opR                  U'   O+U Vs/ s H  oU:w  d  M
  UPM     sn=opR                  U   U'   U R!                  US9  UR#                  U(       a  SO
[%        U5      U5        gs  snf s  snf )ax  
Add an item to a sequence configuration parameter.

:param key: Configuration key name (may contain dots for nested keys).
:param item: Item to add to the sequence.
:param prepend: If True, add to the beginning; if False, add to the end.
:raises CondaValueError: If the key is not a known sequence parameter.
:raises CouldntParseError: If the key should be a list but isn't.
r	   )CondaValueErrorCouldntParseErrorr      NrN   zKey 'z$' is not a known sequence parameter.zkey z should be a list, not topbottomz
Warning: 'z' already in 'z' list, moving to the r   r   )rp   r   r   r   r   r\   r   
setdefaultr`   rd   rg   r2   r   r   	__class__r:   r   insertr   )r+   r   itemprependr   r   subkeyarglistbadlocationmessage_keymessagerJ   s                r   addConfigurationFile.add  s    	D+.#:ciiQ'C;%%999ll--c26G9--HHHll--i<GGPRSG''666ll--c26AA&"MG''===ll--i<GGPRSG!E#.R"STT7H--j#6N6N,,s#--66C#d3'1HQ$OPP? 'uXH060B#)f,K"4&{mCYZbYcdG~:A.O'Q$Yq'.OO,,s+BI6W'QRVYq'6WW,,s+F3  W -GqWt< /P6Ws   	II6	IIc                2   UR                  S5      nU R                  U5      (       d  U[        4$ U R                  R	                  U5      =n(       a  UnUR                  S5      nU R
                  n U H  nXE   nM	     X4$ ! [         a
     U[        4$ f = f)z
Get a configuration value by key.

:param key: Configuration key name (may contain dots for nested keys).
:returns: Tuple of (key, value) or (key, MISSING) if key doesn't exist.
r   )r   r   MISSINGrK   r   r   KeyError)r+   r   	key_partsalias
sub_configparts         r   get_keyConfigurationFile.get_key  s     IIcN	s##<LL//4454CC(I\\
	#!'-
 "
 ?"  	 G|	s   2B 
BBc                   SSK Jn  U R                  U5      (       d	  U" US5      eU R                  R	                  U5      =n(       a  [
        R                  SX5        UnUR                  S5      tpVUS:X  aQ  [        U R                  S5      (       a6  U R                  R                  nU R                  R                  S0 5      nUtpOU R                  nU R                  nUn	UR                  U	5      S   n
U
S:X  a$  [        U5      S	:X  a  UR                  XS
5      X'   gU
S:X  a'  [        U5      S:X  a  X(R                  U	0 5      US	   '   gU" US5      e)z
Set a configuration value for a primitive or map parameter.

:param key: Configuration key name (may contain dots for nested keys).
:param item: Value to set.
:raises CondaKeyError: If the key is unknown or invalid.
r	   CondaKeyErrorunknown parameterz3Key %s is an alias of %s; setting value with latterr   rN   rG   	primitiver   z--set parameterrc   r   invalid parameterN)rp   r   r   rK   r   logwarningr   rS   rN   r   r   rH   r   typify_parameter)r+   r   r   r   aliasedr   r   base_contextbase_configparameter_namerG   s              r   set_keyConfigurationFile.set_key  sE    	/s##%899ll11#6676KKEs Cyy~I'$,,	"B"B<<//L,,11)R@K$(!NT<<L,,K"N%88H
 [(SY!^*6*G*G&7+K' u$TaBF"">26tAw?  %899r   c                l   SSK Jn  UR                  S5      tpEUS:X  aU  [        U R                  S5      (       a:  U R                  R
                  nU R                  R                  S0 5      nUS   n/ nOU R                  nU R                  nUn UR                  U5      S   n	U	S:X  ah  [        U5      S:X  aY  X;  a  US	:w  a	  U" US
5      eS/U R                  U'   X'U   ;  a  U" USU< S35      eXx    V
s/ s H  oU:w  d  M
  U
PM     sn
Xx'   gU" US5      e! [         a
    U" US5      ef = fs  sn
f )z
Remove an item from a sequence configuration parameter.

:param key: Configuration key name.
:param item: Item to remove from the sequence.
:raises CondaKeyError: If the key is unknown, undefined, or the item is not present.
r	   r   r   rN   r   rG   r   rY   channelsundefined in configdefaultszvalue z not present in configr   N)rp   r   r   rS   rK   rN   r   r   rH   r   r   )r+   r   r   r   r   r   r   r   r   rG   is              r   remove_itemConfigurationFile.remove_item  sU    	/yy~I'$,,	"B"B<<//L,,11)R@K!!WND<<L,,K"N	:)<<^L N Z'CIN0!Z/'-BCC0:|^,~66#"fTH4J$K  '6+6at)6+K'  %899%  	:%899	:+s   D 8	D1D1D.c                (   SSK Jn  UR                  S5      nU R                  n USS  H  nXE   nM	     XCS   	 g! [         aL    U R
                  R                  U5      =n(       a    U R                  U5      s $ ! U a     Of = fU" US5      ef = f)z
Remove a configuration key entirely.

:param key: Configuration key name (may contain dots for nested keys).
:raises CondaKeyError: If the key is undefined in the config.
r	   r   r   Nr   )rp   r   r   r   r   rK   r   
remove_key)r+   r   r   r   r   r   r   s          r   r  ConfigurationFile.remove_key1  s     	/IIcN	\\
	<!#2'-
 'R=) 	<33C88u8??511$ %:;;	<s-   ; ,B(A;8B;BBBB)r   r   r   r   r   )NNNN)
r   $str | os.PathLike[str] | Path | NonerK   Configuration | Noner   zdict[str, Any] | Noner   zCallable[[str], None] | Noneri   rj   r   )rK   r  ri   r|   )NN)r   r  rK   r  ri   r|   )ri   r|   ri   rj   )ri   str | os.PathLike[str] | Path)r   r  ri   rj   )ri   r   )ri   rA   )ri   dict[str, Any])r   r  ri   r  )r   r  ri   rj   )r   r   ri   r   )F)r   r   r   r   r   r   ri   rj   )r   r   ri   z"tuple[str, Any | _MissingSentinel])r   r   r   r   ri   rj   )r   r   ri   rj   )r:   r;   r<   r=   r>   rV   classmethodr   r   r   r   r   propertyr   setterrK   r   r   r   r   r   r   r   r   r   r  r?   r)   r   r   r|   r|      s     6:(,)-8<E2E &E '	E
 6E 
E -17*7	7 7 -16*6	6 6  8<(,R4R &R 
	R R(
 
 
 
[[   & $ $
 	 	$Y 4-=^ 
,<+:Z,:\<r   r|   r  )rr   Sequence[str]rs   r  rK   r   ri   rj   )r>   
__future__r   r   r   collections.abcr   	functoolsr   loggingr   pathlibr   typingr   common.configurationr
   r   r   r   r:   r   r$   r&   r   rA   rz   r|   r)   r   r   <module>r     s    # 	 
 $ %     ;(4 KH  & &( 
3> 3>l#
#
$#
 #
 
	#
LO< O<r   