U
    d|"                     @   sj  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 ejZ	e	dkr`d dl
mZmZ eZnd dlmZmZ eZe	dkrd	d
 Zndd
 ZdZddddddhZddddddhZdd ZG dd deZG dd deZe ZG dd  d eZG d!d" d"eZG d#d$ d$eZG d%d& d&eZG d'd( d(eZG d)d* d*eZ e  Z!G d+d, d,eZ"G d-d. d.eZ#dS )/    N)shlex)open)OrderedDict)   r   r   )ConfigParserNoOptionError)SafeConfigParserr   )r      r   c                 C   s
   |  |S N)	read_fileparserfile r   ,/tmp/pip-unpacked-wheel-__u_5bmu/decouple.py<lambda>       r   c                 C   s
   |  |S r
   )readfpr   r   r   r   r      r   zUTF-8yyesttrueon1nnoffalseoff0c                 C   s>   t | tr| S |  } | tkr"dS | tkr.dS td|  d S )NTFzInvalid truth value: )
isinstanceboollowerTRUE_VALUESFALSE_VALUES
ValueErrorvaluer   r   r   	strtobool!   s    
r(   c                   @   s   e Zd ZdS )UndefinedValueErrorN)__name__
__module____qualname__r   r   r   r   r)   .   s   r)   c                   @   s   e Zd ZdZdS )	Undefinedz,
    Class to represent undefined type.
    N)r*   r+   r,   __doc__r   r   r   r   r-   2   s   r-   c                   @   sB   e Zd ZdZdd Zdd Zedd Zeefdd	Z	d
d Z
dS )Configz2
    Handle .env file format used by Foreman.
    c                 C   s
   || _ d S r
   )
repository)selfr0   r   r   r   __init__B   s    zConfig.__init__c                 C   s$   t |}|dkrt|S tt|S )zP
        Helper to convert config values to boolean as ConfigParser do.
         )strr!   r(   )r1   r'   r   r   r   _cast_booleanE   s    zConfig._cast_booleanc                 C   s   | S r
   r   r&   r   r   r   _cast_do_nothingL   s    zConfig._cast_do_nothingc                 C   sp   |t jkrt j| }n2|| jkr,| j| }nt|trDtd||}t|trZ| j}n|tkrh| j	}||S )zD
        Return the value for option or default if defined.
        z={} not found. Declare it as envvar or define a default value.)
osenvironr0   r    r-   r)   formatr6   r!   r5   )r1   optiondefaultcastr'   r   r   r   getP   s    



z
Config.getc                 O   s   | j ||S )z-
        Convenient shortcut to get.
        )r=   r1   argskwargsr   r   r   __call__g   s    zConfig.__call__N)r*   r+   r,   r.   r2   r5   staticmethodr6   	undefinedr=   rA   r   r   r   r   r/   =   s   
r/   c                   @   s*   e Zd ZdefddZdd Zdd ZdS )	RepositoryEmptyr3   c                 C   s   d S r
   r   )r1   sourceencodingr   r   r   r2   o   s    zRepositoryEmpty.__init__c                 C   s   dS )NFr   r1   keyr   r   r   __contains__r   s    zRepositoryEmpty.__contains__c                 C   s   d S r
   r   rG   r   r   r   __getitem__u   s    zRepositoryEmpty.__getitem__N)r*   r+   r,   DEFAULT_ENCODINGr2   rI   rJ   r   r   r   r   rD   n   s   rD   c                   @   s0   e Zd ZdZdZefddZdd Zdd Zd	S )
RepositoryIniz0
    Retrieves option keys from .ini files.
    settingsc              	   C   s0   t  | _t||d}t| j| W 5 Q R X d S )NrF   )r   r   r   read_config)r1   rE   rF   file_r   r   r   r2      s    zRepositoryIni.__init__c                 C   s   |t jkp| j| j|S r
   )r7   r8   r   
has_optionSECTIONrG   r   r   r   rI      s    
zRepositoryIni.__contains__c                 C   s4   z| j | j|W S  tk
r.   t|Y nX d S r
   )r   r=   rR   r   KeyErrorrG   r   r   r   rJ      s    zRepositoryIni.__getitem__N)	r*   r+   r,   r.   rR   rK   r2   rI   rJ   r   r   r   r   rL   y   s
   rL   c                   @   s,   e Zd ZdZefddZdd Zdd ZdS )	RepositoryEnvzM
    Retrieves option keys from .env files with fall back to os.environ.
    c              	   C   s   i | _ t||d}|D ]}| }|r|dsd|kr<q|dd\}}| }| }t|dkr|d dkr|d dks|d d	kr|d d	kr|dd }|| j |< qW 5 Q R X d S )
NrN   #=   r	   r   '")datar   strip
startswithsplitlen)r1   rE   rF   rP   linekvr   r   r   r2      s    <zRepositoryEnv.__init__c                 C   s   |t jkp|| jkS r
   r7   r8   r[   rG   r   r   r   rI      s    zRepositoryEnv.__contains__c                 C   s
   | j | S r
   r[   rG   r   r   r   rJ      s    zRepositoryEnv.__getitem__N)r*   r+   r,   r.   rK   r2   rI   rJ   r   r   r   r   rT      s   rT   c                   @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )RepositorySecretz
    Retrieves option keys from files,
    where title of file is a key, content of file is a value
    e.g. Docker swarm secrets
    /run/secrets/c              
   C   sL   i | _ t|}|D ]2}ttj||d}| | j |< W 5 Q R X qd S )Nr)r[   r7   listdirr   pathjoinread)r1   rE   Zlsr   r   r   r   r   r2      s
    
zRepositorySecret.__init__c                 C   s   |t jkp|| jkS r
   rc   rG   r   r   r   rI      s    zRepositorySecret.__contains__c                 C   s
   | j | S r
   rd   rG   r   r   r   rJ      s    zRepositorySecret.__getitem__N)rf   )r*   r+   r,   r.   r2   rI   rJ   r   r   r   r   re      s   
re   c                   @   sR   e Zd ZdZedefdefgZeZ	dddZ
dd Zd	d
 Zdd Zdd ZdS )
AutoConfigz
    Autodetects the config file and type.

    Parameters
    ----------
    search_path : str, optional
        Initial search path. If empty, the default search path is the
        caller's path.

    zsettings.iniz.envNc                 C   s   || _ d | _d S r
   )search_pathconfig)r1   rm   r   r   r   r2      s    zAutoConfig.__init__c                 C   sn   | j D ]&}tj||}tj|r|  S qtj|}|rjtj|tjtjtjkrj| 	|S dS )Nr3   )
	SUPPORTEDr7   ri   rj   isfiledirnamenormcaseabspathsep
_find_file)r1   ri   Z
configfilefilenameparentr   r   r   ru      s    

&
zAutoConfig._find_filec                 C   s^   z|  tj|}W n tk
r.   d}Y nX | jtj|t}t	||| j
d| _d S )Nr3   rN   )ru   r7   ri   rs   	Exceptionro   r=   basenamerD   r/   rF   rn   )r1   ri   rv   Z
Repositoryr   r   r   _load   s    
zAutoConfig._loadc                 C   s    t  }tj|jjjj}|S r
   )sys	_getframer7   ri   rq   f_backf_codeco_filename)r1   frameri   r   r   r   _caller_path   s    zAutoConfig._caller_pathc                 O   s&   | j s| | jp|   | j ||S r
   )rn   rz   rm   r   r>   r   r   r   rA      s    zAutoConfig.__call__)N)r*   r+   r,   r.   r   rL   rT   ro   rK   rF   r2   ru   rz   r   rA   r   r   r   r   rl      s   


rl   c                   @   s,   e Zd ZdZedejefddZdd Z	dS )CsvzK
    Produces a csv parser that return a list of transformed elements.
    ,c                 C   s   || _ || _|| _|| _dS )ai  
        Parameters:
        cast -- callable that transforms the item just before it's added to the list.
        delimiter -- string of delimiters chars passed to shlex.
        strip -- string of non-relevant characters to be passed to str.strip after the split.
        post_process -- callable to post process all casted values. Default is `list`.
        N)r<   	delimiterr\   post_process)r1   r<   r   r\   r   r   r   r   r2     s    zCsv.__init__c                    sN   |dkr   S  fddt|dd} j|_d|_  fdd|D S )zThe actual transformationNc                    s     |  jS r
   )r<   r\   )s)r1   r   r   r     r   zCsv.__call__.<locals>.<lambda>T)posixc                 3   s   | ]} |V  qd S r
   r   ).0r   )	transformr   r   	<genexpr>  s     zCsv.__call__.<locals>.<genexpr>)r   r   r   
whitespacewhitespace_split)r1   r'   Zsplitterr   )r1   r   r   rA     s    zCsv.__call__N)
r*   r+   r,   r.   	text_typestringr   listr2   rA   r   r   r   r   r     s   r   c                   @   s(   e Zd ZdZdedfddZdd ZdS )ChoiceszD
    Allows for cast and validation based on a list of choices.
    Nc                 C   sJ   |pg | _ || _|pg | _g | _| j| j  | jdd | jD  dS )z
        Parameters:
        flat -- a flat list of valid choices.
        cast -- callable that transforms value before validation.
        choices -- tuple of Django-like choices.
        c                 S   s   g | ]\}}|qS r   r   )r   r'   _r   r   r   
<listcomp>3  s     z$Choices.__init__.<locals>.<listcomp>N)flatr<   choices_valid_valuesextend)r1   r   r<   r   r   r   r   r2   &  s    

zChoices.__init__c                 C   s0   |  |}|| jkr(td|| jn|S d S )Nz.Value not in list: {!r}; valid values are {!r})r<   r   r%   r9   )r1   r'   r   r   r   r   rA   5  s    

 zChoices.__call__)r*   r+   r,   r.   r   r2   rA   r   r   r   r   r   !  s   r   )$r7   r{   r   r   ior   collectionsr   version_infoZ	PYVERSIONconfigparserr   r   r4   r   r   unicoderO   rK   r#   r$   r(   rx   r)   objectr-   rC   r/   rD   rL   rT   re   rl   rn   r   r   r   r   r   r   <module>   s<   
1> 