U
    ڲgN                     @   s   d 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	m
Z
mZmZmZmZmZ ddlmZmZmZmZmZ ddlmZ eejfZeeZdd Zd	d
 Zdd Z dd Z!G dd dZ"G dd dZ#G dd de#Z$G dd dZ%dS )zt
Django-environ allows you to utilize 12factor inspired environment
variables to configure your Django application.
    N)parse_qsParseResultquoteunquoteunquote_plusurlparse
urlunparse   )DJANGO_POSTGRESImproperlyConfiguredjsonPYMEMCACHE_DRIVERREDIS_DRIVER)FileAwareMappingc              	   C   s.   zt | W S  ttfk
r(   |  Y S X d S N)astliteral_eval
ValueErrorSyntaxError)value r   3/tmp/pip-unpacked-wheel-fcyglivv/environ/environ.py_cast,   s    r   c                 C   s   t | dr|  rt| S | S )zReturn int if possible.isdigit)hasattrr   intvr   r   r   	_cast_int6   s    r   c                 C   s   t | trt| S | S r   )
isinstancestrr   r   r   r   r   _cast_urlstr;   s    r!   c                 C   s   t t| ddS )Nz:/?&=@)safe)r   r   )urlr   r   r   _urlparse_quote?   s    r$   c                   @   s   e Zd ZdZdd ZdS )NoValuezRepresent of no value object.c                 C   s   d| j j dS )N<>)	__class____name__selfr   r   r   __repr__F   s    zNoValue.__repr__N)r)   
__module____qualname____doc__r,   r   r   r   r   r%   C   s   r%   c                   @   s|  e Zd ZdZejZe ZdZ	e
ZdddddgZdZeeeed	d
d
ddddddddddZdddddgZdZddddded eeed!
Zd"d#d$d%d&gZd'Zd(d(d(d(d)d*d+d,d-Zd.d/gZd0Zd1d2d3d4d5d6d7d8d9Zd:d; eD Zd<Zd=d> Zd?ed@fdAdBZdCdD Zed@fdEdFZ edGfdHdIZ!efdJdKZ"efdLdMZ#efdNdOZ$efdPdQZ%d?efdRdSZ&d?efdTdUZ'e(efdVdWZ(efdXdYZ)eed?fdZd[Z*e*Z+eed?fd\d]Z,e,Z-eed?fd^d_Z.e.Z/eed?fd`daZ0efdbdcZ1d?ed@fdddeZ2e3dfdg Z4e3d|dhdiZ5e3d}djdkZ6e3d~dldmZ7e3dndo Z8e3dpdq Z9e3drds Z:e3dtdu Z;e3dvdw Z<e3ddxdyZ=e3ddzd{Z>d?S )Enva3  Provide scheme-based lookups of environment variables so that each
    caller doesn't have to pass in ``cast`` and ``default`` parameters.

    Usage:::

        import environ
        import os

        env = environ.Env(
            # set casting, default value
            MAIL_ENABLED=(bool, False),
            SMTP_LOGIN=(str, 'DEFAULT')
        )

        # Set the project base directory
        BASE_DIR = os.path.dirname(
            os.path.dirname(os.path.abspath(__file__))
        )

        # Take environment variables from .env file
        environ.Env.read_env(os.path.join(BASE_DIR, '.env'))

        # False if not in os.environ due to casting above
        MAIL_ENABLED = env('MAIL_ENABLED')

        # 'DEFAULT' if not in os.environ due to casting above
        SMTP_LOGIN = env('SMTP_LOGIN')
    )trueonokyyes1postgres
postgresqlpsqlpgsqlpostgisZDATABASE_URLz&django.contrib.gis.db.backends.postgiszdjango.db.backends.mysqlzmysql.connector.djangoz$django.contrib.gis.db.backends.mysqlmssqlzdjango.db.backends.oraclezsql_server.pyodbcZdjango_redshift_backendz)django.contrib.gis.db.backends.spatialitezdjango.db.backends.sqlite3zldapdb.backends.ldap)r7   r8   r9   r:   r;   ZmysqlZmysql2zmysql-connectorZmysqlgisr<   oracleZpyodbcZredshiftZ
spatialitesqliteldapZCONN_MAX_AGEZATOMIC_REQUESTSZ
AUTOCOMMITZDISABLE_SERVER_SIDE_CURSORSZCONN_HEALTH_CHECKSZ	CACHE_URLz+django.core.cache.backends.db.DatabaseCachez+django.core.cache.backends.dummy.DummyCachez3django.core.cache.backends.filebased.FileBasedCachez-django.core.cache.backends.locmem.LocMemCachez3django.core.cache.backends.memcached.MemcachedCachez1django.core.cache.backends.memcached.PyLibMCCache)
ZdbcacheZ
dummycache	filecacheZlocmemcachememcache
pymemcacheZpylibmcZ
rediscacheredisZredissTIMEOUTZ
KEY_PREFIXVERSIONZKEY_FUNCTIONZBINARYZ	EMAIL_URLz+django.core.mail.backends.smtp.EmailBackendz.django.core.mail.backends.console.EmailBackendz0django.core.mail.backends.filebased.EmailBackendz-django.core.mail.backends.locmem.EmailBackendz,django.core.mail.backends.dummy.EmailBackend)smtpsmtpssmtp+tlssmtp+sslZconsolemailZfilemailZ
memorymailZ	dummymailEMAIL_USE_TLSEMAIL_USE_SSLZ
SEARCH_URLzAhaystack.backends.elasticsearch_backend.ElasticsearchSearchEnginezChaystack.backends.elasticsearch2_backend.Elasticsearch2SearchEnginezChaystack.backends.elasticsearch5_backend.Elasticsearch5SearchEnginezChaystack.backends.elasticsearch7_backend.Elasticsearch7SearchEnginez)haystack.backends.solr_backend.SolrEnginez-haystack.backends.whoosh_backend.WhooshEnginez-haystack.backends.xapian_backend.XapianEnginez-haystack.backends.simple_backend.SimpleEngine)elasticsearchZelasticsearch2Zelasticsearch5Zelasticsearch7solrwhooshxapiansimplec                 C   s(   g | ] }| d rdD ]}|| qqS )rL   ) s)
startswith).0schemerR   r   r   r   
<listcomp>   s
    
 zEnv.<listcomp>Zcloudsqlc                 K   s   d| _ d| _d| _|| _d S )NTFrQ   )
smart_castescape_proxyprefixrU   )r+   rU   r   r   r   __init__   s    zEnv.__init__NFc                 C   s   | j ||||dS )Ncastdefaultparse_default	get_value)r+   varr\   r]   r^   r   r   r   __call__   s    zEnv.__call__c                 C   s
   || j kS r   )ENVIRON)r+   ra   r   r   r   __contains__   s    zEnv.__contains__c                 C   s&   | j |t|d}|r"tdd|S |S )z
        :rtype: str
        r\   r]   z	(\\r)?\\nz\n)r`   r    resub)r+   ra   r]   	multiliner   r   r   r   r       s    zEnv.strutf8c                 C   s(   | j |t|d}t|dr$||S |S )z
        :rtype: bytes
        re   encode)r`   r    r   rj   )r+   ra   r]   encodingr   r   r   r   bytes   s    

z	Env.bytesc                 C   s   | j |t|dS )z
        :rtype: bool
        re   )r`   boolr+   ra   r]   r   r   r   rm      s    zEnv.boolc                 C   s   | j |t|dS )z
        :rtype: int
        re   )r`   r   rn   r   r   r   r      s    zEnv.intc                 C   s   | j |t|dS )z
        :rtype: float
        re   )r`   floatrn   r   r   r   ro      s    z	Env.floatc                 C   s   | j |tj|dS )z'
        :returns: Json parsed
        re   )r`   r   loadsrn   r   r   r   r      s    zEnv.jsonc                 C   s   | j ||stn|g|dS )z
        :rtype: list
        re   )r`   listr+   ra   r\   r]   r   r   r   rq      s
    zEnv.listc                 C   s   | j ||stn|f|dS )z
        :rtype: tuple
        re   )r`   tuplerr   r   r   r   rs     s
    z	Env.tuplec                 C   s   | j |||dS )z
        :rtype: dict
        re   r_   rr   r   r   r   dict  s    zEnv.dictc                 C   s   | j |t|ddS )z2
        :rtype: urllib.parse.ParseResult
        Tr[   )r`   r   rn   r   r   r   r#     s    zEnv.urlc                 C   s   | j | j||d|dS )zReturns a config dictionary, defaulting to DATABASE_URL.

        The db method is an alias for db_url.

        :rtype: dict
        r]   engine)db_url_configr`   r+   ra   r]   rw   r   r   r   db_url   s    z
Env.db_urlc                 C   s   | j | j||d|dS )zReturns a config dictionary, defaulting to CACHE_URL.

        The cache method is an alias for cache_url.

        :rtype: dict
        ru   backend)cache_url_configr#   r+   ra   r]   r|   r   r   r   	cache_url.  s    zEnv.cache_urlc                 C   s   | j | j||d|dS )zReturns a config dictionary, defaulting to EMAIL_URL.

        The email method is an alias for email_url.

        :rtype: dict
        ru   r{   )email_url_configr#   r~   r   r   r   	email_url<  s    zEnv.email_urlc                 C   s   | j | j||d|dS )zUReturns a config dictionary, defaulting to SEARCH_URL.

        :rtype: dict
        ru   rv   )search_url_configr#   ry   r   r   r   
search_urlJ  s    zEnv.search_urlc                 K   s   t | j||df|S )z
        :rtype: Path
        ru   )Pathr`   )r+   ra   r]   kwargsr   r   r   pathT  s    zEnv.pathc              
   C   s  t d||| | j | }|| jkr| j| }zt|dk}W n tk
rZ   d}Y nX |r|sl|d }|| jkrz|d }W q tk
r   Y qX n|s|}z| j| }W nF t	k
r }	 z(|| jkrd| d}
t
|
|	|}W 5 d}	~	X Y nX t|trd	nd
}t|trdnd}t|drR||rR||}| j|||d}| jrrt|drr|||}| jr|dkr|dk	rt|tst|}|dkr|dkrdn|}||ks|r|dk	r| ||}|S )a  Return value for given environment variable.

        :param str var:
            Name of variable.
        :param collections.abc.Callable or None cast:
            Type to cast return value as.
        :param default:
             If var not present in environ, return this instead.
        :param bool parse_default:
            Force to parse default.
        :returns: Value from environment or default (if set).
        :rtype: typing.IO[typing.Any]
        z)get '%s' casted as '%s' with default '%s'   Fr   r	   zSet the z environment variableN   $$s   \$z\$rS   re   replacerQ   )loggerdebugrY   rU   len	TypeErrorNOTSET
IndexErrorrc   KeyErrorr   r   rl   r   rS   lstripr`   rX   r   rW   r%   typeparse_value)r+   ra   r\   r]   r^   var_nameZvar_infoZhas_defaultr   exc	error_msgrY   escaper   r   r   r`   Z  s\      






zEnv.get_valuec                    s  |dkr|S |t krPzt|dk}W n& tk
rJ   |   jk}Y nX nt|trtt|d dd |	dD }nt|t
r|dd	d}t
t|d dd |D }nDt|tr|d	t|d
t|di tt fdddd |	dD }n|tkrBtdd |	dD }n|tkrbdd |	dD }n|t
kr|dd	d}t
dd |D }nn|tkrtdd|}t	d|}t|dkr|d }n d|dd  d|d  }t|}n||}|S )zParse and cast provided value

        :param value: Stringed value.
        :param cast: Type to cast return value as.

        :returns: Casted value
        Nr   c                 S   s   g | ]}|r|qS r   r   rT   xr   r   r   rV     s      z#Env.parse_value.<locals>.<listcomp>,()c                 S   s   g | ]}|r|qS r   r   r   r   r   r   rV     s      keyr   r\   c                    s(   | d   | d | d fS )Nr   r	   )r   get)kvclsZkey_castZ
value_castZvalue_cast_by_keyr   r   <lambda>  s    
z!Env.parse_value.<locals>.<lambda>c                 S   s   g | ]}|r| d qS )=split)rT   valr   r   r   rV     s      ;c                 S   s   g | ]}|r| d dqS )r   r	   r   )rT   r   r   r   r   rV     s      c                 S   s   g | ]}|r|qS r   r   r   r   r   r   rV     s      c                 S   s   g | ]}|r|qS r   r   r   r   r   r   rV     s      z[^\d,.-]rQ   z[,.]r	   .)rm   r   r   lowerstripBOOLEAN_TRUE_STRINGSr   rq   mapr   rs   rt   r   r    ro   rf   rg   r   join)r   r   r\   r   Z	float_strpartsr   r   r   r     sH    	
&
 





 
zEnv.parse_valuec                 C   s2  t || jsN|dkr$| jd ddS zt|}W n tk
rL   t|}Y nX i }|jsdtt|}|jdd }t|	ddd	 }|j
dkr|d
krd}|jrtjd|jddd |j
dkr|j
 d|j }|jr|d|j 7 }|jdd}|j
| jkrnd|d krnttjdd |d 	dD  }d|d	 }t|dkrhdtd|d nd
}n|j}|j}||pd
t|jpd
t|jpd
|pd
t|pd
d |j
| jkr|ds| j|kr|dr|dd\|d< |d< |j
dkr2|d
kr2|d |d< d
|d< |j
dkr`|d sP|d= nt|d |d< |j ri }	t!|j " D ]L\}
}|
# | j$kr||
# t%|d	 i n|	|
t|d	 i qz|	|d< |r||d< n
|j
|d< |d | jkr| j|d  |d< |&dds.td |  i S |S )!af  Parse an arbitrary database URL.

        Supports the following URL schemas:

        * PostgreSQL: ``postgres[ql]?://`` or ``p[g]?sql://``
        * PostGIS: ``postgis://``
        * MySQL: ``mysql://`` or ``mysql2://``
        * MySQL (GIS): ``mysqlgis://``
        * MySQL Connector Python from Oracle: ``mysql-connector://``
        * SQLite: ``sqlite://``
        * SQLite with SpatiaLite for GeoDjango: ``spatialite://``
        * Oracle: ``oracle://``
        * Microsoft SQL Server: ``mssql://``
        * PyODBC: ``pyodbc://``
        * Amazon Redshift: ``redshift://``
        * LDAP: ``ldap://``

        :param urllib.parse.ParseResult or str url:
            Database URL to parse.
        :param str or None engine:
            If None, the database engine is evaluates from the ``url``.
        :return: Parsed database URL.
        :rtype: dict
        zsqlite://:memory:r>   z:memory:)ENGINENAMEr	   N?r   r   rQ   z#SQLite URL contains host component z, it will be ignored   )
stacklevelr?   ://:@r   r   c                 s   s   | ]}| d dV  qdS )r   r	   N)rsplit)rT   hostr   r   r   	<genexpr>(  s   z$Env.db_url_config.<locals>.<genexpr>)r   USERZPASSWORDHOSTPORT/r   r   r=   r   OPTIONSr   Fz Engine not recognized from url: )'r   	URL_CLASS
DB_SCHEMESr   r   r$   r   r   r   r   rU   netlocwarningswarnhostnameportr   POSTGRES_FAMILYrq   	itertoolszip_longestr   r   filterupdater!   usernamepasswordr   rS   CLOUDSQLr    queryr   itemsupper_DB_BASE_OPTIONSr   r   )r   r#   rw   configr   Z	user_hostZhinfor   r   config_optionskr   r   r   r   rx     s    

(	



zEnv.db_url_configc           
         s  t | jssi S tj| jkr8tdj jd}t|dkrX|d }| jj |d}jdkr|	djj
 i jsjdkr|	dd	j
 i nhjd
rjrԈjdd nd  fddjdD }t|dkr|d |d< n||d< jri }tj D ]D\}}| t|d i}	| | jkrj|	|	 n
|	|	 q2||d< |r||d< |S )a  Parse an arbitrary cache URL.

        :param urllib.parse.ParseResult or str url:
            Cache URL to parse.
        :param str or None backend:
            If None, the backend is evaluates from the ``url``.
        :return: Parsed cache URL.
        :rtype: dict
        zInvalid cache schema r   r	   r   )BACKENDLOCATIONr@   r   )rA   rB   zunix:rC   cacherQ   unixc                    s   g | ]} d  | j  qS )r   r   )rT   locrU   r#   r   r   rV     s   z(Env.cache_url_config.<locals>.<listcomp>r   r   )r   r   r   rU   CACHE_SCHEMESr   r   r   r   r   r   rS   r   r   r   r   r   r   r   _CACHE_BASE_OPTIONS)
r   r#   r|   locationr   	locationsr   r   r   optr   r   r   r}   e  sV    

 
 
zEnv.cache_url_configc           	      C   s@  i }t || jst|n|}|jdd }t|ddd }||t|jt|j	|j
t|jd |rv||d< n:|j| jkrtd|j n|j| jkr| j|j |d< |jd	krd
|d< n|jdkrd
|d< |jr<i }t|j D ]B\}}| t|d i}| | jkr(|| q|| q||d< |S )a  Parse an arbitrary email URL.

        :param urllib.parse.ParseResult or str url:
            Email URL to parse.
        :param str or None backend:
            If None, the backend is evaluates from the ``url``.
        :return: Parsed email URL.
        :rtype: dict
        r	   Nr   r   r   )ZEMAIL_FILE_PATHZEMAIL_HOST_USERZEMAIL_HOST_PASSWORDZ
EMAIL_HOSTZ
EMAIL_PORTZEMAIL_BACKENDzInvalid email schema )rG   rH   TrJ   rI   rK   r   )r   r   r   r   r   r   r   r!   r   r   r   r   r   rU   EMAIL_SCHEMESr   r   r   r   r   _EMAIL_BASE_OPTIONS)	r   r#   r|   r   r   r   r   r   r   r   r   r   r     s<    



zEnv.email_url_configc                 C   s   i }i }|j rt|j dkr$||fS t|j }d|krL|d d d|d< d|krp|d d }| |t|d< d|kr| |d d t|d< ||fS )NrQ   ZEXCLUDED_INDEXESr   r   ZINCLUDE_SPELLINGZ
BATCH_SIZE)r   r    r   r   r   rm   r   )r   r#   cfgZprsr   r   r   r   _parse_common_search_params  s    
zEnv._parse_common_search_paramsc                 C   s   i }| dd}t|dkr8d|d d }|d }nd}|d }t|rNdnd|d |dddf|d< d	|kr| |d	 d t|d	< d
|kr|d
 d |d
< ||d< |S )Nr   r	   r   rQ   r   httpshttpURLrD   KWARGSZ
INDEX_NAME)r   r   r   r   r   r   )r   r#   r   secureparamsr   r   indexr   r   r   "_parse_elasticsearch_search_params  s     
z&Env._parse_elasticsearch_search_paramsc                 C   sb   i }t d|dd  |f d |d< d|krF| |d d t|d< d|kr^|d d |d< |S )	N)r   r	   r   )rQ   rQ   rQ   r   rD   r   r   )r   r   r   )r   r#   r   r   r   r   r   r   _parse_solr_search_params  s    "zEnv._parse_solr_search_paramsc                 C   s@   i }d|kr|d d |d< d|kr<|  |d d t|d< |S )NZSTORAGEr   Z
POST_LIMIT)r   r   r   r   r   r   r   r   _parse_whoosh_search_params  s    zEnv._parse_whoosh_search_paramsc                 C   s    i }d|kr|d d |d< |S )NFLAGSr   r   r   r   r   r   _parse_xapian_search_params  s    zEnv._parse_xapian_search_paramsc           	      C   sn  i }t || jst|n|}t|jdd ddd }|j}d}|| jkrh|drh|dd }d	}|| j	krt
d
|j | j	| |d< | |\}}|| |jdkr|S |dr|dd }|jdkr|| ||| |S |j| jkr|| |||| |S d| |d< |jdkr@|| | n|jdkr\|| | |rj||d< |S )a  Parse an arbitrary search URL.

        :param urllib.parse.ParseResult or str url:
            Search URL to parse.
        :param str or None engine:
            If None, the engine is evaluates from the ``url``.
        :return: Parsed search URL.
        :rtype: dict
        r	   Nr   r   r   FrR   r   TzInvalid search schema r   rP   r   rM   PATHrN   rO   )r   r   r   r   r   r   rU   ELASTICSEARCH_FAMILYendswithSEARCH_SCHEMESr   r   r   r   r   r   r   )	r   r#   rw   r   r   rU   r   r   r   r   r   r   r   %  sH    




   zEnv.search_url_configc              	      s  |dkrHt  }tjtj|jjjd}tj	|sHt
d| dS zLt|trztt||d}| }W 5 Q R X n|}| }W 5 Q R X W n" tk
r   t
d| Y dS X t
d| dd }| D ]}	td	|	}
|
rn|
d
|
d }}td|}|r|d
}ntd|}|r:|d
}td|}|r`td||d
}t|||< q|	r|	drqt
d|	 qԇ fdd}|| j}| D ]\}}||| qdS )a{  Read a .env file into os.environ.

        If not given a path to a dotenv path, does filthy magic stack
        backtracking to find the dotenv in the same directory as the file that
        called ``read_env``.

        Existing environment variables take precedent and are NOT overwritten
        by the file content. ``overwrite=True`` will force an overwrite of
        existing environment variables.

        Refs:

        * https://wellfire.co/learn/easier-12-factor-django

        :param env_file: The path to the ``.env`` file your application should
            use. If a path is not provided, `read_env` will attempt to import
            the Django settings module from the Django project root.
        :param overwrite: ``overwrite=True`` will force an overwrite of
            existing environment variables.
        :param encoding: The encoding to use when reading the environment file.
        :param \**overrides: Any additional keyword arguments provided directly
            to read_env will be added to the environment. If the key matches an
            existing environment variable, the value will be overridden.
        Nz.envzU%s doesn't exist - if you're not configuring your environment separately, create one.)rk   zQ%s not found - if you're not configuring your environment separately, check this.z#Read environment variables from: %sc                 S   s   |  d}|dkrd| S |S )z+Keep escaped newline/tabs in quoted stringsr	   Zrnt\)group)matchZescaped_charr   r   r   _keep_escaped_format_characters  s    
z5Env.read_env.<locals>._keep_escaped_format_charactersz$\A(?:export )?([A-Za-z_0-9]+)=(.*)\Zr	   r   z \A\s*'(?<!\\)(.*)'\s*(#.*\s*)?\Zz\A(.*?)(#.*\s*)?\Zz
\A"(.*)"\Zz\\(.)#zInvalid line: %sc                    s   r fddS  fddS )zgReturn lambda to set environ.

             Use setdefault unless overwrite is specified.
             c                    s     | t|iS r   )r   r    r   r   Zenvvalr   r   r         z3Env.read_env.<locals>.set_environ.<locals>.<lambda>c                    s     | t|S r   )
setdefaultr    r   r   r   r   r     r   r   r   	overwriter   r   set_environ  s    z!Env.read_env.<locals>.set_environ)sys	_getframeosr   r   dirnamef_backf_codeco_filenameexistsr   infor   Openableopenr    readOSErrorr   
splitlinesrf   r   r   rg   rS   warningrc   r   )r   Zenv_filer  rk   Z	overridesframefcontentr   linem1r   r   m2Zm2aZm3r  Zsetenvr   r   r  r   read_env`  sb    

	
zEnv.read_env)N)N)N)N)NFri   )?r)   r-   r.   r/   r  environrc   r%   r   r   r   r   r   ZDEFAULT_DATABASE_ENVr
   r   r   ZDEFAULT_CACHE_ENVr   r   r   r   ZDEFAULT_EMAIL_ENVr   r   ZDEFAULT_SEARCH_ENVr   r   r   rZ   rb   rd   r    rl   rm   r   ro   r   rq   rs   rt   r#   rz   dbr   r   r   emailr   r   r`   classmethodr   rx   r}   r   r   r   r   r   r   r   r  r   r   r   r   r0   J   s   
		


I
9 H4


	

:r0   c                   @   s   e Zd ZdZe ZdS )FileAwareEnva  
    First look for environment variables with ``_FILE`` appended. If found,
    their contents will be read from the file system and used instead.

    Use as a drop-in replacement for the standard ``environ.Env``:

    .. code-block:: python

        python env = environ.FileAwareEnv()

    For example, if a ``SECRET_KEY_FILE`` environment variable was set,
    ``env("SECRET_KEY")`` would find the related variable, returning the file
    contents rather than ever looking up a ``SECRET_KEY`` environment variable.
    N)r)   r-   r.   r/   r   rc   r   r   r   r   r    s   r  c                       s   e Zd ZdZdd Zdd Zedd Zd) fd	d
	Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zed'd( Z  ZS )*r   z?Inspired to Django Two-scoops, handling File Paths in Settings.c                 O   s   | j | jf||S )zCreate new Path based on self.root and provided paths.

        :param paths: List of sub paths
        :param kwargs: required=False
        :rtype: Path
        )r(   __root__r+   pathsr   r   r   r   r     s    z	Path.pathc                 O   s   t | |f||S )zOpen a file.

        :param str name: Filename appended to :py:attr:`~root`
        :param \*args: ``*args`` passed to :py:func:`open`
        :param \**kwargs: ``**kwargs`` passed to :py:func:`open`
        :rtype: typing.IO[typing.Any]
        )r  )r+   nameargsr   r   r   r   file  s    	z	Path.filec                 C   s   | j S )zCurrent directory for this Pathr  r*   r   r   r   root  s    z	Path.rootrQ   c                    s:   t    |ddr"tj|}| j|f||| _d S )Nis_fileF)superrZ   r   r  r   r  _absolute_joinr  )r+   startr!  r   r(   r   r   rZ     s    
zPath.__init__c                 O   s   | j | jf||S )zRetrieve the absolute path, with appended paths

        :param paths: List of sub path of self.root
        :param kwargs: required=False
        )r)  r  r   r   r   r   rb      s    zPath.__call__c                 C   s    t |tr| j|jkS | j|kS r   r   r   r  r+   otherr   r   r   __eq__  s    
zPath.__eq__c                 C   s   |  | S r   )r/  r-  r   r   r   __ne__  s    zPath.__ne__c                 C   s$   t |tst| j|S t| j|jS r   r,  r-  r   r   r   __add__  s    
zPath.__add__c                 C   s\   t |tr| d| S t |tr>| j|r>t| j|S tdj	t
| t
|dd S )Nz../zkunsupported operand type(s) for -: '{self}' and '{other}' unless value of {self} ends with value of {other}r-  )r   r   r   r    r  r   r   rstripr   formatr   r-  r   r   r   __sub__  s    
 zPath.__sub__c                 C   s
   |  dS )Nz..r   r*   r   r   r   
__invert__"  s    zPath.__invert__c                 C   s,   | j }t|dkr tj|d}|j |S )Nr	   rQ   )r  r   r  r   r   rS   )r+   item	base_pathr   r   r   rd   %  s    zPath.__contains__c                 C   s   d| j  dS )Nz<Path:r'   r%  r*   r   r   r   r,   +  s    zPath.__repr__c                 C   s   | j S r   r%  r*   r   r   r   __str__.  s    zPath.__str__c                 C   s   |   S r   r8  r*   r   r   r   __unicode__1  s    zPath.__unicode__c                 O   s   |   j||S r   )r8  __getitem__r+   r#  r   r   r   r   r;  4  s    zPath.__getitem__c                 C   s   |   S r   r9  r*   r   r   r   
__fspath__7  s    zPath.__fspath__c                 O   s   t | j||S )z$Proxy method to :py:func:`str.rfind`)r    rfindr<  r   r   r   r>  :  s    z
Path.rfindc                 O   s   t | j||S )z#Proxy method to :py:func:`str.find`)r    findr<  r   r   r   r?  >  s    z	Path.findc                 O   sD   t jt jj| f| }|ddr@t j|s@td| |S )NrequiredFzCreate required path: )r  r   abspathr   r   r  r   )baser!  r   Zabsolute_pathr   r   r   r)  B  s    zPath._absolute_join)rQ   )r)   r-   r.   r/   r   r$  propertyr&  rZ   rb   r/  r0  r1  r4  r5  rd   r,   r8  r:  r;  r=  r>  r?  staticmethodr)  __classcell__r   r   r+  r   r     s,   	
	r   )&r/   r   r   loggingr  rf   r  r   urllib.parser   r   r   r   r   r   r   compatr
   r   r   r   r   Zfileaware_mappingr   r    PathLiker  	getLoggerr)   r   r   r   r!   r$   r%   r0   r  r   r   r   r   r   <module>	   s6   $



       