U
    i7g\                     @   s6  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Zd dl	Z	d dl
mZ d dlmZ d dlmZ d dlmZ d dlmZmZ d dlZd dlmZmZ dd	gZe	d
ZeZeZ e	jee	j!e f Z"e	j!e Z#e	j$dej%j&f Z'e	j(e	j)e	j$def ej%j&f Z*e	j)ej%j& Z+e	j(e+e'f Z,e	j$Z-e.dZ/e.dZ0G dd de1Z2G dd de2Z3G dd de4e2Z5G dd de1Z6de7 de,ee	j8e	j$ e	j9e e-dddZ:e	j$ee-dddZ;e	j8e* e	j)ej%j& dddZ<e	j8e= ej%j!ddd Z>d!d"e	j(ee	j?f ee	j?d#d$d%Z@ddd!d&e	j(ee	jf e	j8e* e	j8e* ee	jd'd(d)ZAe	j(ee	je	j!f d*d+d,ZBe	jd-ed.ZCdCe	j)eC eeCd0d1d2ZDeeEd3d4d5ZFeeEd3d6d7ZGeeEd3d8d9ZHG d:d; d;ej%jIZJG d<d= d=ej%jKZLG d>d? d?ej%jMZNG d@dA dAej%jOZPG dBd	 d	ZQdS )D    N)Mapping)	timedelta)Enum)Path)ParseResulturlparse)_walk_to_rootload_dotenvEnvErrorEnv_T.z((?<!\\)\$\{([A-Za-z0-9_]+)(:-[^\}:]*)?\}u   ^(?:\s*)(?:(-?\d+)\s*w\s*)?(?:(-?\d+)\s*d\s*)?(?:(-?\d+)\s*h\s*)?(?:(-?\d+)\s*m\s*)?(?:(-?\d+)\s*s\s*)?(?:(-?\d+)\s*ms\s*)?(?:(-?\d+)\s*[µu]s\s*)?$c                   @   s   e Zd ZdZdS )r
   z\Raised when an environment variable or
    if a required environment variable is unset.
    N__name__
__module____qualname____doc__ r   r   5/tmp/pip-unpacked-wheel-ghcjkyf1/environs/__init__.pyr
   6   s   c                       s.   e Zd Zeejeef d fddZ  Z	S )EnvValidationError)messageerror_messagesc                    s   || _ t | d S N)r   super__init__)selfr   r   	__class__r   r   r   =   s    zEnvValidationError.__init__)
r   r   r   strtypingUnion	ErrorListErrorMappingr   __classcell__r   r   r   r   r   <   s    r   c                   @   s   e Zd ZdS )EnvSealedErrorN)r   r   r   r   r   r   r   r#   D   s   r#   c                   @   s   e Zd ZdZdS )ParserConflictErrorzYRaised when adding a custom parser that conflicts
    with a built-in parser method.
    Nr   r   r   r   r   r$   H   s   r$   
preprocesspreprocess_kwarg_names)field_or_factorymethod_namer&   r'   returnc                   s   t jd ft jd dd d d ddttjtjt tjtjtjtjtjgtjf tj	tjtjgtjf  f  t
tjt
 tjtjttf  tjtjttjf  tjt d fdd}||_|S )NF)load_defaultvalidaterequired
allow_noner   metadatar   )r   namedefaultsubcastr+   r,   r-   r.   r   r/   r*   c             
      sp  | j rtdt||||p|||	d} fddD }ttr`ttjjr`f | }n"t	|}t
tf d|i|}| ||j\}}}|| j|< |p|}|tjkr| jrtd|p| dn| j| d d S zr|f|}||}W n` tjk
r` } z>| jr>td| d	|jd
  |j|| j| |j W 5 d }~X Y nX || j|< |S )N9Env has already been sealed. New values cannot be parsed.)r,   r-   r.   r+   r   r/   c                    s    i | ]}| kr|  |qS r   )pop).0r0   kwargsr   r   
<dictcomp>u   s      z1_field2method.<locals>.method.<locals>.<dictcomp>r2   Environment variable "	" not setEnvironment variable not set." invalid: r   )_sealedr#   dict
isinstancetype
issubclassmafieldsField_make_subcast_fieldr   castFieldFactory_get_from_environr+   _fieldsmissingeagerr
   _errorsappenddeserializeValidationErrorr   argsmessagesextend_values)r   r0   r1   r2   r+   r,   r-   r.   r   r/   r7   Zfield_kwargsZpreprocess_kwargsfieldZparsed_subcast
parsed_keyvalueproxied_key
source_keyerrorr(   r&   r'   r6   r   methodU   sl    
  


$
z_field2method.<locals>.method)rB   rJ   r   r   AnyOptionalSubcastr   CallableIterableboolDictr   r   r   )r(   r)   r&   r'   r[   r   rZ   r   _field2methodN   s<    
Hrc   )funcr)   r*   c                    s0   t jfdttjtjt d fdd}||_|S )Nr   )r   r0   r1   r*   c              
      s$  | j rtd| ||\}}}tj | j|< |p6|}|tjkrr| jr^t	d|pR| dn| j
| d d S |s~|dkr|}nd }z |f|}W n| t	tjfk
r }	 zVt|	tjr|	jn
|	jd g}
| jrtd| d|	jd  |
|	| j
| |
 W 5 d }	~	X Y nX || j|< |S )Nr3   r9   r:   r;    r   r<   )r=   r#   rH   rB   rC   rD   rI   rJ   rK   r
   rL   rM   rO   r?   rQ   rP   r   rR   rS   )r   r0   r1   r7   rU   	raw_valuerW   rX   rV   rY   rQ   rd   r   r   r[      sD    


"
z_func2method.<locals>.method)rB   rJ   r   r   r\   r]   r   r   )rd   r)   r[   r   rg   r   _func2method   s    +rh   )r2   r*   c                    st   t  tr$ tjjkr$tjj  }nLt  trBt tjjrB }n.t rhG  fdddtjj}|}ntjj}|S )Nc                       s   e Zd Z fddZdS )z)_make_subcast_field.<locals>.SubcastFieldc                    s   t t jdtf  }||S )N.)r   rF   r_   r   )r   rV   rP   r7   rd   r2   r   r   _deserialize   s    z6_make_subcast_field.<locals>.SubcastField._deserializeN)r   r   r   rj   r   ri   r   r   SubcastField   s   rk   )	r?   r@   rB   SchemaZTYPE_MAPPINGrA   rC   rD   callable)r2   inner_fieldrk   r   ri   r   rE      s    rE   c                 K   s   t | }tjj|f|S r   )rE   rB   rC   List)r2   r7   rn   r   r   r   _make_list_field   s    rp   ,)	delimiter)rV   rr   r*   c                K   s6   t j| s| d kr| S | dkr2tt| |S g S )Nre   )rB   utilsZis_iterable_but_not_stringr   rF   r   split)rV   rr   r7   r   r   r   _preprocess_list   s    ru   )subcast_keyssubcast_valuesrr   )rV   rv   rw   rr   r*   c                   sR   t trS t|f | t|f | fddfdd|D D S )Nc                    s*   i | ]"\}}  |  | qS r   )rN   strip)r5   keyval)subcast_keys_instancesubcast_values_instancer   r   r8     s
   z$_preprocess_dict.<locals>.<dictcomp>c                 3   s   | ]} r| d dV  qdS )=   N)rt   )r5   itemrV   r   r   	<genexpr>  s      z#_preprocess_dict.<locals>.<genexpr>)r?   r   rE   rt   )rV   rv   rw   rr   r7   r   )r{   r|   rV   r   _preprocess_dict   s    
r   r   c              
   K   s|   zFt | trt| W S t | ts4t | ts4| d kr:| W S tdW n0 tjk
rv } ztd|W 5 d }~X Y nX d S )NzNot valid JSON.)	r?   r   pyjsonloadsr>   listrB   rO   JSONDecodeError)rV   r7   rY   r   r   r   _preprocess_json	  s    
r   _EnumT)boundF)r@   ignore_caser*   c              
   C   sx   t d|j d}|sLz
||  W S  tk
rJ } z
||W 5 d }~X Y nX |D ]}|j |  krP|  S qP|d S )NzNot a valid 'z' enum.)rB   rO   r   KeyErrorr0   lower)rV   r@   r   Zinvalid_excrY   Z
enum_valuer   r   r   _enum_parser  s    

r   rV   r*   c              
   K   s~   zdd l }W n, tk
r8 } ztd|W 5 d }~X Y nX z|j| f|W S  tk
rx } ztd|W 5 d }~X Y nX d S )Nr   zoThe dj_db_url parser requires the dj-database-url package. You can install it with: pip install dj-database-urlzNot a valid database URL.)dj_database_urlImportErrorRuntimeErrorparse	ExceptionrB   rO   )rV   r7   r   rY   r   r   r   _dj_db_url_parser(  s    r   c              
   K   s~   zdd l }W n, tk
r8 } ztd|W 5 d }~X Y nX z|j| f|W S  tk
rx } ztd|W 5 d }~X Y nX d S )Nr   zlThe dj_email_url parser requires the dj-email-url package. You can install it with: pip install dj-email-urlzNot a valid email URL.)dj_email_urlr   r   r   r   rB   rO   )rV   r7   r   rY   r   r   r   _dj_email_url_parser6  s    r   c              
   K   s   zdd l }W n, tk
r8 } ztd|W 5 d }~X Y nX z|j| f|W S  tk
r~ } zt|jd |W 5 d }~X Y nX d S )Nr   ztThe dj_cache_url parser requires the django-cache-url package. You can install it with: pip install django-cache-url)django_cache_urlr   r   r   r   rB   rO   rP   )rV   r7   r   rY   r   r   r   _dj_cache_url_parserD  s    r   c                       sH   e Zd ZeedddZdeeje ejej ed fddZ	  Z
S )	URLFieldr   c                 O   s   |  S r   )geturl)r   rV   rP   r7   r   r   r   
_serializeU  s    zURLField._serializeN)rV   attrdatar*   c                    s   t  j|||f|}t|S r   )r   rN   r   )r   rV   r   r   r7   retr   r   r   rN   Z  s    zURLField.deserialize)NN)r   r   r   r   r   r   r   r]   r   rN   r"   r   r   r   r   r   T  s     
r   c                       s"   e Zd Zed fddZ  ZS )	PathFieldr*   c                    s*   t |tr|S t j|f||}t|S r   )r?   r   r   rj   )r   rV   rP   r7   r   r   r   r   rj   f  s    
zPathField._deserialize)r   r   r   r   rj   r"   r   r   r   r   r   e  s   r   c                       s"   e Zd Zed fddZ  ZS )LogLevelFieldr   c              
      sz   zt  |W S  ttfk
rt } zD| }tt|rXttt|t	rXtt| W Y S t
d|W 5 d }~X Y nX d S )NzNot a valid log level.)r   _format_num	TypeError
ValueErrorupperhasattrloggingr?   getattrintrB   rO   )r   rV   rY   r   r   r   r   n  s    zLogLevelField._format_num)r   r   r   r   r   r"   r   r   r   r   r   m  s   r   c                       s"   e Zd Zed fddZ  ZS )TimeDeltaFieldr   c                    s   t |tr|S t|}|d k	r|drtt|dp:dt|dpJdt|dpZdt|dpjdt|dpzdt|dpdt|dpdd	S t j|f||S )
Nr   r~                     )weeksdayshoursminutessecondsZmillisecondsmicroseconds)r?   r   _TIMEDELTA_PATTERNmatchgroupr   r   rj   )r   rV   rP   r7   r   r   r   r   rj   z  s    

	zTimeDeltaField._deserialize)r   r   r   r   rj   r"   r   r   r   r   r   y  s   r   c                
   @   sj  e Zd ZU dZeejjdZe	e
d< eejjdZeejjdZeejjdZeejjdZeejjdZeeded	d
Zeejjdedd
ZeejjdedZeejjdZeejjdZ eejj!dZ"ee#dZ$ee%dZ&ee'dZ(eejj)dZ*ee+dZ,e-e.dZ/e-e0dZ1e-e2dZ3e-e4dZ5ddde6e6dddZ7e8d d!d"Z9e:dDe;j<e8 e6e6e6e6e;j=e6e8f d$d%d&Z>e?j@e8e;jAd  d'd(d)ZBd*d+ ZCe8d,d-d.ZDe8e;jEd#d/d0d1ZFe8e;jEe;jEge;jEf d2d3d4ZGe8e;jHejj d5d6d7ZIe;jJe8e;jKf d d8d9ZLdd:e8e;jKe6e;jMe8e;jKe;j<e8 f d;d<d=ZNd>d? ZOdd@e8e6e8dAdBdCZPd#S )Er   zAn environment variable reader.__call__r   ra   r   floatdecimalr   )r2   rr   r%   r>   )r2   rv   Zsubcast_keyrw   rr   json)r&   datetimedatetimepath	log_levelr   uuidurlenum	dj_db_urlr   dj_cache_urlTF)rK   expand_varsc                C   s:   || _ d| _|| _i | _i | _tt| _d | _	i | _
d S )NF)rK   r=   r   rI   rS   collectionsdefaultdictr   rL   _prefix__custom_parsers__)r   rK   r   r   r   r   r     s    zEnv.__init__r   c                 C   s    d| j j d| j d| j dS )N<z(eager=z, expand_vars=z)>)r   r   rK   r   )r   r   r   r   __repr__  s    zEnv.__repr__N)r   recurseverboseoverridereturn_pathr*   c                 C   s   d}| dkrRt  }|dkr$td|j}|dk	s6tt|jjj	 }|d }	nt| 
 rftdt| }	|rtj|	\}
}|
st }
t|
D ].}t|| }| rt|||d}t|}qntt|	||d}t|	}|r|S |S dS )aG  Read a .env file into os.environ.

        If .env is not found in the directory from which this method is called,
        the default behavior is to recurse up the directory tree until a .env
        file is found. If you do not wish to recurse up the tree, you may pass
        False as a second positional argument.
        FNz!Could not get current call frame.z.envz)path must be a filename, not a directory.)r   r   )inspectcurrentframer   f_backAssertionErrorr   f_codeco_filenameparentresolveis_dirr   osr   rt   getcwdr   existsr	   r   )r   r   r   r   r   Zis_env_loadedcurrent_frameframeZ
caller_dirstart	start_direnv_namedirname
check_pathZenv_pathr   r   r   read_env  s<    
  zEnv.read_env)prefixr*   c                 c   sB   z.| j }|dkr|| _ n| | | _ | V  W 5 d| _ X || _ dS )z9Context manager for parsing envvars with a common prefix.Nr   )r   r   Z
old_prefixr   r   r   prefixed  s    
zEnv.prefixedc                 C   s0   d| _ | jr,t| j}i | _td| |dS )zvValidate parsed values and prevent new values from being added.

        :raises: environs.EnvValidationError
        TzEnvironment variables invalid: N)r=   rL   r>   r   )r   r   r   r   r   seal  s    
 zEnv.seal)r0   c              
   C   sP   zt | j| | W S  tk
rJ } zt|  d| |W 5 d }~X Y nX d S )Nz has no attribute )	functoolspartialr   r   AttributeError)r   r0   rY   r   r   r   __getattr__  s    zEnv.__getattr__)r0   rd   r*   c                 C   s0   t | |rtd| dt||d| j|< dS )zRegister a new parser method with the name ``name``. ``func`` must
        receive the input value for an environment variable.
        z$Env already has a method with name 'z'. Use a different name.r)   N)r   r$   rh   r   )r   r0   rd   r   r   r   
add_parser  s    

zEnv.add_parser)r0   r*   c                    s   t jt jd fdd}|S )zDecorator that registers a new parser method with the name ``name``.
        The decorated function must receive the input value for an environment variable.
        )rd   r*   c                    s     |  | S r   )r   rg   r0   r   r   r   	decorator(  s    z!Env.parser_for.<locals>.decorator)r   r_   )r   r0   r   r   r   r   
parser_for!  s    zEnv.parser_for)r0   	field_clsc                 C   s   t ||d| j|< dS )z`Register a new parser method with name ``name``,
        given a marshmallow ``Field``.
        r   N)rc   r   )r   r0   r   r   r   r   add_parser_from_field.  s    zEnv.add_parser_from_fieldc                 C   s   t j| j }|| jS )znDump parsed environment variables to a dictionary of simple data types
        (numbers and strings).
        )rB   rl   	from_dictrI   dumprS   )r   Zschemar   r   r   r   6  s    zEnv.dumpproxied)ry   r1   r   r*   c          
      C   s   | j ||d}tj||}t|dr| jo4t|}|r| d }| d }|dk	rh|dd }n||krvt	j
}|| j||ddd |fS | jot|}	|	r| ||S | jrd	|kr|d	d
}||dfS )a  Access a value from os.environ. Handles proxied variables,
        e.g. SMTP_LOGIN={{MAILGUN_LOGIN}}.

        Returns a tuple (envvar_key, envvar_value, proxied_key). The ``envvar_key``
        will be different from the passed key for proxied variables. proxied_key
        will be None if the envvar isn't proxied.

        The ``proxied`` flag is recursively passed if a proxy lookup is required
        to get a proxy env key.
        omit_prefixrx   r   r~   Nr   Tr   z\$$)_get_keyr   environgetr   r   _EXPANDED_VAR_PATTERNr   groupsrB   rJ   rH   search_expand_varsreplace)
r   ry   r1   r   env_keyrV   Zexpand_matchrW   Zsubs_defaultZexpand_searchr   r   r   rH   =  s.    
zEnv._get_from_environc           
      C   s   d}d}t |D ]}|d}|d}|d kr:tj}n|dd  }| j||dd\}}	}|	tjkrt||	|f  S ||||  |	 7 }| }q|||d  7 }|||fS )Nre   r   r~   r   Tr   )r   finditerr   rB   rJ   rH   r   end)
r   rU   rV   r   Z
prev_startr   r  Zenv_default_Z	env_valuer   r   r   r  f  s    



zEnv._expand_varsr   )ry   r   r*   c                C   s   | j r|s| j | S |S r   r   )r   ry   r   r   r   r   r   y  s    zEnv._get_key)NTFFF)Qr   r   r   r   rc   rB   rC   rD   r   ParserMethod__annotations__Intr   ZBoolra   Strr   ZFloatr   Decimalr   rp   ru   r   rb   r   r>   r   r   DateTimer   Dater   ZTimer   r   r   r   r   r   r   UUIDr   r   r   rh   r   r   r   r   r   r   r   r   	_BoolTyper   _StrTyper   staticmethodr   r]   r   r   
contextlibcontextmanagerIteratorr   r   r   r_   r   r   Typer   r   r\   r   TuplerH   r  r   r   r   r   r   r     s   









     1   ))F)Rr   r  r   r   r   r   r   r   rer   collections.abcr   r   r   r   r   pathlibr   urllib.parser   r   ZmarshmallowrB   Zdotenv.mainr   r	   __all__TypeVarr   r   r  ra   r  ro   r!   r    r_   rC   rD   rG   r   r  r^   Z	FieldTypeZFieldOrFactoryr	  compiler   r   r   r
   r   r   r#   r$   tupler]   Sequencerc   rh   rE   r@   rp   r`   ru   r   r   r   r   r>   r   r   r   URLr   r  r   r  r   Z	TimeDeltar   r   r   r   r   r   <module>   s   

 


S1 