3
ûâdea3  ã               @   s>  d Z ddlZddlZddlZddlZddlmZmZmZm	Z	m
Z
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r¤d
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'eedœdd„Z(ee	e dœdd„Z)eee	e f 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
é    N)ÚAnyÚDictÚIterableÚListÚNewTypeÚOptionalÚTuple)ÚConfigurationErrorÚ!ConfigurationFileCouldNotBeLoaded)Úappdirs)ÚWINDOWS)Ú	getLogger)Ú
ensure_dirÚenumÚKindzpip.inizpip.confÚversionÚhelpÚuserÚglobalÚsiteÚenvzenv-var)ÚUSERÚGLOBALÚSITEÚENVÚENV_VAR)ÚnameÚreturnc             C   s*   | j ƒ jddƒ} | jdƒr&| dd… } | S )zAMake a name consistent regardless of source (environment or file)Ú_ú-z--é   N)ÚlowerÚreplaceÚ
startswith)r   © r$   ú:/tmp/pip-build-red6nood/pip/pip/_internal/configuration.pyÚ_normalize_name2   s    
r&   c             C   s&   d| krdj | ƒ}t|ƒ‚| jddƒS )NÚ.zbKey does not contain dot separated section and key. Perhaps you wanted to use 'global.{}' instead?é   )Úformatr	   Úsplit)r   Úerror_messager$   r$   r%   Ú_disassemble_key:   s
    r,   )r   c              C   st   dd„ t jdƒD ƒ} tjjtjtƒ}tjjtjjdƒt	r<dndtƒ}tjjt j
dƒtƒ}tj| tj|gtj||giS )Nc             S   s   g | ]}t jj|tƒ‘qS r$   )ÚosÚpathÚjoinÚCONFIG_BASENAME)Ú.0r.   r$   r$   r%   ú
<listcomp>F   s    z+get_configuration_files.<locals>.<listcomp>Úpipú~z.pip)r   Úsite_config_dirsr-   r.   r/   ÚsysÚprefixr0   Ú
expanduserr   Úuser_config_dirÚkindsr   r   r   )Zglobal_config_filesZsite_config_fileÚlegacy_config_fileZnew_config_filer$   r$   r%   Úget_configuration_filesD   s    

r<   c                   s¼  e Zd ZdZd6eee ddœ‡ fdd„Zddœdd„Zee	 dœd	d
„Z
eee	ef  dœdd„Ze	edœdd„Ze	eddœdd„Ze	ddœdd„Zddœdd„Zddœdd„Zeee	ef dœdd„ƒZddœdd„Zee	edœdd„Ze	ed œd!d"„Zddœd#d$„Ze	eee	ef  ee	ef d%œd&d'„Zeee	e	f  dœd(d)„Zeeeee	 f  dœd*d+„Zeee	ef d,œd-d.„Z ee	ef dœd/d0„Z!e	edd1œd2d3„Z"e	dœd4d5„Z#‡  Z$S )7Ú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Ú	load_onlyr   c                sj   t ƒ jƒ  |d k	r4|tkr4tdjdj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$   )r1   Úvariantr$   r$   r%   ú
<dictcomp>r   s   z*Configuration.__init__.<locals>.<dictcomp>c             S   s   i | ]
}i |“qS r$   r$   )r1   r@   r$   r$   r%   rA   u   s   )ÚsuperÚ__init__ÚVALID_LOAD_ONLYr	   r)   r/   ÚmapÚreprr>   r?   ÚOVERRIDE_ORDERÚ_parsersÚ_configÚ_modified_parsers)Úselfr>   r?   )Ú	__class__r$   r%   rC   e   s    


zConfiguration.__init__)r   c             C   s   | j ƒ  | js| jƒ  dS )z<Loads configuration from configuration files and environmentN)Ú_load_config_filesr>   Ú_load_environment_vars)rK   r$   r$   r%   Úloadz   s    zConfiguration.loadc             C   s8   | j dk	stdƒ‚y| jƒ d S  tk
r2   dS X dS )z7Returns the file with highest priority in configurationNz)Need to be specified a file to be editingr   )r?   ÚAssertionErrorÚ_get_parser_to_modifyÚ
IndexError)rK   r$   r$   r%   Úget_file_to_edit€   s
    zConfiguration.get_file_to_editc             C   s
   | j jƒ S )z`Returns key-value pairs like dict.items() representing the loaded
        configuration
        )Ú_dictionaryÚitems)rK   r$   r$   r%   rU   ‰   s    zConfiguration.items)Úkeyr   c             C   s2   y
| j | S  tk
r,   td|› �ƒ‚Y nX dS )z#Get a value from the configuration.zNo such key - N)rT   ÚKeyErrorr	   )rK   rV   r$   r$   r%   Ú	get_value�   s    
zConfiguration.get_value)rV   Úvaluer   c             C   st   | j ƒ  | jst‚| jƒ \}}|dk	rTt|ƒ\}}|j|ƒsF|j|ƒ |j|||ƒ || j| j |< | j	||ƒ dS )z$Modify a value in the configuration.N)
Ú_ensure_have_load_onlyr?   rP   rQ   r,   Úhas_sectionÚadd_sectionÚsetrI   Ú_mark_as_modified)rK   rV   rY   ÚfnameÚparserÚsectionr   r$   r$   r%   Ú	set_value–   s    


zConfiguration.set_valuec             C   s    | j ƒ  | jst‚|| j| j kr0td|› �ƒ‚| jƒ \}}|dk	rŽt|ƒ\}}|j|ƒod|j||ƒsntdƒ‚|j	|ƒs‚|j
|ƒ | j||ƒ | j| j |= dS )z#Unset a value in the configuration.zNo such key - Nz4Fatal Internal error [id=1]. Please report as a bug.)rZ   r?   rP   rI   r	   rQ   r,   r[   Úremove_optionrU   Úremove_sectionr^   )rK   rV   r_   r`   ra   r   r$   r$   r%   Úunset_value¨   s    


zConfiguration.unset_valuec          
   C   s\   | j ƒ  xN| jD ]D\}}tjd|ƒ ttjj|ƒƒ t|dƒ�}|j	|ƒ W dQ R X qW dS )z!Save the current in-memory state.zWriting to %sÚwN)
rZ   rJ   ÚloggerÚinfor   r-   r.   ÚdirnameÚopenÚwrite)rK   r_   r`   Úfr$   r$   r%   ÚsaveÃ   s    zConfiguration.savec             C   s$   | j d krtdƒ‚tjd| j ƒ d S )Nz'Needed a specific file to be modifying.z$Will be working with %s variant only)r?   r	   rg   Údebug)rK   r$   r$   r%   rZ   Ô   s    
z$Configuration._ensure_have_load_onlyc             C   s&   i }xt D ]}|j| j| ƒ q
W |S )z3A dictionary representing the loaded configuration.)rG   ÚupdaterI   )rK   Úretvalr@   r$   r$   r%   rT   Ù   s    
zConfiguration._dictionaryc             C   s    t | jƒ ƒ}|tj dd… tjgkr4tjdƒ dS xf|jƒ D ]Z\}}xP|D ]H}| j	dk	rt|| j	krttjd||ƒ qL| j
||ƒ}| j| j||fƒ qLW q>W 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_filesr:   r   r-   Údevnullrg   rn   rU   r?   Ú
_load_filerH   Úappend)rK   Úconfig_filesr@   Úfilesr_   r`   r$   r$   r%   rM   å   s    
z Configuration._load_config_files)r@   r_   r   c             C   sP   t jd||ƒ | j|ƒ}x2|jƒ D ]&}|j|ƒ}| j| j| j||ƒƒ q"W |S )Nz'For variant '%s', will try loading '%s')rg   ÚverboseÚ_construct_parserÚsectionsrU   rI   ro   Ú_normalized_keys)rK   r@   r_   r`   ra   rU   r$   r$   r%   rt   ü   s    

zConfiguration._load_file)r_   r   c             C   s€   t jƒ }tjj|ƒr|y|j|ƒ W nX tk
rN   tdjt	j
dƒƒ|d�‚Y n. t jk
rz } zt|d�‚W Y d d }~X nX |S )Nzcontains invalid {} charactersF)Úreasonr_   )Úerror)ÚconfigparserÚRawConfigParserr-   r.   ÚexistsÚreadÚUnicodeDecodeErrorr
   r)   ÚlocaleÚgetpreferredencodingÚError)rK   r_   r`   r}   r$   r$   r%   ry     s    
zConfiguration._construct_parserc             C   s"   | j tj j| jd| jƒ ƒƒ dS )z.Loads configuration from environment variablesz:env:N)rI   r:   r   ro   r{   Úget_environ_vars)rK   r$   r$   r%   rN     s    z$Configuration._load_environment_vars)ra   rU   r   c             C   s2   i }x(|D ] \}}|d t |ƒ }|||< q
W |S )z×Normalizes 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&   )rK   ra   rU   Ú
normalizedr   ÚvalrV   r$   r$   r%   r{   "  s
    zConfiguration._normalized_keysc             c   sH   xBt jjƒ D ]4\}}|jdƒr|dd… jƒ }|tkr||fV  qW dS )z@Returns a generator with all environmental vars with prefix PIP_ZPIP_é   N)r-   ÚenvironrU   r#   r!   ÚENV_NAMES_IGNORED)rK   rV   rˆ   r   r$   r$   r%   r†   0  s
    
zConfiguration.get_environ_varsc             c   s�   t jjddƒ}|dk	r&tj|gfV  ntjg fV  tƒ }tj|tj fV  | j ob|o`t jj	|ƒ }|rztj
|tj
 fV  tj|tj fV  dS )zYields variant and configuration files associated with it.

        This should be treated like items of a dictionary.
        ÚPIP_CONFIG_FILEN)r-   rŠ   Úgetr:   r   r<   r   r>   r.   r€   r   r   )rK   Úconfig_filerv   Zshould_load_user_configr$   r$   r%   rr   9  s    zConfiguration.iter_config_files)r@   r   c             C   s
   | j | S )z#Get values present in a config file)rI   )rK   r@   r$   r$   r%   Úget_values_in_configW  s    z"Configuration.get_values_in_configc             C   s*   | j s
t‚| j| j  }|s"tdƒ‚|d S )Nz4Fatal Internal error [id=2]. Please report as a bug.r(   éÿÿÿÿ)r?   rP   rH   r	   )rK   Úparsersr$   r$   r%   rQ   [  s    
z#Configuration._get_parser_to_modify)r_   r`   r   c             C   s"   ||f}|| j kr| j j|ƒ d S )N)rJ   ru   )rK   r_   r`   Zfile_parser_tupler$   r$   r%   r^   i  s    
zConfiguration._mark_as_modifiedc             C   s   | j j› d| j›d�S )Nú(ú))rL   Ú__name__rT   )rK   r$   r$   r%   Ú__repr__n  s    zConfiguration.__repr__)N)%r”   Ú
__module__Ú__qualname__Ú__doc__Úboolr   r   rC   rO   ÚstrrS   r   r   r   rU   rX   rb   re   rm   rZ   Úpropertyr   rT   rM   r   rt   ry   rN   r{   r†   r   rr   r�   rQ   r^   r•   Ú__classcell__r$   r$   )rL   r%   r=   W   s0   	
	r=   )r   r   ),r˜   r~   rƒ   r-   r6   Útypingr   r   r   r   r   r   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   r0   r‹   r:   r   r   r   r   r   rG   rD   r”   rg   r&   r,   r<   r=   r$   r$   r$   r%   Ú<module>   s6   $

