o
    i[9                     @   s  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mZmZmZmZ ddlmZmZ ddlmZ eedf ZeeZd	efd
dZdee d	ee fddZ G dd dZ!	d<dededee d	ee fddZ"e
	d=dedee ded	eeee ee f  fddZ#				d>dedededed edee ded	eee eef fd!d"Z$			d?ded#ededee ded	eee ef fd$d%Z%d&eeeee f  d'ed	eeee f fd(d)Z&ded	ee fd*d+Z'	,		d@d-ed.ed/ed	efd0d1Z(					2	dAdee d3eee  d4ed'ed5edee d	efd6d7Z)				2	dBdee d3eee  d4ed5edee d	eeee f fd8d9Z*ded	efd:d;Z+dS )C    N)OrderedDict)contextmanager)IODictIterableIteratorMappingOptionalTupleUnion   )Bindingparse_stream)parse_variableszos.PathLike[str]returnc                  C   s$   dt jvrdS t jd  } | dv S )z8
    Determine if dotenv loading has been disabled.
    ZPYTHON_DOTENV_DISABLEDF>   truey1tyes)osenvironcasefold)value r   E/home/kim/smarthome/.venv/lib/python3.10/site-packages/dotenv/main.py_load_dotenv_disabled   s   
r   mappingsc                 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)r   mappingr   r   r   with_warn_for_invalid_lines    s   r$   c                   @   s   e Zd Z					ddee deee  dedee ded	ed
dfddZe	d
e
ee  fddZd
eeee f fddZd
e
eeee f  fddZd
efddZded
ee fddZdS )DotEnvNFTdotenv_pathstreamverboseencodinginterpolateoverrider   c                 C   s.   || _ || _d | _|| _|| _|| _|| _d S N)r&   r'   _dictr(   r)   r*   r+   )selfr&   r'   r(   r)   r*   r+   r   r   r   __init__+   s   	
zDotEnv.__init__c                 c   s    | j r't| j r't| j | jd}|V  W d    d S 1 s w   Y  d S | jd ur2| jV  d S | jr>td| j p<d t	dV  d S )Nr)   z3python-dotenv could not find configuration file %s..env )
r&   _is_file_or_fifoopenr)   r'   r(   r   infoioStringIO)r.   r'   r   r   r   _get_stream<   s   "
zDotEnv._get_streamc                 C   sD   | j r| j S |  }| jrtt|| jd| _ | j S t|| _ | j S )zReturn dotenv as dict)r+   )r-   parser*   r   resolve_variablesr+   )r.   Z
raw_valuesr   r   r   dictK   s   
zDotEnv.dictc                 c   sZ    |   }tt|D ]}|jd ur|j|jfV  qW d    d S 1 s&w   Y  d S r,   )r8   r$   r   keyr   )r.   r'   r#   r   r   r   r9   [   s   

"zDotEnv.parsec                 C   sJ   |   sdS |    D ]\}}|tjv r| jsq|dur"|tj|< qdS )zI
        Load the current dotenv as system environment variable.
        FNT)r;   itemsr   r   r+   )r.   kvr   r   r   set_as_environment_variablesa   s   
z#DotEnv.set_as_environment_variablesr<   c                 C   s2   |   }||v r|| S | jrtd|| j dS ) zKey %s not found in %s.N)r;   r(   r   r    r&   )r.   r<   datar   r   r   getp   s   z
DotEnv.get)NFNTT)__name__
__module____qualname__r	   StrPathr   strboolr/   r   r   r8   r   r;   r
   r9   r@   rC   r   r   r   r   r%   *   s6    

r%   utf-8r&   
key_to_getr)   c                 C   s   t | d|d|S )z
    Get the value of a given key from the given .env.

    Returns `None` if the key isn't found or doesn't have a value.
    T)r(   r)   )r%   rC   )r&   rK   r)   r   r   r   get_key}   s   
rL   Fpathfollow_symlinksc           
      c   s   |r	t j| } z*t| |d}zt | }t|jr"t|jnd }W n t	y1   |
   w W n tyC   td}d }Y nw tjd|ddt jt j| d>}t|j}d }z| ||fV  W d    n1 srw   Y  W n t	y }	 z|	}W Y d }	~	nd }	~	ww W d    n1 sw   Y  |d u rz|d urt || t ||  W d S  t	y   |jdd  w |jdd |d )	Nr0   r2   wFz.tmp_)moder)   deleteprefixdirT)
missing_ok)r   rM   realpathr4   lstatstatS_ISREGst_modeS_IMODEBaseExceptioncloseFileNotFoundErrorr6   r7   tempfileNamedTemporaryFiledirnameabspathpathlibPathnamechmodreplaceunlink)
rM   r)   rN   sourceZ	path_statZoriginal_modedest	dest_pathr   errr   r   r   rewrite   sh   


rl   always
key_to_setvalue_to_set
quote_modeexportc                 C   s  |dvrt d| |dkp|dko|  }|r$d|dd}n|}|r2d| d	| d
}	n| d	| d
}	t| ||dA\}
}d}d}tt|
D ]}|j|kr]||	 d}qN||j	j
 |j	j
d
 }qN|s{|rv|d
 ||	 W d   n1 sw   Y  d||fS )aS  
    Adds or Updates a key/value to the given .env

    The target .env file is created if it doesn't exist.

    This function doesn't follow symlinks by default, to avoid accidentally
    modifying a file at a potentially untrusted path. If you don't need this
    protection and need symlinks to be followed, use `follow_symlinks`.
    )rm   autoneverzUnknown quote_mode: rm   rr   z'{}''z\'zexport =
r)   rN   FTN)
ValueErrorisalnumformatrf   rl   r$   r   r<   writer!   stringendswith)r&   rn   ro   rp   rq   r)   rN   quoteZ	value_outZline_outrh   ri   ZreplacedZmissing_newliner#   r   r   r   set_key   s:   




r   key_to_unsetc           	      C   s   t j| std|  d|fS d}t| ||d"\}}tt|D ]}|j|kr,d}q"|	|j
j q"W d   n1 s>w   Y  |sPtd||  d|fS ||fS )a  
    Removes a given key from the given `.env` file.

    If the .env path given doesn't exist, fails.
    If the given key doesn't exist in the .env, fails.

    This function doesn't follow symlinks by default, to avoid accidentally
    modifying a file at a potentially untrusted path. If you don't need this
    protection and need symlinks to be followed, use `follow_symlinks`.
    z(Can't delete from %s - it doesn't exist.NFrw   Tz/Key %s not removed from %s - key doesn't exist.)r   rM   existsr   r    rl   r$   r   r<   r{   r!   r|   )	r&   r   rp   r)   rN   Zremovedrh   ri   r#   r   r   r   	unset_key   s&   

r   valuesr+   c                    s   i }| D ]:\}}|d u rd }n+t |}i  |r# tj  | n |  tj d fdd|D }|||< q|S )Nr2   c                 3   s    | ]}|  V  qd S r,   )resolve).0Zatomenvr   r   	<genexpr>3  s    z$resolve_variables.<locals>.<genexpr>)r   updater   r   join)r   r+   
new_valuesrd   r   resultZatomsr   r   r   r:   !  s   

r:   c                 c   s    t j| stdt j| rt j| } d}t j| }||kr>|V  t jt j|t jj}||}}||ks#dS dS )zL
    Yield directories starting from the given directory up to the root
    zStarting path not foundN)	r   rM   r   IOErrorisfiler`   ra   r   pardir)rM   Zlast_dirZcurrent_dir
parent_dirr   r   r   _walk_to_root:  s   
r   r1   filenameraise_error_if_not_foundusecwdc                 C   s   dd }dd }|s| s| st tddrt }n:t }t}|jj|ks/tj	|jjsG|j
dus6J |j
}|jj|ks/tj	|jjr/|jj}tjtj|}t|D ]}	tj|	| }
t|
rj|
  S qY|rqt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   sP   t tds
t tdrdS ztddddgd} W n
 ty!   Y dS w t | d S )	z<Decide whether this is running in a REPL or IPython notebookps1Zps2T__main__N__file__)fromlistF)hasattrsys
__import__ModuleNotFoundError)mainr   r   r   _is_interactiveW  s   z$find_dotenv.<locals>._is_interactivec                   S   s   t  d uS r,   )r   gettracer   r   r   r   _is_debuggera  s   z!find_dotenv.<locals>._is_debuggerfrozenFNzFile not foundr2   )getattrr   r   getcwd	_getframer   f_codeco_filenamerM   r   f_backr`   ra   r   r   r3   r   )r   r   r   r   r   rM   frameZcurrent_fileframe_filenamer`   
check_pathr   r   r   find_dotenvL  s0   

r   Tr'   r(   r*   c                 C   sF   t  r
td dS | du r|du rt } t| |||||d}| S )a  Parse a .env file and then load all the variables found as environment variables.

    Parameters:
        dotenv_path: Absolute or relative path to .env file.
        stream: Text stream (such as `io.StringIO`) with .env content, used if
            `dotenv_path` is `None`.
        verbose: Whether to output a warning the .env file is missing.
        override: Whether to override the system environment variables with the variables
            from the `.env` file.
        encoding: Encoding to be used to read the file.
    Returns:
        Bool: True if at least one environment variable is set else False

    If both `dotenv_path` and `stream` are `None`, `find_dotenv()` is used to find the
    .env file with it's default parameters. If you need to change the default parameters
    of `find_dotenv()`, you can explicitly call `find_dotenv()` and pass the result
    to this function as `dotenv_path`.

    If the environment variable `PYTHON_DOTENV_DISABLED` is set to a truthy value,
    .env loading is disabled.
    zSpython-dotenv: .env loading disabled by PYTHON_DOTENV_DISABLED environment variableFNr&   r'   r(   r*   r+   r)   )r   r   debugr   r%   r@   )r&   r'   r(   r+   r*   r)   Zdotenvr   r   r   load_dotenv  s    r   c                 C   s.   | du r|du rt  } t| |||d|d S )a  
    Parse a .env file and return its content as a dict.

    The returned dict will have `None` values for keys without values in the .env file.
    For example, `foo=bar` results in `{"foo": "bar"}` whereas `foo` alone results in
    `{"foo": None}`

    Parameters:
        dotenv_path: Absolute or relative path to the .env file.
        stream: `StringIO` object with .env content, used if `dotenv_path` is `None`.
        verbose: Whether to output a warning if the .env file is missing.
        encoding: Encoding to be used to read the file.

    If both `dotenv_path` and `stream` are `None`, `find_dotenv()` is used to find the
    .env file.
    NTr   )r   r%   r;   )r&   r'   r(   r*   r)   r   r   r   dotenv_values  s   r   c              	   C   sD   t j| rdS zt | }W n ttfy   Y dS w t|jS )zN
    Return True if `path` exists and is either a regular file or a FIFO.
    TF)r   rM   r   rW   r]   OSErrorS_ISFIFOrY   )rM   str   r   r   r3     s   r3   )rJ   )F)rm   FrJ   F)rm   rJ   F)r1   FF)NNFFTrJ   )NNFTrJ   ),r6   loggingr   rb   rW   r   r^   collectionsr   
contextlibr   typingr   r   r   r   r   r	   r
   r   parserr   r   	variablesr   rH   rG   	getLoggerrD   r   rI   r   r$   r%   rL   rl   r   r   r:   r   r   r   r   r3   r   r   r   r   <module>   s   (


V
:
:
)

4

2

$