U
    dt!                     @   sb  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 eZnd dlmZ eZe	dkr~d	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)SafeConfigParser)r      r   c                 C   s
   |  |S N)	read_fileparserfile r   ,/tmp/pip-unpacked-wheel-bxjtmt_t/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   s0   |   } | tkrdS | tkr dS td|  d S )NTFzInvalid truth value: )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*   0   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)selfr-   r   r   r   __init__@   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.
         )strboolr%   )r.   r$   r   r   r   _cast_booleanC   s    zConfig._cast_booleanc                 C   s   | S r	   r   r#   r   r   r   _cast_do_nothingJ   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environr-   
isinstancer*   r&   formatr4   r2   r3   )r.   optiondefaultcastr$   r   r   r   getN   s    



z
Config.getc                 O   s   | j ||S )z-
        Convenient shortcut to get.
        )r<   r.   argskwargsr   r   r   __call__e   s    zConfig.__call__N)r'   r(   r)   r+   r/   r3   staticmethodr4   	undefinedr<   r@   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 )	RepositoryEmptyr0   c                 C   s   d S r	   r   )r.   sourceencodingr   r   r   r/   m   s    zRepositoryEmpty.__init__c                 C   s   dS )NFr   r.   keyr   r   r   __contains__p   s    zRepositoryEmpty.__contains__c                 C   s   d S r	   r   rF   r   r   r   __getitem__s   s    zRepositoryEmpty.__getitem__N)r'   r(   r)   DEFAULT_ENCODINGr/   rH   rI   r   r   r   r   rC   l   s   rC   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rE   )r   r   r   read_config)r.   rD   rE   file_r   r   r   r/   }   s    zRepositoryIni.__init__c                 C   s   |t jkp| j| j|S r	   )r5   r6   r   
has_optionSECTIONrF   r   r   r   rH      s    
zRepositoryIni.__contains__c                 C   s   | j | j|S r	   )r   r<   rQ   rF   r   r   r   rI      s    zRepositoryIni.__getitem__N)	r'   r(   r)   r+   rQ   rJ   r/   rH   rI   r   r   r   r   rK   w   s
   rK   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 )
NrM   #=   r   r   '")datar   strip
startswithsplitlen)r.   rD   rE   rO   linekvr   r   r   r/      s    <zRepositoryEnv.__init__c                 C   s   |t jkp|| jkS r	   r5   r6   rY   rF   r   r   r   rH      s    zRepositoryEnv.__contains__c                 C   s
   | j | S r	   rY   rF   r   r   r   rI      s    zRepositoryEnv.__getitem__N)r'   r(   r)   r+   rJ   r/   rH   rI   r   r   r   r   rR      s   rR   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)rY   r5   listdirr   pathjoinread)r.   rD   Zlsr   r   r   r   r   r/      s
    
zRepositorySecret.__init__c                 C   s   |t jkp|| jkS r	   ra   rF   r   r   r   rH      s    zRepositorySecret.__contains__c                 C   s
   | j | S r	   rb   rF   r   r   r   rI      s    zRepositorySecret.__getitem__N)rd   )r'   r(   r)   r+   r/   rH   rI   r   r   r   r   rc      s   
rc   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)r.   rk   r   r   r   r/      s    zAutoConfig.__init__c                 C   s^   | j D ]&}tj||}tj|r|  S qtj|}|rZ|tjtjkrZ| |S dS )Nr0   )		SUPPORTEDr5   rg   rh   isfiledirnameabspathsep
_find_file)r.   rg   Z
configfilefilenameparentr   r   r   rr      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 )Nr0   rM   )rr   r5   rg   rp   	Exceptionrm   r<   basenamerC   r,   rE   rl   )r.   rg   rs   Z
Repositoryr   r   r   _load   s    
zAutoConfig._loadc                 C   s    t  }tj|jjjj}|S r	   )sys	_getframer5   rg   ro   f_backf_codeco_filename)r.   framerg   r   r   r   _caller_path   s    zAutoConfig._caller_pathc                 O   s&   | j s| | jp|   | j ||S r	   )rl   rw   rk   r~   r=   r   r   r   r@      s    zAutoConfig.__call__)N)r'   r(   r)   r+   r   rK   rR   rm   rJ   rE   r/   rr   rw   r~   r@   r   r   r   r   rj      s   


rj   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;   	delimiterrZ   post_process)r.   r;   r   rZ   r   r   r   r   r/     s    zCsv.__init__c                    s>    fddt |dd} j|_d|_ fdd|D S )zThe actual transformationc                    s     |  jS r	   )r;   rZ   )s)r.   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   
whitespacewhitespace_splitr   )r.   r$   Zsplitterr   )r.   r   r   r@     s
    zCsv.__call__N)
r'   r(   r)   r+   	text_typestringr   listr/   r@   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>+  s     z$Choices.__init__.<locals>.<listcomp>N)flatr;   choices_valid_valuesextend)r.   r   r;   r   r   r   r   r/     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"   r8   )r.   r$   r   r   r   r   r@   -  s    

 zChoices.__call__)r'   r(   r)   r+   r   r/   r@   r   r   r   r   r     s   r   )#r5   rx   r   r   ior   collectionsr   version_infoZ	PYVERSIONconfigparserr   r1   r   r   unicoderN   rJ   r    r!   r%   ru   r&   objectr*   rB   r,   rC   rK   rR   rc   rj   rl   r   r   r   r   r   r   <module>   s<   
1>