B
    nôb\ùE  ã               @   sÄ   d Z ddlmZ ddlZddlZddlmZ ddlZddl	Z	ddl
Z
ddlmZmZmZ ddlmZ ddlmZ ddlmZmZmZ erddlZG dd	„ d	ƒZG d
d„ dejƒZG dd„ deƒZdS )z—
This module provides user configuration file management features for Spyder

It's based on the ConfigParser module (present in the standard library).
é    )Úprint_functionN)Úget_conf_pathÚget_home_dirÚget_module_source_path)Úcheck_version)Úconfigparser)ÚPY2Úis_text_stringÚto_text_stringc               @   s   e Zd ZdS )Ú	NoDefaultN)Ú__name__Ú
__module__Ú__qualname__© r   r   ú1lib/python3.7/site-packages/spyder/config/user.pyr   &   s   r   c               @   sP   e Zd Z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S )ÚDefaultsConfigzT
    Class used to save defaults to a file and as base class for
    UserConfig
    c             C   s2   t rtj | ¡ ntjj| d d || _|| _d S )N)Zinterpolation)r   ÚcpÚConfigParserÚ__init__ÚnameÚ	subfolder)Úselfr   r   r   r   r   r   2   s
    zDefaultsConfig.__init__c          	   C   sè   | j rV| dtj ¡ x4| j  ¡ D ]&\}}| d|t|ƒ dd¡f ¡ q"W | d¡ xŒ| jD ]‚}| d| ¡ xd| j|  ¡ D ]R\}}|dkr’q€|dk	s¦| j| j	krÄt
|ƒ}d || dd¡f¡}| d| ¡ q€W | d¡ q^W dS )	zz
        Private write method for Python 2
        The one from configparser fails for non-ascii Windows accounts
        z[%s]
z%s = %s
Ú
z
	r   Nz = z%s
)Z	_defaultsÚwriter   ZDEFAULTSECTÚitemsÚstrÚreplaceZ	_sectionsZ_optcreZOPTCREr
   Újoin)r   ÚfpÚkeyÚvalueÚsectionr   r   r   Ú_write:   s    "
zDefaultsConfig._writec             C   sP   |   |¡s|  |¡ t|ƒs$t|ƒ}|r:td|||f ƒ tj | |||¡ dS )z$
        Private set method
        z%s[ %s ] = %sN)Úhas_sectionÚadd_sectionr	   ÚreprÚprintr   r   Úset)r   r!   Úoptionr    Úverboser   r   r   Ú_setO   s    

zDefaultsConfig._setc                s˜   ˆ   ¡ }‡ fdd„}y||ƒ W nr tk
r’   y*t |¡rFt |¡ t d¡ ||ƒ W n2 tk
rŒ } zt	dƒ t	|ƒ W dd}~X Y nX Y nX dS )z;
        Save config into the associated .ini file
        c          	      sT   t r,tj| ddd}ˆ  |¡ W d Q R X n$t| ddd}ˆ  |¡ W d Q R X d S )NÚwzutf-8)Úencoding)r   ÚcodecsÚopenr"   r   )ÚfnameÚ
configfile)r   r   r   Ú_write_filec   s
    z)DefaultsConfig._save.<locals>._write_filegš™™™™™©?zOFailed to write user configuration file to disk, with the exception shown belowN)
ÚfilenameÚEnvironmentErrorÚospÚisfileÚosÚremoveÚtimeZsleepÚ	Exceptionr&   )r   r/   r1   Úer   )r   r   Ú_save[   s    



zDefaultsConfig._savec             C   sD   t | ddƒ| _t | ddƒ| _| jdkr8| jdkr8|  ¡ S |  ¡ S dS )z2Defines the name of the configuration file to use.Ú	_filenameNÚ
_root_path)Úgetattrr<   r=   Ú_filename_globalÚ_filename_projects)r   r   r   r   r2   z   s
    zDefaultsConfig.filenamec             C   s   t  | j| j¡S )z·Create a .ini filename located in the current project directory.
        This .ini files stores the specific project preferences for each
        project created with spyder.
        )r4   r   r=   r<   )r   r   r   r   r@   †   s    z!DefaultsConfig._filename_projectsc             C   sl   | j dkr"t tƒ d| j ¡}|S tƒ }d| jkrRt |d¡}t |¡sRt |¡ t |d| j ¡}|S dS )z}Create a .ini filename located in user home directory.
        This .ini files stores the global spyder preferences.
        Nz.%s.iniÚdefaultsz%s.ini)	r   r4   r   r   r   r   Úisdirr6   Úmkdir)r   Zconfig_fileZfolderr   r   r   r?      s    



zDefaultsConfig._filename_globalc             C   s<   x6|D ].\}}x$|D ]}|| }|   |||d¡ qW qW d S )NF)r*   )r   rA   r!   Úoptionsr(   Ú	new_valuer   r   r   Úset_defaultsž   s    
zDefaultsConfig.set_defaultsN)r   r   r   Ú__doc__r   r"   r*   r;   r2   r@   r?   rF   r   r   r   r   r   -   s   r   c               @   s´   e Zd ZdZdZd+dd„Zd,d	d
„Zd-dd„Zdd„ Zdd„ Z	dd„ Z
d.dd„Zdd„ Zdd„ Zdd„ Zd/dd„Zdd„ Zdd „ Zefd!d"„Zd#d$„ Zd0d%d&„Zd'd(„ Zd)d*„ ZdS )1Ú
UserConfiga¥  
    UserConfig class, based on ConfigParser
    name: name of the config
    defaults: dictionnary containing options
              *or* list of tuples (section_name, options)
    version: version of the configuration file (X.Y.Z format)
    subfolder: configuration file will be saved in %home%/subfolder/%name%.ini
    
    Note that 'get' and 'set' arguments number and type
    differ from the overriden methods
    ÚmainNTFc	             C   s’  t  | ||¡ |rdnd| _|d k	r@t d|¡d kr@td| ƒ‚t|tƒrV| j|fg}|| _	|d k	rp| j
dd |  ¡ }	|r¦yt |	d|	 ¡ W n tk
r¤   Y nX |rŽ|  ¡  |  |¡}
dd	„ }d
d	„ }|  |||¡ ||ƒ||
ƒkr||r$yt |	d|	|
f ¡ W n tk
r"   Y nX t|
ddƒr@| j
dd n|  ||
¡ |sd||ƒ||
ƒkrn|  |
¡ | j|dd |d krŽ|  ¡  d S )Né   r   z^(\d+).(\d+).(\d+)$z8Version number %r is incorrect - must be in X.Y.Z formatF)Úsavez%s.bakc             S   s   | d |   d¡… S )NÚ.)Úfind)Ú_tr   r   r   Ú<lambda>Ì   s    z%UserConfig.__init__.<locals>.<lambda>c             S   s   | d |   d¡… S )NrL   )Úrfind)rN   r   r   r   rO   Í   s    z	%s-%s.bakz2.4.0ú<)r   r   ÚrawÚreÚmatchÚ
ValueErrorÚ
isinstanceÚdictÚDEFAULT_SECTION_NAMErA   Úreset_to_defaultsr2   ÚshutilZcopyfileÚIOErrorÚload_from_iniÚget_versionÚ_save_new_defaultsr   Ú_update_defaultsÚ_remove_deprecated_optionsÚset_versionÚset_as_defaults)r   r   rA   ÚloadÚversionr   ZbackupZraw_modeZremove_obsoleter/   Zold_verZ_majorZ_minorr   r   r   r   µ   sH    



zUserConfig.__init__ú0.0.0c             C   s   |   | jd|¡S )z/Return configuration (not application!) versionrd   )ÚgetrX   )r   rd   r   r   r   r]   ä   s    zUserConfig.get_versionc             C   s   | j | jd||d dS )z,Set configuration (not application!) versionrd   )rK   N)r'   rX   )r   rd   rK   r   r   r   ra   è   s    zUserConfig.set_versionc          	   C   sš   yvt rb|  ¡ }t |¡rty(tj|dd}|  |¡ W dQ R X W qt tk
r^   td|ƒ Y qtX n| j	|  ¡ dd W n t
jk
r”   tdƒ Y nX dS )z;
        Load config from the associated .ini file
        zutf-8)r,   NzFailed reading filez*Warning: File contains no section headers.)r   r2   r4   r5   r-   r.   Zreadfpr[   r&   Úreadr   ZMissingSectionHeaderError)r   r/   r0   r   r   r   r\   ì   s    
zUserConfig.load_from_inic             C   sV   t  ¡ }t|ddƒrtdƒ}nt |  ¡ ¡}t |d¡}| t |d| d ¡¡ |S )zRead old defaultsz3.0.0z<=ZspyderrA   z	defaults-z.ini)	r   r   r   r   r4   Údirnamer2   r   rg   )r   Úold_versionÚold_defaultsÚpathr   r   r   Ú_load_old_defaults   s    
zUserConfig._load_old_defaultsc             C   s4   t d| |d}t | ¡ ¡s0| |¡ | ¡  dS )zSave new defaultsz	defaults-)r   r   N)r   r4   r5   r2   rF   r;   )r   rA   Znew_versionr   Znew_defaultsr   r   r   r^     s
    
zUserConfig._save_new_defaultsc       
      C   sŒ   |   |¡}x||D ]t\}}xj|D ]b}|| }y| ||¡}	W n  tjtjfk
rZ   d}	Y nX |	dkspt|ƒ|	kr|  ||||¡ qW qW dS )z)Update defaults after a change in versionN)rl   rf   r   ÚNoSectionErrorÚNoOptionErrorr
   r*   )
r   rA   ri   r)   rj   r!   rD   r(   rE   Ú	old_valuer   r   r   r_     s    


zUserConfig._update_defaultsc          
   C   s¢   |   |¡}x’| ¡ D ]†}x€|j|| jdD ]l\}}|  ||¡tkr*y2|  ||¡ t| j|| jdƒdkrr|  |¡ W q* t	j
k
r”   |  |¡ Y q*X q*W qW dS )zW
        Remove options which are present in the .ini file but not in defaults
        )rR   r   N)rl   Úsectionsr   rR   Úget_defaultr   Úremove_optionÚlenÚremove_sectionr   rm   )r   ri   rj   r!   r(   Ú_r   r   r   r`   !  s    
z%UserConfig._remove_deprecated_optionsc             C   s   t  |  ¡ ¡ dS )z7
        Remove .ini file associated to config
        N)r6   r7   r2   )r   r   r   r   Úcleanup0  s    zUserConfig.cleanupc             C   sV   g | _ xJ|  ¡ D ]>}i }x$| j|| jdD ]\}}|||< q*W | j  ||f¡ qW dS )z6
        Set defaults from the current config
        )rR   N)rA   rp   r   rR   Úappend)r   r!   Zsecdictr(   r    r   r   r   rb   6  s    zUserConfig.set_as_defaultsc             C   sZ   xH| j D ]>\}}|dks ||krx$|D ]}|| }|  ||||¡ q&W qW |rV|  ¡  dS )z0
        Reset config to Default values
        N)rA   r*   r;   )r   rK   r)   r!   ÚsecrD   r(   r    r   r   r   rY   A  s    
zUserConfig.reset_to_defaultsc             C   s4   |dkr| j }nt|ƒs tdƒ‚t|ƒs0tdƒ‚|S )zB
        Private method to check section and option types
        Nz#Argument 'section' must be a stringz"Argument 'option' must be a string)rX   r	   ÚRuntimeError)r   r!   r(   r   r   r   Ú_check_section_optionM  s    z UserConfig._check_section_optionc             C   s@   |   ||¡}x.| jD ] \}}||kr||kr|| S qW tS dS )zu
        Get Default value for a given (section, option)
        -> useful for type checking in 'get' method
        N)rz   rA   r   )r   r!   r(   rx   rD   r   r   r   rq   Y  s    zUserConfig.get_defaultc          	   C   sh  |   ||¡}|  |¡s4|tkr*t |¡‚n
|  |¡ |  ||¡sh|tkrVt ||¡‚n|  |||¡ |S tj	j
| ||| jd}|  ||¡}t|tƒr t |¡}nÄt|tƒr´t|ƒ}n°t|tƒrÈt|ƒ}nœt|ƒr:trdyD| d¡}yt |¡}t|ƒrü|}W n ttfk
r   Y nX W n ttfk
r6   Y nX n*yt |¡}W n ttfk
rb   Y nX |S )zÅ
        Get an option
        section=None: attribute a default section name
        default: default value (if not specified, an exception
        will be raised if option doesn't exist)
        )rR   zutf-8)rz   r#   r   r   rm   r$   Z
has_optionrn   r'   r   rf   rR   rq   rV   ÚboolÚastZliteral_evalÚfloatÚintr	   r   ÚdecodeÚSyntaxErrorrU   ÚUnicodeEncodeErrorÚUnicodeDecodeError)r   r!   r(   Údefaultr    Údefault_valuerE   r   r   r   rf   f  sF    










zUserConfig.getc             C   s4   |   ||¡}x"| jD ]\}}||kr|||< qW dS )z
        Set Default value for a given (section, option)
        -> called when a new (section, option) is set and no default exists
        N)rz   rA   )r   r!   r(   r„   rx   rD   r   r   r   Úset_defaultš  s    zUserConfig.set_defaultc             C   s²   |   ||¡}|  ||¡}|tkrFtr4t|ƒr4t|ƒ}|}|  |||¡ t|tƒrZt|ƒ}n8t|t	ƒrnt	|ƒ}n$t|t
ƒr‚t
|ƒ}nt|ƒs’t|ƒ}|  ||||¡ |r®|  ¡  dS )zV
        Set an option
        section=None: attribute a default section name
        N)rz   rq   r   r   r	   r%   r…   rV   r{   r}   r~   r*   r;   )r   r!   r(   r    r)   rK   r„   r   r   r   r'   ¤  s$    





zUserConfig.setc             C   s   t j | |¡ |  ¡  d S )N)r   r   rt   r;   )r   r!   r   r   r   rt   ¿  s    zUserConfig.remove_sectionc             C   s   t j | ||¡ |  ¡  d S )N)r   r   rr   r;   )r   r!   r(   r   r   r   rr   Ã  s    zUserConfig.remove_option)NTNNFFF)re   )re   T)F)TFN)FT)r   r   r   rG   rX   r   r]   ra   r\   rl   r^   r_   r`   rv   rb   rY   rz   rq   r   rf   r…   r'   rt   rr   r   r   r   r   rH   ¨   s,     
-



4

rH   )rG   Z
__future__r   r|   r6   Úos.pathrk   r4   rS   rZ   r8   Zspyder.config.baser   r   r   Zspyder.utils.programsr   Zspyder.py3compatr   r   r   r	   r
   r-   r   r   r   rH   r   r   r   r   Ú<module>   s    {