o
    i8                     @  s"  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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 dd	lmZ dd
lmZmZ ejZedeZerTdndZdZeddddddZejejej ej!ej"fZ#ejejej fZ$ee%Z&d"ddZ'd#ddZ(d$ddZ)G d d! d!Z*dS )%a  Configuration management setup

Some terminology:
- name
  As written in config files.
- value
  Value associated with a name
- key
  Name combined with it's section (section.name)
- variant
  A single word describing where the configuration key-value pair came from
    )annotationsN)Iterable)AnyNewType)ConfigurationError!ConfigurationFileCouldNotBeLoaded)appdirs)WINDOWS)	getLogger)
ensure_direnumKindzpip.inizpip.conf)versionhelpuserglobalZsiteenvzenv-var)USERGLOBALSITEENVENV_VARnamestrreturnc                 C  s   |   dd} | d} | S )zAMake a name consistent regardless of source (environment or file)_-z--)lowerreplaceremoveprefix)r    r    ;lib/python3.10/site-packages/pip/_internal/configuration.py_normalize_name5   s   
r"   	list[str]c                 C  s(   d| vrd|  d}t || ddS )N.zVKey does not contain dot separated section and key. Perhaps you wanted to use 'global.z
' instead?   )r   split)r   Zerror_messager    r    r!   _disassemble_key<   s   r'   dict[Kind, list[str]]c                  C  st   dd t dD } tjtjt}tjtjdt	rdndt}tjt 
dt}tj| tj|gtj||giS )Nc                 S  s   g | ]	}t j|tqS r    )ospathjoinCONFIG_BASENAME).0r*   r    r    r!   
<listcomp>G   s    z+get_configuration_files.<locals>.<listcomp>Zpip~z.pip)r   Zsite_config_dirsr)   r*   r+   sysprefixr,   
expanduserr	   Zuser_config_dirkindsr   r   r   )Zglobal_config_filesZsite_config_fileZlegacy_config_fileZnew_config_filer    r    r!   get_configuration_filesF   s   


r4   c                      s   e Zd ZdZdEdF fd	d
ZdGddZdHddZdIddZdJddZdKddZ	dLddZ
dGddZdGdd ZedMd"d#ZdGd$d%ZdNd*d+ZdOd,d-ZdGd.d/ZdPd3d4ZdQd6d7ZdRd9d:ZdSd;d<ZdTd>d?ZdUdAdBZdVdCdDZ  ZS )WConfigurationa  Handles management of configuration.

    Provides an interface to accessing and managing configuration files.

    This class converts provides an API that takes "section.key-name" style
    keys and stores the value associated with it as "key-name" under the
    section "section".

    This allows for a clean interface wherein the both the section and the
    key-name are preserved in an easy to manage form in the configuration files
    and the data stored is also nice.
    Nisolatedbool	load_onlyKind | Noner   Nonec                   sj   t    |d ur|tvrtddttt|| _|| _	dd t
D | _dd t
D | _g | _d S )Nz5Got invalid value for load_only - should be one of {}z, c                 S  s   i | ]}|g qS r    r    r-   variantr    r    r!   
<dictcomp>t       z*Configuration.__init__.<locals>.<dictcomp>c                 S  s   i | ]}|i qS r    r    r;   r    r    r!   r=   w   r>   )super__init__VALID_LOAD_ONLYr   formatr+   mapreprr6   r8   OVERRIDE_ORDER_parsers_config_modified_parsers)selfr6   r8   	__class__r    r!   r@   g   s    

zConfiguration.__init__c                 C  s   |    | js|   dS dS )z<Loads configuration from configuration files and environmentN)_load_config_filesr6   _load_environment_varsrI   r    r    r!   load|   s   zConfiguration.load
str | Nonec                 C  s6   | j dus	J dz|  d W S  ty   Y dS w )z7Returns the file with highest priority in configurationNz)Need to be specified a file to be editingr   )r8   _get_parser_to_modify
IndexErrorrN   r    r    r!   get_file_to_edit   s   zConfiguration.get_file_to_editIterable[tuple[str, Any]]c                 C  s
   | j  S )z`Returns key-value pairs like dict.items() representing the loaded
        configuration
        )_dictionaryitemsrN   r    r    r!   rV      s   
zConfiguration.itemskeyr   r   c                 C  sZ   |}t |}zi }| j D ]}|| q|| W S  ty,   t| td| w )z#Get a value from the configuration.No such key - )r"   rU   valuesupdateKeyErrorr'   r   )rI   rW   orig_keyZclean_configZfile_valuesr    r    r!   	get_value   s   
zConfiguration.get_valuevaluec                 C  s   t |}|   | jsJ |  \}}|dur.t|\}}||s'|| |||| | j| j 	|i  || j| j | |< | 
|| dS )z$Modify a value in the configuration.N)r"   _ensure_have_load_onlyr8   rQ   r'   has_sectionZadd_sectionsetrG   
setdefault_mark_as_modified)rI   rW   r^   fnameparsersectionr   r    r    r!   	set_value   s   


zConfiguration.set_valuec                 C  s   |}t |}|   | jsJ |  \}}|| j| j | vr.|| j| j vr.td| |durWt|\}}||rC|||sGtd|	|sQ|
| | || z| j| j | |= W dS  tyt   | j| j |= Y dS w )z#Unset a value in the configuration.rX   Nz4Fatal Internal error [id=1]. Please report as a bug.)r"   r_   r8   rQ   rG   r   r'   r`   Zremove_optionrV   Zremove_sectionrc   r[   )rI   rW   r\   rd   re   rf   r   r    r    r!   unset_value   s2   



zConfiguration.unset_valuec                 C  s   |    | jD ]D\}}td| ttj| zt|d}|	| W d   n1 s/w   Y  W q t
yK } z
td| d| d}~ww dS )z!Save the current in-memory state.zWriting to %swNz:An error occurred while writing to the configuration file z: )r_   rH   loggerinfor   r)   r*   dirnameopenwriteOSErrorr   )rI   rd   re   ferrorr    r    r!   save   s(   zConfiguration.savec                 C  s$   | j d u r	tdtd| j  d S )Nz'Needed a specific file to be modifying.z$Will be working with %s variant only)r8   r   rj   debugrN   r    r    r!   r_      s   
z$Configuration._ensure_have_load_onlydict[str, dict[str, Any]]c                 C  s"   i }t D ]
}|| j|  q|S )z3A dictionary representing the loaded configuration.)rE   rZ   rG   )rI   Zretvalr<   r    r    r!   rU      s   zConfiguration._dictionaryc                 C  s   t |  }|tj dd tjgkrtd dS | D ]+\}}|D ]$}| j	dur8|| j	kr8td|| q$| 
||}| j| ||f q$qdS )z,Loads configuration from configuration filesr   r%   zZSkipping loading configuration files due to environment's PIP_CONFIG_FILE being os.devnullNz Skipping file '%s' (variant: %s))dictiter_config_filesr3   r   r)   devnullrj   rs   rV   r8   
_load_filerF   append)rI   config_filesr<   filesrd   re   r    r    r!   rL      s   z Configuration._load_config_filesr<   r   rd   RawConfigParserc                 C  sb   t d|| | |}| D ]}||}| j| |i  | j| | | || q|S )Nz'For variant '%s', will try loading '%s')	rj   verbose_construct_parserZsectionsrV   rG   rb   rZ   _normalized_keys)rI   r<   rd   re   rf   rV   r    r    r!   rx     s   

zConfiguration._load_filec              
   C  s|   t  }tj|r<td}z
|j||d W |S  ty*   t	d| d|d t j
y; } zt	|dd }~ww |S )NF)encodingzcontains invalid z characters)reasonrd   )rq   )configparserr|   r)   r*   existslocalegetpreferredencodingreadUnicodeDecodeErrorr   Error)rI   rd   re   Zlocale_encodingrq   r    r    r!   r~   !  s    



zConfiguration._construct_parserc                 C  s:   | j tj di  | j tj d | d|   dS )z.Loads configuration from environment variablesz:env:N)rG   r3   r   rb   rZ   r   get_environ_varsrN   r    r    r!   rM   6  s   z$Configuration._load_environment_varsrf   rV   dict[str, Any]c                 C  s.   i }|D ]\}}|d t | }|||< q|S )zNormalizes items to construct a dictionary with normalized keys.

        This routine is where the names become keys and are made the same
        regardless of source - configuration files or environment.
        r$   )r"   )rI   rf   rV   Z
normalizedr   valrW   r    r    r!   r   =  s
   
zConfiguration._normalized_keysIterable[tuple[str, str]]c                 c  sF    t j D ]\}}|dr |dd  }|tvr ||fV  qdS )z@Returns a generator with all environmental vars with prefix PIP_ZPIP_   N)r)   environrV   
startswithr   ENV_NAMES_IGNORED)rI   rW   r   r   r    r    r!   r   K  s   

zConfiguration.get_environ_vars Iterable[tuple[Kind, list[str]]]c                 c  s    t jdd}t }tj|tj fV  | j o |ot j| }|r,tj	|tj	 fV  tj
|tj
 fV  |durBtj|gfV  dS tjg fV  dS )a  Yields variant and configuration files associated with it.

        This should be treated like items of a dictionary. The order
        here doesn't affect what gets overridden. That is controlled
        by OVERRIDE_ORDER. However this does control the order they are
        displayed to the user. It's probably most ergonomic to display
        things in the same order as OVERRIDE_ORDER
        ZPIP_CONFIG_FILEN)r)   r   getr4   r3   r   r6   r*   r   r   r   r   )rI   Zenv_config_filerz   Zshould_load_user_configr    r    r!   rv   T  s   zConfiguration.iter_config_filesc                 C  s
   | j | S )z#Get values present in a config file)rG   )rI   r<   r    r    r!   get_values_in_configt  s   
z"Configuration.get_values_in_configtuple[str, RawConfigParser]c                 C  s*   | j sJ | j| j  }|std|d S )Nz4Fatal Internal error [id=2]. Please report as a bug.)r8   rF   r   )rI   parsersr    r    r!   rQ   x  s   
z#Configuration._get_parser_to_modifyre   c                 C  s&   ||f}|| j vr| j | d S d S N)rH   ry   )rI   rd   re   Zfile_parser_tupler    r    r!   rc     s   
zConfiguration._mark_as_modifiedc                 C  s   | j j d| jdS )N())rK   __name__rU   rN   r    r    r!   __repr__  s   zConfiguration.__repr__r   )r6   r7   r8   r9   r   r:   )r   r:   )r   rP   )r   rT   )rW   r   r   r   )rW   r   r^   r   r   r:   )rW   r   r   r:   )r   rt   )r<   r   rd   r   r   r|   )rd   r   r   r|   )rf   r   rV   rT   r   r   )r   r   )r   r   )r<   r   r   r   )r   r   )rd   r   re   r|   r   r:   )r   r   )r   
__module____qualname____doc__r@   rO   rS   rV   r]   rg   rh   rr   r_   propertyrU   rL   rx   r~   rM   r   r   rv   r   rQ   rc   r   __classcell__r    r    rJ   r!   r5   Y   s0    


	



"







	
 

r5   )r   r   r   r   )r   r   r   r#   )r   r(   )+r   Z
__future__r   r   r   r)   r0   Zcollections.abcr   typingr   r   Zpip._internal.exceptionsr   r   Zpip._internal.utilsr   Zpip._internal.utils.compatr	   Zpip._internal.utils.loggingr
   Zpip._internal.utils.miscr   r   r|   r   r   r,   r   r3   r   r   r   r   r   rE   rA   r   rj   r"   r'   r4   r5   r    r    r    r!   <module>   s>    




