U
    S8c!                     @   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-fgapzjtl/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)selfr/   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'   )r0   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environr/   r   r,   r(   formatr5   r    r4   )r0   optiondefaultcastr&   r   r   r   getP   s    



z
Config.getc                 O   s   | j ||S )z-
        Convenient shortcut to get.
        )r<   r0   argskwargsr   r   r   __call__g   s    zConfig.__call__N)r)   r*   r+   r-   r1   r4   staticmethodr5   	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 )	RepositoryEmptyr2   c                 C   s   d S r	   r   )r0   sourceencodingr   r   r   r1   o   s    zRepositoryEmpty.__init__c                 C   s   dS )NFr   r0   keyr   r   r   __contains__r   s    zRepositoryEmpty.__contains__c                 C   s   d S r	   r   rF   r   r   r   __getitem__u   s    zRepositoryEmpty.__getitem__N)r)   r*   r+   DEFAULT_ENCODINGr1   rH   rI   r   r   r   r   rC   n   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)r0   rD   rE   file_r   r   r   r1      s    zRepositoryIni.__init__c                 C   s   |t jkp| j| j|S r	   )r6   r7   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   r1   rH   rI   r   r   r   r   rK   y   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)r0   rD   rE   rO   linekvr   r   r   r1      s    <zRepositoryEnv.__init__c                 C   s   |t jkp|| jkS r	   r6   r7   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   r1   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   r6   listdirr   pathjoinread)r0   rD   Zlsr   r   r   r   r   r1      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-   r1   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)r0   rk   r   r   r   r1      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 )Nr2   )		SUPPORTEDr6   rg   rh   isfiledirnameabspathsep
_find_file)r0   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 )Nr2   rM   )rr   r6   rg   rp   	Exceptionrm   r<   basenamerC   r.   rE   rl   )r0   rg   rs   Z
Repositoryr   r   r   _load   s    
zAutoConfig._loadc                 C   s    t  }tj|jjjj}|S r	   )sys	_getframer6   rg   ro   f_backf_codeco_filename)r0   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   r1   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)r0   r;   r   rZ   r   r   r   r   r1     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;   rZ   )s)r0   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)r0   r&   Zsplitterr   )r0   r   r   r@     s    zCsv.__call__N)
r)   r*   r+   r-   	text_typestringr   listr1   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>0  s     z$Choices.__init__.<locals>.<listcomp>N)flatr;   choices_valid_valuesextend)r0   r   r;   r   r   r   r   r1   #  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   )r0   r&   r   r   r   r   r@   2  s    

 zChoices.__call__)r)   r*   r+   r-   r   r1   r@   r   r   r   r   r     s   r   )#r6   rx   r   r   ior   collectionsr   version_infoZ	PYVERSIONconfigparserr   r3   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> 