a
   q+                   @   sv  d dl mZmZmZ d dlZd dlZd dlZd dl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mZmZmZ ddlmZmZ eeZerd dlmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ e	j%d	krej&Z'ne"Z'e	j%d
kreZ(nee" Z(e)dej*Z+dd Z,G dd dZ-dd Z.edd Z/d&ddZ0d'ddZ1dd Z2dd Z3d(dd Z4d)d"d#Z5d*d$d%Z6dS )+    )absolute_importprint_functionunicode_literalsN)OrderedDict)contextmanager   )IS_TYPE_CHECKINGPY2StringIOto_env)Bindingparse_stream)
DictIterableIteratorMatchOptionalPatternUnionTextIOTuple)      )r   r   zh
    \$\{
        (?P<name>[^\}:]*)
        (?::-
            (?P<default>[^\}]*)
        )?
    \}
    c                 c   s*   | D ] }|j rtd|jj |V  qd S )Nz;Python-dotenv could not parse statement starting at line %s)errorloggerwarningoriginalline)Zmappingsmapping r    //usr/lib/python3.9/site-packages/dotenv/main.pywith_warn_for_invalid_lines.   s    r"   c                   @   sD   e Zd ZdddZedd Zdd	 Zd
d ZdddZdd Z	dS )DotEnvFNTc                 C   s"   || _ d | _|| _|| _|| _d S N)dotenv_path_dictverboseencodinginterpolate)selfr%   r'   r(   r)   r    r    r!   __init__;   s
    zDotEnv.__init__c                 c   s   t | jtr| jV  njtj| jr^tj| j| jd}|V  W d    q1 sR0    Y  n"| j	rvt
d| jprd tdV  d S )N)r(   z3Python-dotenv could not find configuration file %s..env )
isinstancer%   r
   ospathisfileioopenr(   r'   r   info)r*   streamr    r    r!   _get_streamC   s    
&zDotEnv._get_streamc                 C   s6   | j r| j S | jr t|  }nt|  }|| _ |S )zReturn dotenv as dict)r&   r)   resolve_nested_variablesparser   )r*   valuesr    r    r!   dictP   s    zDotEnv.dictc                 c   sV   |   :}tt|D ]}|jd ur|j|jfV  qW d    n1 sH0    Y  d S r$   )r6   r"   r   keyvalue)r*   r5   r   r    r    r!   r8   ^   s    

zDotEnv.parsec                 C   sD   |    D ]2\}}|tjv r$|s$q|durt|tjt|< qdS )zH
        Load the current dotenv as system environemt variable.
        NT)r:   itemsr/   environr   )r*   overridekvr    r    r!   set_as_environment_variablese   s    z#DotEnv.set_as_environment_variablesc                 C   s2   |   }||v r|| S | jr.td|| j dS )z	
        zKey %s not found in %s.N)r:   r'   r   r   r%   )r*   r;   datar    r    r!   getr   s    z
DotEnv.get)FNT)F)
__name__
__module____qualname__r+   r   r6   r:   r8   rB   rD   r    r    r    r!   r#   9   s   


r#   c                 C   s   t | dd|S )zl
    Gets the value of a given key from the given .env

    If the .env path given doesn't exist, fails
    T)r'   )r#   rD   )r%   Z
key_to_getr    r    r!   get_key   s    rH   c              	   c   s   zt j| sDt| d}|d W d    n1 s:0    Y  tjdddD}t| }||fV  W d    n1 s~0    Y  W d    n1 s0    Y  W n. ty   t j|j	rt 
|j	  Y n0 t|j	|  d S )Nzw+r-   F)modedelete)r/   r0   r1   r2   r3   writetempfileZNamedTemporaryFileBaseExceptionnameunlinkshutilmove)r0   sourcedestr    r    r!   rewrite   s    (JrT   alwaysFc                 C   s   | d d}d|v rd}|dkr8d|dd}n|}|rNd||}nd||}t| `\}}d	}	tt|D ],}
|
j|kr|| d
}	qx||
jj	 qx|	s|| W d   n1 s0    Y  d
||fS )z
    Adds or Updates a key/value to the given .env

    If the .env path given doesn't exist, fails instead of risking creating
    an orphan .env somewhere in the filesystem
    '" rU   z"{}"z\"zexport {}={}
z{}={}
FTN)
stripformatreplacerT   r"   r   r;   rK   r   string)r%   Z
key_to_setZvalue_to_set
quote_modeZexportZ	value_outZline_outrR   rS   Zreplacedr   r    r    r!   set_key   s&    

(r^   c                 C   s   t j| s td|  d|fS d}t| D\}}tt|D ]"}|j|krRd}q>|	|j
j q>W d   n1 sv0    Y  |std||  d|fS ||fS )z
    Removes a given key from the given .env

    If the .env path given doesn't exist, fails
    If the given key doesn't exist in the .env, fails
    z(Can't delete from %s - it doesn't exist.NFTz/Key %s not removed from %s - key doesn't exist.)r/   r0   existsr   r   rT   r"   r   r;   rK   r   r\   )r%   Zkey_to_unsetr]   ZremovedrR   rS   r   r    r    r!   	unset_key   s    
.r`   c                    sJ   fdd  fdd}i | D ]$\}}|d ur<t ||nd |< q S )Nc                    s(   |d ur|nd}  | t| |}|S )Nr-   )rD   r/   getenv)rN   defaultret)
new_valuesr    r!   _replacement   s    z.resolve_nested_variables.<locals>._replacementc                    s   |   } |d |d dS )zh
        From a match object gets the variable name and returns
        the correct replacement
        rN   rb   )rN   rb   )	groupdict)matchmatches)re   r    r!   _re_sub_callback   s    z2resolve_nested_variables.<locals>._re_sub_callback)__posix_variablesub)r9   ri   r@   rA   r    )re   rd   r!   r7      s    	r7   c                 c   st   t j| stdt j| r,t j| } d}t j| }||krp|V  t jt j|t jj}|| }}q<dS )zL
    Yield directories starting from the given directory up to the root
    zStarting path not foundN)	r/   r0   r_   IOErrorr1   dirnameabspathjoinpardir)r0   Zlast_dirZcurrent_dirZ
parent_dirr    r    r!   _walk_to_root   s    rq   r,   c           
      C   s   dd }|s| st tddr(t }nnt }trTtdsTtddd d }nt}|j	j
|krz|jd	usrJ |j}qX|j	j
}tjtj|}t|D ]&}tj|| }	tj|	r|	  S q|rtd
dS )z
    Search in increasingly higher folders for the given file

    Returns path to the file if found, or an empty string otherwise
    c                  S   s   t ddddgd} t| d S )z> Decide whether this is running in a REPL or IPython notebook __main__N__file__)fromlist)
__import__hasattr)mainr    r    r!   _is_interactive  s    z$find_dotenv.<locals>._is_interactivefrozenFz.py.r   r   NzFile not foundr-   )getattrsysr/   getcwd	_getframer	   rs   endswithrsplitf_codeco_filenamef_backr0   rm   rn   rq   ro   r1   rl   )
filenameZraise_error_if_not_foundZusecwdrx   r0   frameZcurrent_fileZframe_filenamerm   Z
check_pathr    r    r!   find_dotenv  s&    

r   Tc                 K   s,   | p|pt  }t|f||d|j|dS )a  Parse a .env file and then load all the variables found as environment variables.

    - *dotenv_path*: absolute or relative path to .env file.
    - *stream*: `StringIO` object with .env content.
    - *verbose*: whether to output the warnings related to missing .env file etc. Defaults to `False`.
    - *override*: where to override the system environment variables with the variables in `.env` file.
                  Defaults to `False`.
    r'   r)   )r?   )r   r#   rB   )r%   r5   r'   r?   r)   kwargsfr    r    r!   load_dotenv4  s    
r   c                 K   s(   | p|pt  }t|f||d| S )Nr   )r   r#   r:   )r%   r5   r'   r)   r   r   r    r    r!   dotenv_valuesB  s    r   )rU   F)rU   )r,   FF)NNFFT)NNFT)7Z
__future__r   r   r   r2   Zloggingr/   rerP   r|   rL   collectionsr   
contextlibr   compatr   r	   r
   r   parserr   r   Z	getLoggerrE   r   typingr   r   r   r   r   r   r   r   r   r   version_infoPathLikeZ	_PathLikeZ	_StringIOcompileVERBOSErj   r"   r#   rH   rT   r^   r`   r7   rq   r   r   r   r    r    r    r!   <module>   sH   
0

H


$

,
