o
    (g                     @   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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ZddlmZ ddlZddlmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%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/ e0d
Z1e0dej2Z3e0dZ4e0dej2j5Z6d7 Z8g dZ9dZ:dZ;e;j<dj<ej= edZ>dd Z?dd Z@dd ZAdBddZBdBddZCdBddZDdedfd d!ZEd"d# ZFe0d$ej2ZGeFd%d& ZHG d'd( d(ZIG d)d* d*eIZJG d+d, d,eZKe0d-jLZMd.d/ ZNd0d1 ZOdCd2d3ZPd4d5 ZQG d6d7 d7ZRG d8d9 d9ejSZTejUjVfd:d;ZWd<d= ZXePe:eWZWd>d? ZYd@dA ZZdS )Dz#PyPI and direct package downloading    Nwraps)CHECKOUT_DISTDistributionBINARY_DISTnormalize_pathSOURCE_DISTEnvironmentfind_distributions	safe_namesafe_versionto_filenameRequirementDEVELOP_DISTEGG_DISTparse_version)log)DistutilsError)	translate)Wheelunique_everseenz^egg=([-A-Za-z0-9_.+!]+)$zhref\s*=\s*['"]?([^'"> ]+)z<a href="([^"#]+)">([^<]+)</a>\n\s+\(<a (?:title="MD5 hash"\n\s+)href="[^?]+\?:action=show_md5&amp;digest=([0-9a-f]{32})">md5</a>\)z([-+.a-z0-9]{2,}):z.tar.gz .tar.bz2 .tar .zip .tgz)PackageIndexdistros_for_urlparse_bdist_wininstinterpret_distro_name   z<setuptools/{setuptools.__version__} Python-urllib/{py_major}z{}.{})py_major
setuptoolsc              
   C   s6   zt | W S  ty } ztd| f |d }~ww )Nz1Not a URL, existing file, or requirement spec: %r)r   parse
ValueErrorr   )spece r#   `/var/www/python.lazyprojects.co.uk/venv/lib/python3.10/site-packages/setuptools/package_index.pyparse_requirement_arg7   s   r%   c                 C   s   |   }d\}}}|drS|dr| dd }d}n7|ddr1| d	d
 }| dd }d}n"|dr?| dd }d}n|ddrS| d	d
 }| dd }d}|||fS )z=Return (base,pyversion) or (None,None) for possible .exe name)NNN.exez
.win32.exeNiwin32z	.win32-pyiiz.win-amd64.exeiz	win-amd64z.win-amd64-pyi)lowerendswith
startswith)namer)   basepy_verplatr#   r#   r$   r   @   s$   




r   c           	      C   sx   t j| }|\}}}}}}t j|dd }|dkr,|dkr,t j|dd }d|v r8|dd\}}||fS )N/zsourceforge.netdownload#   )urllibr   urlparseunquotesplit)	urlpartsschemeserverpath
parametersqueryfragmentr-   r#   r#   r$   egg_info_for_urlX   s   rB   c                 c   sf    t | \}}t| ||D ]}|V  q|r-t|}|r/t| |d|tdD ]	}|V  q'dS dS dS )zEYield egg or source distribution objects that might be found at a URLr5   )
precedenceN)rB   distros_for_locationEGG_FRAGMENTmatchr   groupr   )r:   metadatar-   rA   distrF   r#   r#   r$   r   c   s   

r   c                 C   s   | dr|dd }| drd|v rt| ||gS | dr<d|v r<t|}| s/g S t| |j|jtd dgS | d	rUt|\}}}|durUt	| |||t
|S tD ]}| |ro|dt|  }t	| ||  S qWg S )
z:Yield egg or source distribution objects based on basename.egg.zipNr(   z.egg-z.whlr5   )locationproject_nameversionrC   r&   )r*   r   from_locationr   is_compatiblerM   rN   r   r   r   r   
EXTENSIONSlen)rL   basenamerH   wheelwin_baser.   platformextr#   r#   r$   rD   q   s4   


rD   c                 C   s   t t| tj| |S )zEYield possible egg or source distribution objects based on a filename)rD   r   osr>   rS   )filenamerH   r#   r#   r$   distros_for_filename   s   rZ   c              
   c   s~    | d}|stdd |dd D rdS tdt|d D ]}t| |d|d| d||d |||dV  q dS )zGenerate alternative interpretations of a source distro name

    Note: if `location` is a filesystem filename, you should call
    ``pkg_resources.normalize_path()`` on it before passing it to this
    routine!
    rK   c                 s   s    | ]	}t d |V  qdS )z	py\d\.\d$N)rerF   ).0pr#   r#   r$   	<genexpr>   s    z(interpret_distro_name.<locals>.<genexpr>   Nr5   )
py_versionrC   rV   )r9   anyrangerR   r   join)rL   rS   rH   r`   rC   rV   r;   r]   r#   r#   r$   r      s   
$
r   c                    s   t   fdd}|S )zs
    Wrap a function returning an iterable such that the resulting iterable
    only ever yields unique items.
    c                     s   t  | i |S Nr   )argskwargsfuncr#   r$   wrapper   s   zunique_values.<locals>.wrapperr   )rh   ri   r#   rg   r$   unique_values   s   rj   z3<([^>]*\srel\s{0,10}=\s{0,10}['"]?([^'" >]+)[^>]*)>c              	   c   s    t |D ]2}| \}}tttj| d}d|v s#d|v r8t	|D ]}t
j| t|dV  q(qdD ] }||}|dkr[t	||}|r[t
j| t|dV  q;dS )zEFind rel="homepage" and rel="download" links in `page`, yielding URLs,homepager2   r5   )z<th>Home Pagez<th>Download URLr1   N)RELfinditergroupssetmapstrstripr)   r9   HREFr6   r   urljoin
htmldecoderG   findsearch)r:   pagerF   tagrelrelsposr#   r#   r$   find_external_links   s    
r~   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	ContentCheckerzP
    A null content checker that defines the interface for checking content
    c                 C      dS )z3
        Feed a block of data to the hash.
        Nr#   selfblockr#   r#   r$   feed      zContentChecker.feedc                 C   r   )zC
        Check the hash. Return False if validation fails.
        Tr#   r   r#   r#   r$   is_valid   r   zContentChecker.is_validc                 C   r   )zu
        Call reporter with information about the checker (hash name)
        substituted into the template.
        Nr#   )r   reportertemplater#   r#   r$   report   s   zContentChecker.reportN)__name__
__module____qualname____doc__r   r   r   r#   r#   r#   r$   r      s
    r   c                   @   sB   e Zd ZedZdd Zedd Zdd Z	dd	 Z
d
d ZdS )HashCheckerzK(?P<hash_name>sha1|sha224|sha384|sha256|sha512|md5)=(?P<expected>[a-f0-9]+)c                 C   s   || _ t|| _|| _d S rd   )	hash_namehashlibnewhashexpected)r   r   r   r#   r#   r$   __init__   s   
zHashChecker.__init__c                 C   sB   t j|d }|st S | j|}|st S | di | S )z5Construct a (possibly null) ContentChecker from a URLr1   Nr#   )r6   r   r7   r   patternrx   	groupdict)clsr:   rA   rF   r#   r#   r$   from_url  s   zHashChecker.from_urlc                 C   s   | j | d S rd   )r   updater   r#   r#   r$   r        zHashChecker.feedc                 C   s   | j  | jkS rd   )r   	hexdigestr   r   r#   r#   r$   r     r   zHashChecker.is_validc                 C   s   || j  }||S rd   )r   )r   r   r   msgr#   r#   r$   r     s   
zHashChecker.reportN)r   r   r   r[   compiler   r   classmethodr   r   r   r   r#   r#   r#   r$   r      s    

r   c                       sb  e Zd ZdZ		dPddZ fdd	ZdQddZdQddZdQddZdd Z	dd Z
dd Zdd Zdd ZdRddZdd ZdR fdd 	Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Z	
	dSd+d,ZdTd-d.Zd/d0 Zd1Zd2d3 Zd4d5 ZdRd6d7Zd8d9 Zed:d; Zd<d= Z d>d? Z!d@dA Z"dBdC Z#dDdE Z$dFdG Z%edHdI Z&dJdK Z'dLdM Z(dNdO Z)  Z*S )Ur   z;A distribution index that scans web pages for download URLshttps://pypi.org/simple/*NTc                 O   sr   t j| g|R i | |dd |d   | _i | _i | _i | _td	t
t|j| _g | _tjj| _d S )Nr0   |)r	   r   r*   	index_urlscanned_urlsfetched_urlspackage_pagesr[   r   rc   rq   r   rF   allowsto_scanr6   requesturlopenopener)r   r   hosts	ca_bundle
verify_sslre   kwr#   r#   r$   r     s   zPackageIndex.__init__c                    s0   zt |j W n
 ty   Y d S w t |S rd   )r   rN   	Exceptionsuperadd)r   rI   	__class__r#   r$   r   *  s   zPackageIndex.addFc                 C   s  || j v r	|s	dS d| j |< t|s| | dS tt|}|r.| |s(dS | d| |s7|r7|| jv rAtt| j	| dS | |sMd| j|< dS | 
d| d| j|< d}| ||| }|du rhdS t|tjjr||jdkr|| 
d|j  d| j|j< d|jd	d
 vr|  dS |j}| }t|tst|tjjrd}n|jdpd}||d}|  t|D ]}	tj|t|	 d}
| !|
 q|"| j#rt$|dddkr| %||}dS dS dS )z<Evaluate a URL as a possible download, and maybe retrieve itNTzFound link: %sz
Reading %sz<Download error on %s: %%s -- Some packages may not be found!i  zAuthentication error: %shtmlcontent-type zlatin-1charsetignorer5   code  )&r   
URL_SCHEMEprocess_filenamelistr   url_okdebugr   rq   r   infoopen_url
isinstancer6   error	HTTPErrorr   r   r:   headersgetr)   closereadrr   	get_paramdecodert   rn   r   ru   rv   rG   process_urlr+   r   getattrprocess_index)r   r:   retrievediststmplfr-   ry   r   rF   linkr#   r#   r$   r   3  sV   






zPackageIndex.process_urlc                 C   s   t j|s| d| d S t j|r/|s/t j|}t |D ]}| t j||d q!t	|}|rE| 
d| tt| j| d S d S )NzNot found: %sTz	Found: %s)rX   r>   existswarnisdirrealpathlistdirr   rc   rZ   r   r   rq   r   )r   fnnestedr>   itemr   r#   r#   r$   r   h  s   zPackageIndex.process_filenamec                 C   s`   t |}|o|d dk}|s| tj|d rdS d}|r(t|| | || d S )Nr5   fileTzN
Note: Bypassing %s (disallowed host; see http://bit.ly/2hrImnY for details).
)	r   rG   r)   r   r6   r   r7   r   r   )r   r:   fatalsis_filer   r#   r#   r$   r   x  s   zPackageIndex.url_okc                 C   s2   t tjj|}dd |D }tt| j| d S )Nc                 s   s2    | ]}t |D ]}|d r	||fV  q	qdS )z	.egg-linkN)rX   r   r*   )r\   r>   entryr#   r#   r$   r^     s    z.PackageIndex.scan_egg_links.<locals>.<genexpr>)filterrX   r>   r   r   	itertoolsstarmapscan_egg_link)r   search_pathdirs	egg_linksr#   r#   r$   scan_egg_links  s
   zPackageIndex.scan_egg_linksc                 C   s   t tj||}ttd ttj|}W d    n1 sw   Y  t	|dkr,d S |\}}t
tj||D ]}tjj|g|R  |_t|_| | q9d S )Nr_   )openrX   r>   rc   r   r   rq   rr   rs   rR   r
   rL   r   rC   r   )r   r>   r   	raw_lineslinesegg_path
setup_pathrI   r#   r#   r$   r     s   zPackageIndex.scan_egg_linkc                 C   s   d}| | js
|S tttjj|t| jd  d}t|dks)d|d v r+|S t	|d }t
|d }d| j| i |< t|t|fS )N)NNr0   r_   r4   r5   r   T)r+   r   r   rq   r6   r   r8   rR   r9   r   r   r   
setdefaultr)   r   )r   r   NO_MATCH_SENTINELr;   pkgverr#   r#   r$   _scan  s   zPackageIndex._scanc           	   
   C   s   t |D ]}z| tj|t|d W q ty!   Y qw | |\}}|s-dS t	||D ]$}t
|\}}|drQ|sQ|rL|d||f 7 }n| | | | q2tdd |S )z#Process the contents of a PyPI pager5   r   .pyz
#egg=%s-%sc                 S   s   d|  ddd S )Nz<a href="%s#md5=%s">%s</a>r5      r_   )rG   )mr#   r#   r$   <lambda>  s    z,PackageIndex.process_index.<locals>.<lambda>)rt   rn   r   r6   r   ru   rv   rG   r    r~   rB   r*   need_version_infoscan_urlPYPI_MD5sub)	r   r:   ry   rF   r   r   new_urlr-   fragr#   r#   r$   r     s&   "
zPackageIndex.process_indexc                 C   s   |  d| d S )NzPPage at %s links to .py file(s) without version info; an index scan is required.)scan_allr   r:   r#   r#   r$   r     s   zPackageIndex.need_version_infoc                 G   s<   | j | jvr|r| j|g|R   | d | | j  d S )Nz6Scanning index of all packages (this may take a while))r   r   r   r   r   r   r   re   r#   r#   r$   r     s   zPackageIndex.scan_allc                 C   sz   |  | j|j d  | j|js|  | j|j d  | j|js)| | t| j|jdD ]}|  | q3d S )Nr0   r#   )	r   r   unsafe_namer   r   keyrM   not_found_in_indexr   )r   requirementr:   r#   r#   r$   find_packages  s   
zPackageIndex.find_packagesc                    sR   |    | | | |j D ]}||v r|  S | d|| qtt| ||S )Nz%s does not match %s)prescanr  r  r   r   r   obtain)r   r  	installerrI   r   r#   r$   r    s   
zPackageIndex.obtainc                 C   sL   | | jd|  | s$|  t| td|jjtj	
|f dS )z-
        checker is a ContentChecker
        zValidating %%s checksum for %sz7%s validation failed for %s; possible download problem?N)r   r   r   r   rX   unlinkr   r   r,   r>   rS   )r   checkerrY   tfpr#   r#   r$   
check_hash  s   
zPackageIndex.check_hashc                 C   sN   |D ]"}| j du st|r|dstt|r| | q| j | qdS )z;Add `urls` to the list that will be prescanned for searchesNfile:)r   r   r+   r   r   r   append)r   urlsr:   r#   r#   r$   add_find_links  s   

zPackageIndex.add_find_linksc                 C   s"   | j rtt| j| j  d| _ dS )z7Scan urls scheduled for prescanning (e.g. --find-links)N)r   r   rq   r   r   r#   r#   r$   r    s   
zPackageIndex.prescanc                 C   s<   | |j  r| jd}}n| jd}}|||j |   d S )Nz#Couldn't retrieve index page for %rz3Couldn't find index page for %r (maybe misspelled?))r  r   r   r  r   )r   r  methr   r#   r#   r$   r    s   
zPackageIndex.not_found_in_indexc                 C   sv   t |ts1t|}|r%| ||}t|\}}|dr#| |||}|S tj	|r-|S t
|}t| ||ddS )a  Locate and/or download `spec` to `tmpdir`, returning a local path

        `spec` may be a ``Requirement`` object, or a string containing a URL,
        an existing local filename, or a project/version requirement spec
        (i.e. the string form of a ``Requirement`` object).  If it is the URL
        of a .py file with an unambiguous ``#egg=name-version`` tag (i.e., one
        that escapes ``-`` as ``_`` throughout), a trivial ``setup.py`` is
        automatically created alongside the downloaded file.

        If `spec` is a ``Requirement`` object or a string containing a
        project/version requirement spec, this method returns the location of
        a matching distribution (possibly after downloading it to `tmpdir`).
        If `spec` is a locally existing file or directory name, it is simply
        returned unchanged.  If `spec` is a URL, it is downloaded to a subpath
        of `tmpdir`, and the local filename is returned.  Various errors may be
        raised if a problem occurs during downloading.
        r   rL   N)r   r   r   _download_urlrB   r*   	gen_setuprX   r>   r   r%   r   fetch_distribution)r   r!   tmpdirr<   foundr-   rA   r#   r#   r$   r2   $  s   

zPackageIndex.downloadc           	         s    d| i d}d
 fdd	}|r$  | ||}|s/|dur/|||}|du r@jdur<  ||}|du rO|sO| ||}|du r`drZdp[d| dS  d| |j|jd	S )a|  Obtain a distribution suitable for fulfilling `requirement`

        `requirement` must be a ``pkg_resources.Requirement`` instance.
        If necessary, or if the `force_scan` flag is set, the requirement is
        searched for in the (online) package index as well as the locally
        installed packages.  If a distribution matching `requirement` is found,
        the returned distribution's ``location`` is the value you would have
        gotten from calling the ``download()`` method with the matching
        distribution's URL or filename.  If no matching distribution is found,
        ``None`` is returned.

        If the `source` flag is set, only source distributions and source
        checkout links will be considered.  Unless the `develop_ok` flag is
        set, development and system eggs (i.e., those using the ``.egg-info``
        format) will be ignored.
        zSearching for %sNc                    s   |d u r}|| j  D ];}|jtkr# s#|vr"d| d|< q|| v o.|jtkp. }|rF|j}||_tj	
|jrF|  S qd S )Nz&Skipping development or system egg: %sr5   )r  rC   r   r   r   r2   rL   download_locationrX   r>   r   )reqenvrI   testloc
develop_okr   skippedsourcer  r#   r$   rw   ^  s(   z-PackageIndex.fetch_distribution.<locals>.findz:No local packages or working download links found for %s%sza source distribution of r   zBest match: %s)rL   rd   )r   r  r  r   r   cloner  )	r   r  r  
force_scanr   r  local_indexrI   rw   r#   r  r$   r  F  s2   




zPackageIndex.fetch_distributionc                 C   s"   |  ||||}|dur|jS dS )a3  Obtain a file suitable for fulfilling `requirement`

        DEPRECATED; use the ``fetch_distribution()`` method now instead.  For
        backward compatibility, this routine is identical but returns the
        ``location`` of the downloaded distribution instead of a distribution
        object.
        N)r  rL   )r   r  r  r"  r   rI   r#   r#   r$   fetch  s   zPackageIndex.fetchc           
   	   C   s  t |}|rdd t||dd D pg }t|dkrxtj|}tj||krEtj	||}ddl
m} |||sEt|| |}ttj	|dd}	|	d|d j|d jtj|d f  W d    |S 1 sqw   Y  |S |rtd	||f td
)Nc                 S   s   g | ]}|j r|qS r#   )rN   )r\   dr#   r#   r$   
<listcomp>  s    z*PackageIndex.gen_setup.<locals>.<listcomp>r5   r   )samefilezsetup.pywzIfrom setuptools import setup
setup(name=%r, version=%r, py_modules=[%r])
zCan't unambiguously interpret project/version identifier %r; any dashes in the name or version should be escaped using underscores. %rzpCan't process plain .py files without an '#egg=name-version' suffix to enable automatic setup script generation.)rE   rF   r   rG   rR   rX   r>   rS   dirnamerc   setuptools.command.easy_installr'  shutilcopy2r   writerM   rN   splitextr   )
r   rY   rA   r  rF   r   rS   dstr'  r   r#   r#   r$   r    sF   



		zPackageIndex.gen_setupi    c                 C   s2  |  d| d }zt|}| |}t|tjjr%td||j	|j
f |  }d}| j}d}d|v rI|d}	ttt|	}| ||||| t|d1}
	 ||}|ro|| |
| |d	7 }| ||||| nnqP| |||
 W d    n1 sw   Y  |W |r|  S S |r|  w w )
NzDownloading %szCan't download %s: %s %sr   r1   zcontent-lengthzContent-LengthwbTr5   )r   r   r   r   r   r6   r   r   r   r   r   dl_blocksizeget_allmaxrq   int
reporthookr   r   r   r-  r  r   )r   r:   rY   fpr  r   blocknumbssizesizesr  r   r#   r#   r$   _download_to  sF   





	

zPackageIndex._download_toc                 C   s   d S rd   r#   )r   r:   rY   r7  blksizer9  r#   r#   r$   r5       zPackageIndex.reporthookc              
   C   s  | dr	t|S zt|| jW S  ttjjfyD } z$ddd |j	D }|r0| 
|| n	td||f |W Y d }~d S d }~w tjjyY } z|W  Y d }~S d }~w tjjy } z|rl| 
||j n
td||jf |W Y d }~d S d }~w tjjy } z|r| 
||j n
td||jf |W Y d }~d S d }~w tjjtjfy } z|r| 
|| n	td||f |W Y d }~d S d }~ww )Nr   c                 S   s   g | ]}t |qS r#   )rr   )r\   argr#   r#   r$   r&    s    z)PackageIndex.open_url.<locals>.<listcomp>z%s %szDownload error for %s: %sz;%s returned a bad status line. The server might be down, %s)r+   
local_openopen_with_authr   r    httpclient
InvalidURLrc   re   r   r   r6   r   r   URLErrorreasonBadStatusLinelineHTTPExceptionsocket)r   r:   warningvr   r#   r#   r$   r     s^   
zPackageIndex.open_urlc                 C   sv   t |\}}|rd|v r|dddd}d|v snd}|dr(|d d }tj||}| ||p:| ||S )Nz...\___downloaded__rJ   r(   )rB   replacer*   rX   r>   rc   _download_vcs_download_other)r   r:   r  r,   rA   rY   r#   r#   r$   r    s   
zPackageIndex._download_urlc                 C   sL   t j| j}|d\}}}tddgdgt|  }tt|h|@ dS )a  
        >>> rvcs = PackageIndex._resolve_vcs
        >>> rvcs('git+http://foo/bar')
        'git'
        >>> rvcs('hg+https://foo/bar')
        'hg'
        >>> rvcs('git:myhost')
        'git'
        >>> rvcs('hg:myhost')
        >>> rvcs('http://foo/bar')
        +svngithgN)	r6   r   urlsplitr<   	partitionrp   boolnextiter)r:   r<   preseppostallowedr#   r#   r$   _resolve_vcs&  s   zPackageIndex._resolve_vcsc              
   C   s   |  |}|s	d S |dkr| ||S |d\}}}| |\}}| d| d| d|  t|dd||g t|d|d	d|g|d
|ddd|dgd}|d ura| d|  t||  |S )NrU  r4   zDoing z clone from z to r!  z--quietz-Ccheckoutz--cwdupz-r-q)rV  rW  zChecking out )ra  _download_svnrY  _vcs_split_rev_from_urlr   
subprocess
check_calldict)r   r:   spec_filenamevcsrY   rO  revco_commandsr#   r#   r$   rR  9  s"   
zPackageIndex._download_vcsc                 C   sD   t j|j}|dkrt jt j|jS | |d | 	||S )Nr   T)
r6   r   rX  r<   r   url2pathnamer7   r>   r   _attempt_download)r   r:   rY   r<   r#   r#   r$   rS  P  s
   zPackageIndex._download_otherc                 C   s   |  |d d S )NT)r   r   r#   r#   r$   r   X  r   zPackageIndex.scan_urlc                 C   s2   |  ||}d|dd v r| |||S |S )Nr   r   r   )r;  r   r)   _download_html)r   r:   rY   r   r#   r#   r$   ro  [  s   zPackageIndex._attempt_downloadc                 C   sj   t |}|D ]}| r%td|r#|  t| | ||  S  nq|  t| td| )Nz <title>([^- ]+ - )?Revision \d+:zUnexpected HTML page found at )	r   rs   r[   rx   r   rX   r
  re  r   )r   r:   r   rY   r   rH  r#   r#   r$   rp  b  s   

zPackageIndex._download_htmlc                 C   s  t dt |ddd }g }| drwd|v rwtj|\}}}}}}	|sw|drwd|d	d  v rw|d	d  dd\}}t	|\}
}|
rwd
|
v r`|
d
d\}}|
d|d|g n|
d|
g |}||||||	f}tj|}| d|| g d| ||g }t| |S )Nz"SVN download support is deprecatedr4   r5   r   zsvn:@z//r0   r_   :z
--usernamez
--passwordz'Doing subversion checkout from %s to %s)rU  rb  rd  )warningsr   UserWarningr9   r)   r+   r6   r   r7   
_splituserextend
urlunparser   rg  rh  )r   r:   rY   credsr<   netlocr>   r]   qr   authhostuserpwr;   cmdr#   r#   r$   re  q  s(   
zPackageIndex._download_svnc                 C   st   t j| }|jddd }|jd\}}}|d\}}}|r&||fn|df\}}	|j||dd	 }
|
|	fS )	a  
        Given a possible VCS URL, return a clean URL and resolved revision if any.

        >>> vsrfu = PackageIndex._vcs_split_rev_from_url
        >>> vsrfu('git+https://github.com/pypa/setuptools@v69.0.0#egg-info=setuptools')
        ('https://github.com/pypa/setuptools', 'v69.0.0')
        >>> vsrfu('git+https://github.com/pypa/setuptools#egg-info=setuptools')
        ('https://github.com/pypa/setuptools', None)
        >>> vsrfu('http://foo/bar')
        ('http://foo/bar', None)
        rT  r5   r1   r4   rq  Nr   )r<   r>   rA   )
r6   r   rX  r<   r9   r>   rY  
rpartition_replacegeturl)r:   r;   clean_schemeno_fragment_pathrO  r]  r^  r_  
clean_pathrl  resolvedr#   r#   r$   rf    s   z$PackageIndex._vcs_split_rev_from_urlc                 G      t j|g|R   d S rd   )r   r   r  r#   r#   r$   r        zPackageIndex.debugc                 G   r  rd   )r   r   r  r#   r#   r$   r     r  zPackageIndex.infoc                 G   r  rd   )r   r   r  r#   r#   r$   r     r  zPackageIndex.warn)r   r   NT)Frd   )FFFN)FF)+r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r2   r  r$  r  r1  r;  r5  r   r  staticmethodra  rR  rS  r   ro  rp  re  rf  r   r   r   __classcell__r#   r#   r   r$   r     sZ    

	
5


		
#

L)$
#

r   z!&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?c                 C   s   |  d}t|S )Nr   )rG   r   unescape)rF   whatr#   r#   r$   decode_entity  s   

r  c                 C   s
   t t| S )a  
    Decode HTML entities in the given text.

    >>> htmldecode(
    ...     'https://../package_name-0.1.2.tar.gz'
    ...     '?tokena=A&amp;tokenb=B">package_name-0.1.2.tar.gz')
    'https://../package_name-0.1.2.tar.gz?tokena=A&tokenb=B">package_name-0.1.2.tar.gz'
    )
entity_subr  )textr#   r#   r$   rv     s   
	rv   c                    s    fdd}|S )Nc                    s    fdd}|S )Nc               	      s:   t  }t  z | i |W t | S t | w rd   )rJ  getdefaulttimeoutsetdefaulttimeout)re   rf   old_timeout)rh   timeoutr#   r$   _socket_timeout  s
   
z@socket_timeout.<locals>._socket_timeout.<locals>._socket_timeoutr#   )rh   r  r  rg   r$   r    s   z'socket_timeout.<locals>._socket_timeoutr#   )r  r  r#   r  r$   socket_timeout  s   r  c                 C   s2   t j| }| }t|}| }|ddS )a9  
    Encode auth from a URL suitable for an HTTP header.
    >>> str(_encode_auth('username%3Apassword'))
    'dXNlcm5hbWU6cGFzc3dvcmQ='

    Long auth strings should not cause a newline to be inserted.
    >>> long_auth = 'username:' + 'password'*10
    >>> chr(10) in str(_encode_auth(long_auth))
    False
    
r   )r6   r   r8   encodebase64	b64encoder   rQ  )r{  auth_s
auth_bytesencoded_bytesencodedr#   r#   r$   _encode_auth  s
   
r  c                   @   r   )	
Credentialz:
    A username/password pair. Use like a namedtuple.
    c                 C   s   || _ || _d S rd   usernamepassword)r   r  r  r#   r#   r$   r     s   
zCredential.__init__c                 c   s    | j V  | jV  d S rd   r  r   r#   r#   r$   __iter__  s   zCredential.__iter__c                 C   s   dt |  S )Nz%(username)s:%(password)s)varsr   r#   r#   r$   __str__  s   zCredential.__str__N)r   r   r   r   r   r  r  r#   r#   r#   r$   r    s
    r  c                   @   s0   e Zd Zdd Zedd Zdd Zdd Zd	S )

PyPIConfigc                 C   sR   t g dd}tj| | tjtjdd}tj	|r'| 
| dS dS )z%
        Load from ~/.pypirc
        )r  r  
repositoryr   ~z.pypircN)ri  fromkeysconfigparserRawConfigParserr   rX   r>   rc   
expanduserr   r   )r   defaultsrcr#   r#   r$   r     s   zPyPIConfig.__init__c                    s&    fdd   D }tt j|S )Nc                    s    g | ]}  |d  r|qS )r  )r   rs   )r\   sectionr   r#   r$   r&    s    z2PyPIConfig.creds_by_repository.<locals>.<listcomp>)sectionsri  rq   _get_repo_cred)r   sections_with_repositoriesr#   r   r$   creds_by_repository
  s   
zPyPIConfig.creds_by_repositoryc                 C   s6   |  |d }|t|  |d |  |d fS )Nr  r  r  )r   rs   r  )r   r  repor#   r#   r$   r    s
   zPyPIConfig._get_repo_credc                 C   s*   | j  D ]\}}||r|  S qdS )z
        If the URL indicated appears to be a repository defined in this
        config, return the credential for that repository.
        N)r  itemsr+   )r   r:   r  credr#   r#   r$   find_credential  s
   
zPyPIConfig.find_credentialN)r   r   r   r   propertyr  r  r  r#   r#   r#   r$   r    s    
r  c                 C   s:  t j| }|\}}}}}}|drtjd|dv r$t|\}	}
nd}	|	sBt 	| }|rBt
|}	|j| f}tjdg|R   |	redt|	 }	||
||||f}t j|}t j|}|d|	 nt j| }|dt ||}|	rt j|j\}}}}}}||kr||
kr||||||f}t j||_|S )	z4Open a urllib2 request, handling HTTP authenticationrr  znonnumeric port: '')rB  httpsNz*Authenticating as %s for %s (from .pypirc)zBasic Authorizationz
User-Agent)r6   r   r7   r*   rB  rC  rD  ru  r  r  rr   r  r   r   r  rw  r   Request
add_header
user_agentr:   )r:   r   parsedr<   ry  r>   paramsr@   r   r{  addressr  r   r;   r   r   r6  s2h2path2param2query2frag2r#   r#   r$   rA  $  s8   

rA  c                 C   s$   |  d\}}} |r|| fS d| fS )zNsplituser('user[:passwd]@host[:port]')
    --> 'user[:passwd]', 'host[:port]'.rq  N)r  )r|  r}  delimr#   r#   r$   ru  S  s   ru  c                 C   s   | S rd   r#   )r:   r#   r#   r$   
fix_sf_url^  r=  r  c              	   C   s*  t j| \}}}}}}t j|}tj|rt j| S |	dr}tj
|r}g }t|D ];}	tj||	}
|	dkrXt|
d}| }W d   n1 sQw   Y   n tj
|
rb|	d7 }	|dj|	d q0d}|j| d|d	}d
\}}nd\}}}ddi}t|}t j| ||||S )z7Read a local path, with special support for directoriesr0   z
index.htmlrNz<a href="{name}">{name}</a>)r,   zB<html><head><title>{url}</title></head><body>{files}</body></html>r  )r:   files)   OK)r   zPath not foundz	Not foundr   z	text/html)r6   r   r7   r   rn  rX   r>   isfiler   r*   r   r   rc   r   r   r  formatioStringIOr   r   )r:   r<   r=   r>   paramr@   r   rY   r  r   filepathr6  bodyr   statusmessager   body_streamr#   r#   r$   r@  b  s0   



r@  rd   )r   )[r   sysrg  rX   r[   r  r+  rJ  r  r   r   rs  r  r   http.clientrB  urllib.parser6   urllib.requesturllib.error	functoolsr   r   pkg_resourcesr   r   r   r   r   r	   r
   r   r   r   r   r   r   r   	distutilsr   distutils.errorsr   fnmatchr   setuptools.wheelr    setuptools.extern.more_itertoolsr   r   rE   Irt   r   rF   r   r9   rQ   __all___SOCKET_TIMEOUT_tmplr  version_infor  r%   r   rB   r   rD   rZ   r   rj   rm   r~   r   r   r   r   r  r  rv   r  r  r  r  r  r   r   rA  ru  r  r@  r#   r#   r#   r$   <module>   s    @
	


!
#
!      
&/