B
    =)H[4  ã               @   sð   d Z ddlZddlZddl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mZmZ ddlmZmZ ddlmZ er°dd	lmZmZmZmZmZmZmZ ejZed
eƒZe  e!¡Z"dd„ Z#dd„ Z$edddddd�Z%G dd„ de&ƒ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)Úsix)Úconfigparser)ÚConfigurationError)Úlegacy_config_fileÚnew_config_fileÚrunning_under_virtualenvÚsite_config_filesÚvenv_config_file)Ú
ensure_dirÚenum)ÚMYPY_CHECK_RUNNING)ÚAnyÚDictÚIterableÚListÚNewTypeÚOptionalÚTupleÚKindc             C   s*   |   ¡  dd¡} |  d¡r&| dd… } | S )zFMake a name consistent regardless of source (environment or file)
    Ú_ú-z--é   N)ÚlowerÚreplaceÚ
startswith)Úname© r   ú\C:\Users\HIRONO~1\AppData\Local\Temp\pip-install-qz7kpjmn\pip\pip\_internal\configuration.pyÚ_normalize_name'   s    
r   c             C   s   |   dd¡S )NÚ.é   )Úsplit)r   r   r   r   Ú_disassemble_key1   s    r"   ÚuserÚglobalÚvenvÚenvzenv-var)ÚUSERÚGLOBALÚVENVÚENVÚENV_VARc                   s¶   e Zd ZdZd)‡ fdd„	Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zedd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Z‡  ZS )*Ú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.
    Nc          
      s¨   t t| ƒ ¡  tjtjtjd g}||krJtd d 	t
t|d d… ƒ¡¡ƒ‚|| _|| _tjtjtjtjtjg| _ddg| _dd„ | jD ƒ| _dd„ | jD ƒ| _g | _d S )	Nz5Got invalid value for load_only - should be one of {}z, éÿÿÿÿÚversionÚhelpc             S   s   i | ]
}g |“qS r   r   )Ú.0Úvariantr   r   r   ú
<dictcomp>d   s   z*Configuration.__init__.<locals>.<dictcomp>c             S   s   i | ]
}i |“qS r   r   )r0   r1   r   r   r   r2   g   s   )Úsuperr,   Ú__init__Úkindsr'   r(   r)   r   ÚformatÚjoinÚmapÚreprÚisolatedÚ	load_onlyr*   r+   Ú_override_orderÚ_ignore_env_namesÚ_parsersÚ_configÚ_modified_parsers)Úselfr:   r;   Ú_valid_load_only)Ú	__class__r   r   r4   N   s    
zConfiguration.__init__c             C   s   |   ¡  | js|  ¡  dS )zELoads configuration from configuration files and environment
        N)Ú_load_config_filesr:   Ú_load_environment_vars)rA   r   r   r   Úloadl   s    zConfiguration.loadc             C   s8   | j dk	stdƒ‚y|  ¡ d S  tk
r2   dS X dS )z@Returns the file with highest priority in configuration
        Nz)Need to be specified a file to be editingr   )r;   ÚAssertionErrorÚ_get_parser_to_modifyÚ
IndexError)rA   r   r   r   Úget_file_to_editt   s    zConfiguration.get_file_to_editc             C   s
   | j  ¡ S )z`Returns key-value pairs like dict.items() representing the loaded
        configuration
        )Ú_dictionaryÚitems)rA   r   r   r   rL   €   s    zConfiguration.itemsc             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)rK   ÚKeyErrorr   r6   )rA   Úkeyr   r   r   Ú	get_value‡   s    
zConfiguration.get_valuec             C   sj   |   ¡  |  ¡ \}}|dk	rJt|ƒ\}}| |¡s<| |¡ | |||¡ || j| j |< |  ||¡ dS )z-Modify a value in the configuration.
        N)	Ú_ensure_have_load_onlyrH   r"   Úhas_sectionÚadd_sectionÚsetr?   r;   Ú_mark_as_modified)rA   rN   ÚvalueÚfnameÚparserÚsectionr   r   r   r   Ú	set_value�   s    

zConfiguration.set_valuec       	      C   sÔ   |   ¡  || j| j kr&td |¡ƒ‚|  ¡ \}}|dk	rÂt|ƒ\}}d}| |¡r`| ||¡}|rºt	| 
|¡ƒ}yt |¡}W n tk
r˜   d}Y nX |dkr¬| |¡ |  ||¡ ntdƒ‚| j| j |= dS )z,Unset a value in the configuration.
        zNo such key - {}NFz4Fatal Internal error [id=1]. Please report as a bug.)rP   r?   r;   r   r6   rH   r"   rQ   Úremove_optionÚiterrL   r   ÚnextÚStopIterationÚremove_sectionrT   )	rA   rN   rV   rW   rX   r   Úmodified_somethingÚsection_iterÚvalr   r   r   Úunset_value£   s*    


zConfiguration.unset_valuec          
   C   s\   |   ¡  xN| jD ]D\}}t d|¡ ttj |¡ƒ t|dƒ�}| 	|¡ W dQ R X qW dS )z)Save the currentin-memory state.
        zWriting to %sÚwN)
rP   r@   ÚloggerÚinfor
   ÚosÚpathÚdirnameÚopenÚwrite)rA   rV   rW   Úfr   r   r   ÚsaveÊ   s    zConfiguration.savec             C   s$   | j d krtdƒ‚t d| j ¡ d S )Nz'Needed a specific file to be modifying.z$Will be working with %s variant only)r;   r   rd   Údebug)rA   r   r   r   rP   Ý   s    
z$Configuration._ensure_have_load_onlyc             C   s(   i }x| j D ]}| | j| ¡ qW |S )z<A dictionary representing the loaded configuration.
        )r<   Úupdater?   )rA   Úretvalr1   r   r   r   rK   ã   s    zConfiguration._dictionaryc             C   s    t |  ¡ ƒ}|tj dd… tjgkr4t d¡ dS xf| ¡ D ]Z\}}xP|D ]H}| j	dk	rt|| j	krtt d||¡ qL|  
||¡}| j|  ||f¡ qLW q>W dS )z5Loads configuration from configuration files
        r   r    zZSkipping loading configuration files due to environment's PIP_CONFIG_FILE being os.devnullNz Skipping file '%s' (variant: %s))ÚdictÚ_iter_config_filesr5   r*   rf   Údevnullrd   rm   rL   r;   Ú
_load_filer>   Úappend)rA   Úconfig_filesr1   ÚfilesrV   rW   r   r   r   rD   ñ   s    

z Configuration._load_config_filesc             C   sP   t  d||¡ |  |¡}x2| ¡ D ]&}| |¡}| j|  |  ||¡¡ q"W |S )Nz'For variant '%s', will try loading '%s')rd   rm   Ú_construct_parserÚsectionsrL   r?   rn   Ú_normalized_keys)rA   r1   rV   rW   rX   rL   r   r   r   rs     s    

zConfiguration._load_filec             C   sR   t  ¡ }tj |¡rNy| |¡ W n* tk
rL   tdt 	d¡|f ƒ‚Y nX |S )NzgERROR: Configuration file contains invalid %s characters.
Please fix your configuration, located at %s
F)
r   ÚRawConfigParserrf   rg   ÚexistsÚreadÚUnicodeDecodeErrorr   ÚlocaleÚgetpreferredencoding)rA   rV   rW   r   r   r   rw     s    zConfiguration._construct_parserc             C   s"   | j tj  |  d|  ¡ ¡¡ dS )z7Loads configuration from environment variables
        z:env:N)r?   r5   r+   rn   ry   Ú_get_environ_vars)rA   r   r   r   rE   )  s    z$Configuration._load_environment_varsc             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   )rA   rX   rL   Ú
normalizedr   ra   rN   r   r   r   ry   1  s
    zConfiguration._normalized_keysc             c   sV   xPt j ¡ D ]B\}}| d¡o2|dd…  ¡ | jk}|r|dd…  ¡ |fV  qW dS )z@Returns a generator with all environmental vars with prefix PIP_ÚPIP_é   N)rf   ÚenvironrL   r   r   r=   )rA   rN   ra   Úshould_be_yieldedr   r   r   r€   >  s
    
zConfiguration._get_environ_varsc             c   sˆ   t j dd¡}|dk	r&tj|gfV  ntjg fV  tjttƒfV  | j oZ|oXt j	 
|¡ }|rptjttgfV  tƒ r„tjtg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)rf   r„   Úgetr5   r*   r(   Úlistr   r:   rg   r{   r'   r   r   r   r)   r	   )rA   Úconfig_fileÚshould_load_user_configr   r   r   rq   J  s    	z Configuration._iter_config_filesc             C   s    | j | j }|stdƒ‚|d S )Nz4Fatal Internal error [id=2]. Please report as a bug.r-   )r>   r;   r   )rA   Úparsersr   r   r   rH   h  s
    z#Configuration._get_parser_to_modifyc             C   s"   ||f}|| j kr| j  |¡ d S )N)r@   rt   )rA   rV   rW   Úfile_parser_tupler   r   r   rT   v  s    
zConfiguration._mark_as_modified)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r4   rF   rJ   rL   rO   rY   rb   rl   rP   ÚpropertyrK   rD   rs   rw   rE   ry   r€   rq   rH   rT   Ú__classcell__r   r   )rC   r   r,   @   s(   	'r,   )(r�   r~   Úloggingrf   Úpip._vendorr   Úpip._vendor.six.movesr   Úpip._internal.exceptionsr   Úpip._internal.locationsr   r   r   r   r	   Úpip._internal.utils.miscr
   r   Úpip._internal.utils.typingr   Útypingr   r   r   r   r   r   r   rz   Ústrr   Ú	getLoggerr�   rd   r   r"   r5   Úobjectr,   r   r   r   r   Ú<module>   s.   $


